gcx-hci / tray Goto Github PK
View Code? Open in Web Editor NEWa SharedPreferences replacement for Android with multiprocess support
License: Apache License 2.0
a SharedPreferences replacement for Android with multiprocess support
License: Apache License 2.0
I have the same problem.
android.database.sqlite.SQLiteReadOnlyDatabaseException: attempt to write a readonly database (code 1032)
at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(Native Method)
at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:743)
at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:754)
at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
at android.database.sqlite.SQLiteDatabase.updateWithOnConflict(SQLiteDatabase.java:1606)
at android.database.sqlite.SQLiteDatabase.update(SQLiteDatabase.java:1552)
at net.grandcentrix.tray.provider.SqliteHelper.a(ProGuard:164)
at net.grandcentrix.tray.provider.TrayContentProvider.insert(ProGuard:179)
at android.content.ContentProvider$Transport.insert(ContentProvider.java:246)
at android.content.ContentResolver.insert(ContentResolver.java:1256)
at net.grandcentrix.tray.provider.TrayProviderHelper.a(ProGuard:128)
at net.grandcentrix.tray.provider.ContentProviderStorage.a(ProGuard:227)
at net.grandcentrix.tray.core.Preferences.b(ProGuard:123)
at com.meituan.banma.util.SPUtil.b(ProGuard:52)
at com.meituan.banma.model.AppPrefs.b(ProGuard:159)
at com.meituan.banma.model.UserModel.a(ProGuard:102)
at com.meituan.banma.model.UserModel$2.onResponse(ProGuard:85)
at com.meituan.banma.net.request.BaseRequest.a(ProGuard:104)
at com.meituan.banma.net.request.BaseRequest$1.onResponse(ProGuard:85)
at com.meituan.banma.net.request.BaseRequest$1.onResponse(ProGuard:82)
at com.meituan.banma.net.request.BaseRequest$InnerRequest.deliverResponse(ProGuard:212)
at com.meituan.banma.net.request.BaseRequest$InnerRequest.deliverResponse(ProGuard:189)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ProGuard:99)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:230)
at android.app.ActivityThread.main(ActivityThread.java:5682)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:998)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:793)
How to solve?
I'm using 1.0.0-rc2 version.
Very thanks for your product,but i have got a NullPointerException while migrating data,can anybody give me some advice?
java.lang.NullPointerException:
Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
at net.grandcentrix.tray.core.SharedPreferencesImport.onPostMigrate(SharedPreferencesImport.java:79)
at net.grandcentrix.tray.core.SharedPreferencesImport.onPostMigrate(SharedPreferencesImport.java:38)
at net.grandcentrix.tray.core.Preferences.migrate(Preferences.java:125)
at ...module.sp.CookiePreferences.importSP(CookiePreferences.java:47)
at ...module.sp.CookiePreferences.onCreate(CookiePreferences.java:29)
at net.grandcentrix.tray.core.Preferences.changeVersion(Preferences.java:262)
at net.grandcentrix.tray.core.Preferences.isVersionChangeChecked(Preferences.java:292)
at net.grandcentrix.tray.core.Preferences.(Preferences.java:58)
at net.grandcentrix.tray.core.AbstractTrayPreference.(AbstractTrayPreference.java:31)
at net.grandcentrix.tray.TrayPreferences.(TrayPreferences.java:43)
at net.grandcentrix.tray.TrayPreferences.(TrayPreferences.java:48)
at ..*.module.sp.CookiePreferences.(CookiePreferences.java:23)
And below is code in CookiePreferences:
`public class CookiePreferences extends TrayPreferences {
private static final String TAG = CookiePreferences.class.getSimpleName();
public static final String MODULE = "cookie";
private static final String SP_NAME = "mycookie";
public CookiePreferences(Context context) {
super(context, MODULE, 1);
}
@Override
protected void onCreate(int initialVersion) {
super.onCreate(initialVersion);
importSP();
}
private void importSP() {
final SharedPreferences sps = getContext().getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
HashMap<String, Object> all = new HashMap<>(sps.getAll());
Set<Map.Entry<String, Object>> set = all.entrySet();
for (Map.Entry<String, Object> en : set) {
String key = en.getKey();
SharedPreferencesImport ip = new SharedPreferencesImport(getContext(), SP_NAME, key, key);
migrate(ip);
}
}
}`
Version:
compile 'net.grandcentrix.tray:tray:0.11.1'
Hi and thanks for the cool library 👍
Here is Gradle support with Jitpack
https://jitpack.io/#grandcentrix/tray/v0.9
java.lang.ClassNotFoundException: Didn't find class "net.grandcentrix.tray.provider.TrayContentProvider" on path: DexPathList
I am having two processes in my app. Say I have two process com.example.appname.xx and another com.example.appname.yy . By default it is running in the process com.example.appname. How can I indicate it to run this in either com.example.appname.xx orcom.example.appname.yy.Thanks.
Dear grandcentrix GmbH,
I like this library , it make sharedPreference so easy to use....
but it need minApi is 15 , it's wired , this limited many customer requirements,
because many shopping apps do not want higher api level , that means lost costom.....
so when I use it I must import the library moudle ,then set the minSdkVersion to 10 ,
but I think many developers do not know that the library's api-level could be reduced , maybe it will lost many follows cause this...
So would please reduce it to fits much more app ?
Best Regards.
Though I've just reported the issue in Google's issue tracker, I thought it would be good to also report here.
I just got following error when tried to use Android Gradle plugin 1.5.0-beta2 with proguard enabled.
without proguard, it works fine. but when I enable proguard, it starts crashing right after I launch the app.
With Gradle plugin 1.3.0, it works fine.
I'm using 1.0.0-rc3 of the tray.
java.lang.RuntimeException: Unable to get provider net.grandcentrix.tray.provider.TrayContentProvider: java.lang.ClassNotFoundException: Didn't find class "net.grandcentrix.tray.provider.TrayContentProvider" on path: DexPathList[[zip file "/data/app/net.yslibrary.omnitweety-1/base.apk"],nativeLibraryDirectories=[/data/app/net.yslibrary.omnitweety-1/lib/arm64, /data/app/net.yslibrary.omnitweety-1/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]]
at android.app.ActivityThread.installProvider(ActivityThread.java:5156)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:4748)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4688)
at android.app.ActivityThread.-wrap1(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.ClassNotFoundException: Didn't find class "net.grandcentrix.tray.provider.TrayContentProvider" on path: DexPathList[[zip file "/data/app/net.yslibrary.omnitweety-1/base.apk"],nativeLibraryDirectories=[/data/app/net.yslibrary.omnitweety-1/lib/arm64, /data/app/net.yslibrary.omnitweety-1/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at android.app.ActivityThread.installProvider(ActivityThread.java:5141)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:4748)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4688)
at android.app.ActivityThread.-wrap1(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Suppressed: java.lang.ClassNotFoundException: net.grandcentrix.tray.provider.TrayContentProvider
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 12 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
TODO: add documentation how to migrate from SharedPreferences
to Tray
Inserting null
with insert(KEY, null)
doesn't work at the moment. The only way to delete a value
is to call remove(KEY)
.
JNI: CheckJNI is off; workarounds are off; pins=0; globals=269
DALVIK THREADS:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0)
"main" prio=5 tid=1 NATIVE
| group="main" sCount=1 dsCount=0 obj=0x41db7d08 self=0x415cd008
| sysTid=10032 nice=-11 sched=0/0 cgrp=apps handle=1074487636
| state=D schedstat=( 0 0 0 ) utm=88 stm=33 core=0
#00 pc 0002035c pwrite64 LINE:libc.so
#01 pc 0000c3b7 /system/lib/libsqlite.so
#02 pc 0001ccb5 /system/lib/libsqlite.so
#03 pc 000312bb /system/lib/libsqlite.so
#04 pc 00035ecd /system/lib/libsqlite.so
#05 pc 0003608f /system/lib/libsqlite.so
#06 pc 00036b51 /system/lib/libsqlite.so
#07 pc 000537cb /system/lib/libsqlite.so
#08 pc 000417f3 sqlite3_step LINE:libsqlite.so
#09 pc 0006492d /system/lib/libandroid_runtime.so
#10 pc 00064989 /system/lib/libandroid_runtime.so
#11 pc 0001dd4c dvmPlatformInvoke LINE:libdvm.so
#12 pc 0004dfc7 /system/lib/libdvm.so
#13 pc 00027160 /system/lib/libdvm.so
#14 pc 0002e0a8 dvmMterpStd LINE:libdvm.so
#15 pc 0002b754 /system/lib/libdvm.so
#16 pc 000603bb /system/lib/libdvm.so
#17 pc 000603df /system/lib/libdvm.so
#18 pc 0006b999 dvmInitClass LINE:libdvm.so
#19 pc 0006c469 dvmResolveStaticField LINE:libdvm.so
#20 pc 00022574 dvmAsmSisterStart LINE:libdvm.so
#21 pc 0002e0a8 dvmMterpStd LINE:libdvm.so
#22 pc 0002b754 /system/lib/libdvm.so
#23 pc 0006069d /system/lib/libdvm.so
#24 pc 000685b3 /system/lib/libdvm.so
#25 pc 00027160 /system/lib/libdvm.so
#26 pc 0002e0a8 dvmMterpStd LINE:libdvm.so
#27 pc 0002b754 /system/lib/libdvm.so
#28 pc 000603bb /system/lib/libdvm.so
#29 pc 00049c17 /system/lib/libdvm.so
#30 pc 00051a37 /system/lib/libandroid_runtime.so
#31 pc 00052fcb /system/lib/libandroid_runtime.so
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:972)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1603)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1473)
at com.tray.provider.SqliteHelper.insertOrUpdate(ProGuard:148)
at com.tray.provider.TrayContentProvider.insertOrUpdate(ProGuard:1206)
insert
at android.content.ContentProvider$Transport.insert(ContentProvider.java:220)
at android.content.ContentResolver.insert(ContentResolver.java:1195)
at com.tray.provider.TrayProviderHelper.persist(ProGuard:149)
at com.tray.provider.ContentProviderStorage.com.tray.provider.TrayProviderHelper.persist(ProGuard:13140)
setVersion
at com.tray.core.Preferences.changeVersion(ProGuard:270)
at com.tray.core.Preferences.isVersionChangeChecked(ProGuard:290)
at com.tray.core.Preferences.<init>(ProGuard:56)
at com.tray.core.AbstractTrayPreference.<init>(ProGuard:32)
at com.tray.TrayPreferences.<init>(ProGuard:42)
at com.tray.TrayPreferences.<init>(ProGuard:47)
Do you know why this security exception occur?
I am accessing it in my own process.
I am keeping tray provider like below for proguard obfuscation
-keep class net.grandcentrix.tray.provider.** {*;}
03-25 15:02:57.107 W 22864 22969 System.err: net.grandcentrix.tray.a.f: Hard error accessing the ContentProvider
03-25 15:02:57.107 W 22864 22969 System.err: at net.grandcentrix.tray.provider.TrayProviderHelper.queryProvider(SourceFile:170)
03-25 15:02:57.107 W 22864 22969 System.err: at net.grandcentrix.tray.provider.ContentProviderStorage.getVersion(SourceFile:216)
03-25 15:02:57.107 W 22864 22969 System.err: at net.grandcentrix.tray.a.e.a(SourceFile:257)
03-25 15:02:57.107 W 22864 22969 System.err: at net.grandcentrix.tray.a.e.a(SourceFile:291)
03-25 15:02:57.107 W 22864 22969 System.err: at net.grandcentrix.tray.a.e.<init>(SourceFile:57)
03-25 15:02:57.107 W 22864 22969 System.err: at net.grandcentrix.tray.a.a.<init>(SourceFile:31)
03-25 15:02:57.107 W 22864 22969 System.err: at net.grandcentrix.tray.c.<init>(SourceFile:43)
03-25 15:02:57.107 W 22864 22969 System.err: at net.grandcentrix.tray.c.<init>(SourceFile:48)
03-25 15:02:57.108 W 22864 22969 System.err: Caused by: java.lang.SecurityException: Permission Denial: reading net.grandcentrix.tray.provider.TrayContentProvider uri content://com.xxxxxxx.tray/internal_preferences/THEME/version?backup=true from pid=0, uid=1000 requires the provider be exported, or grantUriPermission()
03-25 15:02:57.109 W 22864 22969 System.err: at net.grandcentrix.tray.provider.TrayProviderHelper.queryProvider(SourceFile:168)
03-25 15:02:57.113 W 22864 22969 System.err: net.grandcentrix.tray.a.f: Hard error accessing the ContentProvider
03-25 15:02:57.113 W 22864 22969 System.err: at net.grandcentrix.tray.provider.TrayProviderHelper.queryProvider(SourceFile:170)
03-25 15:02:57.113 W 22864 22969 System.err: at net.grandcentrix.tray.provider.ContentProviderStorage.getVersion(SourceFile:216)
03-25 15:02:57.113 W 22864 22969 System.err: at net.grandcentrix.tray.a.e.a(SourceFile:257)
03-25 15:02:57.114 W 22864 22969 System.err: at net.grandcentrix.tray.a.e.a(SourceFile:291)
03-25 15:02:57.114 W 22864 22969 System.err: at net.grandcentrix.tray.a.e.b(SourceFile:130)
03-25 15:02:57.114 W 22864 22969 System.err: Caused by: java.lang.SecurityException: Permission Denial: reading net.grandcentrix.tray.provider.TrayContentProvider uri content://com.xxxxxxxx.tray/internal_preferences/THEME/version?backup=true from pid=0, uid=1000 requires the provider be exported, or grantUriPermission()
03-25 15:02:57.115 W 22864 22969 System.err: at net.grandcentrix.tray.provider.TrayProviderHelper.queryProvider(SourceFile:168)
The following causes the compiler to complain; TrayStorage.Type.USER needs to be an int.
private class MyPreference extends TrayPreferences {
public MyPreference(@NonNull final Context context) {
super(context, "myModule", VERSION, TrayStorage.Type.USER);
}
}
Is there any possibility to reduce the minSdk to 11?
Since this is based on content provider, is Tray required to declare in manifest as Content Provider does with tag? My concern is usability across apps.
Just an FYI letting you i created a new library that utilizes tray to implement sharedpreference UI. It also handles Set < String > using JSON and saves it as a string. You could probably use the same method in tray as well.
https://github.com/draekko-rand/traypreferences
Currently only tested on API 23. I've included a sample app. The project uses Android Studio 2.2
I'm trying to run Robolectric tests with code that uses Tray, but immediately get the following error for any classes that access AppPreferences
:
java.lang.IllegalStateException: could not access stored data with uri content://com.example.tray/internal_preferences/com.example/version?backup=true. Is the provider registered in the manifest of your application?
Is there a suggested set up for unit testing classes that use Tray? I tried following the existing Tray library unit tests, but ran into issues since TrayContract
is private scope.
As title. Is there any API limit the minSdkVersion
?
I have a question,when a call mPrefs.get("key") on the ui thread, and it is synchronous, will it block the UI thread when the data is so big?
Hi Tray team,
What do you think of adding the ability to read an input stream from a tray item and write to a tray item using an outputstream ?
(Ideally there would be no transformation of the binary stream to get higher speed levels).
Actually, it would help to serialize and parse Pojos encoded with whatever format devs want (I would use it for JSON, but protobuf would also work, etc..)
thanks for your efforts on this lib guys !
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to get provider net.grandcentrix.tray.provider.TrayContentProvider: java.lang.ClassNotFoundException: Didn't find class "net.grandcentrix.tray.provider.TrayContentProvider" on path: /data/app/com.yudong.fitnew-1.apk
at android.app.ActivityThread.installProvider(ActivityThread.java:5157)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:4755)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4693)
at android.app.ActivityThread.access$1400(ActivityThread.java:160)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1377)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5454)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: Didn't find class "net.grandcentrix.tray.provider.TrayContentProvider" on path: /data/app/com.yudong.fitnew-1.apk
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:64)
at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
at android.app.ActivityThread.installProvider(ActivityThread.java:5142)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:4755)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4693)
at android.app.ActivityThread.access$1400(ActivityThread.java:160)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1377)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5454)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
at dalvik.system.NativeStart.main(Native Method)
there is documentation or functionallity about how to use TrayPreferences with an external App?
something like:
public class AppPreferencesManager extends TrayPreferencesConnector {
// setting up access:
// like uri of Tray ContentProvider
}
so we can use
AppPreferencesManager appPref;
appPref.put(key,value);
storedValue = appPref.get(key,value);
from any app outside of app/module container.
Hello @passsy
I met a problem of CursorWindowAllocationException today.
Stack Trace
android.database.CursorWindowAllocationException
Cursor window allocation of 2048 kb failed.
java.lang.RuntimeException:Unable to resume activity {com.jiahe.qixin/com.jiahe.qixin.ui.MainActivity}: android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed.
android.app.ActivityThread.performResumeActivity(ActivityThread.java:2940)
......
cause by:
android.database.CursorWindowAllocationException:Cursor window allocation of 2048 kb failed.
android.database.CursorWindow.<init>(CursorWindow.java:108)
android.database.CursorWindow.<init>(CursorWindow.java:100)
android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
android.database.sqlite.SQLiteCursor.clearOrCreateWindow(SQLiteCursor.java:301)
android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:139)
android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
android.content.ContentResolver.query(ContentResolver.java:436)
android.content.ContentResolver.query(ContentResolver.java:360)
net.grandcentrix.tray.provider.TrayProviderHelper.java.util.List queryProvider(android.net.Uri)(TrayProviderHelper.java:192)
net.grandcentrix.tray.storage.TrayStorage.int getVersion()(TrayStorage.java:85)
net.grandcentrix.tray.accessor.Preference.void changeVersion(int)(Preference.java:158)
net.grandcentrix.tray.accessor.Preference.void <init>(net.grandcentrix.tray.storage.PreferenceStorage,int)(Preference.java:52)
net.grandcentrix.tray.accessor.TrayPreference.void <init>(net.grandcentrix.tray.storage.ModularizedStorage,int)(TrayPreference.java:33)
net.grandcentrix.tray.TrayModulePreferences.void <init>(android.content.Context,java.lang.String,int)(TrayModulePreferences.java:40)
com.XXX.YYY.ui.theme.ThemeSharePrefs.void <init>(android.content.Context,java.lang.String)(ThemeSharePrefs.java:20)
com.XXX.YYY.utils.PrefUtils.java.lang.String getThemeColorFromPreferece(android.content.Context)(PrefUtils.java:912)
com.XXX.YYY.ui.MainActivity.void onResume()(MainActivity.java:1137)
android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1209)
android.app.Activity.performResume(Activity.java:5450)
android.app.ActivityThread.performResumeActivity(ActivityThread.java:2925)
android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2969)
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1371)
android.os.Handler.dispatchMessage(Handler.java:99)
android.os.Looper.loop(Looper.java:177)
android.app.ActivityThread.main(ActivityThread.java:5496)
java.lang.reflect.Method.invokeNative(Native Method)
java.lang.reflect.Method.invoke(Method.java:525)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1225)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1041)
dalvik.system.NativeStart.main(Native Method)
Hi,
In Android Studio,we can use resValue to define authority in provider,but how to define authority in eclipse environment for multi-apps?
Different projects in the same project, using the tray to INSTALL_FAILED_CONFLICTING_PROVIDER problems in API = 19
If the goal of this project is to be a SharedPreferences replacement, it should support PreferenceFragment / PreferenceActivity, but I don't see that ability.
Would it be possible to add a memory cache mechanism to Tray to boost its performances.
Something inspired by https://github.com/tumblr/Remember ?
I think the new PreferenceDataStore
interface may be of interest for this library. Classes that implement this interface can be used as the backend for SharedPreferences
operations.
I see your library and i need to replace my shared prefs because my prefs is caching in my service and i dont want it , so Context.MODE_MULTI_PROCESS is deprecated.
Actually i can use this library for now but i need to store Set this is so important for me , can you add this support please !
can i use listener like:
sharedPreferences.registerOnSharedPreferenceChangeListener(this)
?
thanks
util.SqliteHelper uses a method (android.database.DatabaseUtils.queryNumEntries) which is in api level 11, leading to crash on android 2.3 device.
Currently it is not possible to check if a key exist in Tray.
We have to do something like:
try {
return mPreference.getBoolean(key)
} catch (ItemNotFoundException e) {
return false;
}
It would be great if we have a method like contains(key)
to check if a key exists.
when i use Tray in two app,config different tray__authority,then i put a key in one app and get the key in another app.But the value it empty.
Can tray share data on multi-apps?
protected void onUpgrade(int oldVersion, int newVersion) {
switch (newVersion){
case 2:
put(CURRENT_DEVICES_ID, UUID.randomUUID().toString());
}
}
when put function call ,then will call onUpgrade again
My application is the only launcher of the android firmware.I got the follow error:
The TrayPreferences
is initialized in MyApplication.onCreate
08-12 14:52:14.283 E/ActivityThread( 1462): Failed to find provider info for com.testtay.user_preference
08-12 14:52:14.293 E/CrashHandler( 1462): encountered a fatal error
08-12 14:52:14.293 E/CrashHandler( 1462): java.lang.RuntimeException: Unable to create application com.testtay.application.MyApplication: java.lang.IllegalStateException: could not access stored data with uri content://com.testtay.user_preference/internal_preferences/group/version?backup=true. Is the provider registered in the manifest of your application?
08-12 14:52:14.293 E/CrashHandler( 1462): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4347)
08-12 14:52:14.293 E/CrashHandler( 1462): at android.app.ActivityThread.access$1500(ActivityThread.java:135)
08-12 14:52:14.293 E/CrashHandler( 1462): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
08-12 14:52:14.293 E/CrashHandler( 1462): at android.os.Handler.dispatchMessage(Handler.java:102)
08-12 14:52:14.293 E/CrashHandler( 1462): at android.os.Looper.loop(Looper.java:136)
08-12 14:52:14.293 E/CrashHandler( 1462): at android.app.ActivityThread.main(ActivityThread.java:5017)
08-12 14:52:14.293 E/CrashHandler( 1462): at java.lang.reflect.Method.invokeNative(Native Method)
08-12 14:52:14.293 E/CrashHandler( 1462): at java.lang.reflect.Method.invoke(Method.java:515)
08-12 14:52:14.293 E/CrashHandler( 1462): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:788)
08-12 14:52:14.293 E/CrashHandler( 1462): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:604)
08-12 14:52:14.293 E/CrashHandler( 1462): at dalvik.system.NativeStart.main(Native Method)
08-12 14:52:14.293 E/CrashHandler( 1462): Caused by: java.lang.IllegalStateException: could not access stored data with uri content://com.testtay.user_preference/internal_preferences/group/version?backup=true. Is the provider registered in the manifest of your application?
08-12 14:52:14.293 E/CrashHandler( 1462): at net.grandcentrix.tray.provider.TrayProviderHelper.queryProvider(TrayProviderHelper.java:145)
08-12 14:52:14.293 E/CrashHandler( 1462): at net.grandcentrix.tray.provider.ContentProviderStorage.getVersion(ContentProviderStorage.java:214)
08-12 14:52:14.293 E/CrashHandler( 1462): at net.grandcentrix.tray.core.Preferences.changeVersion(Preferences.java:224)
08-12 14:52:14.293 E/CrashHandler( 1462): at net.grandcentrix.tray.core.Preferences.<init>(Preferences.java:51)
08-12 14:52:14.293 E/CrashHandler( 1462): at net.grandcentrix.tray.core.AbstractTrayPreference.<init>(AbstractTrayPreference.java:31)
08-12 14:52:14.293 E/CrashHandler( 1462): at net.grandcentrix.tray.TrayPreferences.<init>(TrayPreferences.java:43)
08-12 14:52:14.293 E/CrashHandler( 1462): at net.grandcentrix.tray.TrayPreferences.<init>(TrayPreferences.java:48)
08-12 14:52:14.293 E/CrashHandler( 1462): at com.testtay.common.preferences.CacheTrayPreferences.<init>(CacheTrayPreferences.java:24)
08-12 14:52:14.293 E/CrashHandler( 1462): at com.testtay.common.preferences.UserPreferences.<init>(UserPreferences.java:34)
08-12 14:52:14.293 E/CrashHandler( 1462): at com.testtay.common.preferences.UserPreferences.init(UserPreferences.java:21)
08-12 14:52:14.293 E/CrashHandler( 1462): at com.testtay.utils.ProcessUtils.initCommon(ProcessUtils.java:149)
08-12 14:52:14.293 E/CrashHandler( 1462): at com.testtay.application.process.MainProcessApp.create(MainProcessApp.java:64)
08-12 14:52:14.293 E/CrashHandler( 1462): at com.testtay.application.MyApplication.onCreate(MyApplication.java:50)
08-12 14:52:14.293 E/CrashHandler( 1462): at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1021)
08-12 14:52:14.293 E/CrashHandler( 1462): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4344)
08-12 14:52:14.293 E/CrashHandler( 1462): ... 10 more
This constant was deprecated in API level 23.
MODE_MULTI_PROCESS does not work reliably in some versions of Android, and furthermore does not provide any mechanism for reconciling concurrent modifications across processes. Applications should not attempt to use it. Instead, they should use an explicit cross-process data management approach such as ContentProvider.
Tray is an accepted (recommended) solution from the Android documentation. Not mentioned there of cause, but a good alternative.
Caused by: java.lang.IllegalArgumentException: Query is not supported for Uri: content://com.sankuai.meituan.dispatch.crowdsource.tray/preferences/com.sankuai.meituan.xxxxx/xxxxxxxe.mark?backup=true
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:167)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:413)
at android.content.ContentResolver.query(ContentResolver.java:461)
at android.content.ContentResolver.query(ContentResolver.java:404)
at net.grandcentrix.tray.provider.TrayProviderHelper.a(ProGuard:141)
at net.grandcentrix.tray.provider.ContentProviderStorage.a(ProGuard:2172)
at net.grandcentrix.tray.core.Preferences.a(ProGuard:68)
at com.meituan.xxx.util.SPUtil.a(ProGuard:1118)
at com.meituan.xxx.util.SPUtil.a(ProGuard:25)
resValue "string", "tray__authority", "${applicationId}.tray"
causes missing translation error during exporting signed apk. How can I ignore this the elegant way?
There is no way to add translatable="false". I don't want to ignore all the missing translations either.
It's so strange because my second project doesn't have the problem at all.
04-28 08:37:18.840 8826-9078/*** E/SQLiteDatabase: Error inserting KEY=version MIGRATED_KEY=null UPDATED=1493368638631 CREATED=1493368638631 MODULE=cookie VALUE=1
android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: TrayInternal.MODULE, TrayInternal.KEY (code 2067)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:782)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1472)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1343)
at net.grandcentrix.tray.provider.SqliteHelper.insertOrUpdate(SqliteHelper.java:148)
at net.grandcentrix.tray.provider.TrayContentProvider.insertOrUpdate(TrayContentProvider.java:206)
at net.grandcentrix.tray.provider.TrayContentProvider.insert(TrayContentProvider.java:187)
at android.content.ContentProvider$Transport.insert(ContentProvider.java:264)
at android.content.ContentResolver.insert(ContentResolver.java:1274)
at net.grandcentrix.tray.provider.TrayProviderHelper.persist(TrayProviderHelper.java:151)
at net.grandcentrix.tray.provider.TrayProviderHelper.persist(TrayProviderHelper.java:142)
at net.grandcentrix.tray.provider.ContentProviderStorage.setVersion(ContentProviderStorage.java:350)
at net.grandcentrix.tray.core.Preferences.changeVersion(Preferences.java:272)
at net.grandcentrix.tray.core.Preferences.isVersionChangeChecked(Preferences.java:292)
at net.grandcentrix.tray.core.Preferences.(Preferences.java:58)
at net.grandcentrix.tray.core.AbstractTrayPreference.(AbstractTrayPreference.java:31)
at net.grandcentrix.tray.TrayPreferences.(TrayPreferences.java:43)
at net.grandcentrix.tray.TrayPreferences.(TrayPreferences.java:48)
at ***.module.sp.CookiePreferences.(CookiePreferences.java:23)
at ***.util.FileTypeUtil.getCookies(FileTypeUtil.java:839)
at ***.util.Util.SendPhoneInfo(Util.java:386)
at .util.Util.access$000(Util.java:124)
at .util.Util$1.run(Util.java:371)
04-28 08:37:18.840 8826-9078/ W/Tray: Couldn't update or insert data. Uri: content://.tray/internal_preferences/cookie/version?backup=true
Reference:
compile 'net.grandcentrix.tray:tray:0.11.1'
And code at "net.grandcentrix.tray.core.Preferences.changeVersion(Preferences.java:272)" is below:
getStorage().setVersion(newVersion);
Hi everyone, here asking for some help!
It crashed in the TrayContract.java
I get a nullpointerexpection, in this method
@nonnull
private static String getAuthority(@nonnull final Context context) {
return TextUtils.isEmpty(sTestAuthority) ?
context.getString(R.string.tray__authority) :
sTestAuthority;
}
I believe it can't get the context.getString(R.string.tray__authority) in here.
I don't understand the issue, can somebody help?
java.lang.IllegalStateException: could not access stored data with uri content://com.taobao.qianniu.tray/internal_preferences/qianniu/version. Is the provider registered in the manifest of your application?
at net.grandcentrix.tray.provider.TrayProviderHelper.queryProvider(SourceFile:196)
at net.grandcentrix.tray.storage.TrayStorage.getVersion(SourceFile:85)
at net.grandcentrix.tray.accessor.Preference.changeVersion(SourceFile:158)
at net.grandcentrix.tray.accessor.Preference.(SourceFile:52)
at net.grandcentrix.tray.accessor.TrayPreference.(SourceFile:33)
at net.grandcentrix.tray.TrayModulePreferences.(SourceFile:40)
MediaPad X1 7.0 11
PE-TL00M 7
Coolpad 9150W 6
HUAWEI P7-L07 6
PE-TL20 6
Che2-UL00 6
G621-TL00 5
vivo X5Pro D 5
Coolpad 8675-A 4
SM-N900
uses-sdk:minSdkVersion 9 cannot be smaller than version 15 declared in library
I'm wondering can It support a lower version
Wrote an encryption wrapper class using Tray to replace the one i had been using for SharedPreferences. Maybe someone else will find it useful. Find it here https://github.com/draekko/securedtray
Thanks for the good work on Tray as it solved a problem i had with concurrent access to data with multiple processes & SharedPreferences. Saved me a ton of time writing a similar library from scratch.
会不能同时安装
Hi,
In the "Missing Features" section you ask if someone wants to save Set - yes, I do!
Well, actually more saving a Map or an ArrayList<Map<String, Object>> - that's what I work with mostly. So I would very often need to save something like this as the value to some key:
[
{
"key": "value",
"key2": 222,
"key3": {"sub_key":"sub_value", "sub_key2":23232},
"key4": [1,2,3,4],
"key5": "etc"
}
]
I've had to use a combination of Base64OutputStream, ByteArrayOutputStream and ObjectOutputStream to save objects to shared prefs. :\
Support use across multiple processess
I'm trying to understand how can I take advantage of it . Can you give a practical example ?
Is it simply writes data asynchronous?
what will be happen when the app is killed before the data has been written to disk?
Is it true 'commit' semantics?
Topics that do not fully understand:
Tray solves this problem with a ContentProvider based storage.
What are the benefits it gives to us? Why we want use ContentProvider? Whether it's sharing of resources between different applications ?
Works multiprocess
So I can save several values in parallel?
automatically saves metadata for each entry (created, last updated, ...)
I do not understand? automatically saves metadata?
At first, it was the simpst way to use IPC with Binder to solve the multiprocess problem. Using the ContentProvider with a database turned out to be very handy when it comes to save metadata. We thought about replacing the database with the real SharedPreferences to boost the performance (the SharedPreferences do not access the disk for every read/write action which causes the multiprocess problem btw) but the metadata seemed to be more valuable to us.
Why we want use ContentProvider? Whether it's sharing of resources between different applications ?
Is it Tray support multi-thread?
Such as multi-thread work on insert a key.and other thread read it
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.