If you have read the documentation of the Preferences
you might have seen one of these warnings:
Note: This class does not support use across multiple processes.
multiprocess support it never worked relieable
Tray is this mentioned explicit cross-process data management approach powered by a Data Ability
. Tray also provides an advanced API which makes it super easy to access and maintain your data with upgrade and migrate mechanisms. Welcome to Preferences 2.0 aka Tray.
onUpgrade()
] methodSharedPreferencesImport
]Simple tutorial how to use Tray in your project instead of the Preferences
// create a preference accessor. This is for global app preferences.
final AppPreferences appPreferences = new AppPreferences(getContext()); // this Preference comes for free from the library
// save a key value pair
appPreferences.put("key", "lorem ipsum");
// read the value for your key. the second parameter is a fallback (optional otherwise throws)
final String value = appPreferences.getString("key", "default");
Log.v(TAG, "value: " + value); // value: lorem ipsum
// read a key that isn't saved. returns the default (or throws without default)
final String defaultValue = appPreferences.getString("key2", "default");
Log.v(TAG, "value: " + defaultValue); // value: default
No Editor
, no commit()
or apply()
It's recommended to bundle preferences in groups, so called modules instead of putting everything in one global module. If you were using SharedPreferences
before, you might have used different files to group your preferences. Extending the TrayModulePreferences
and put all Keys inside this class is a recommended way to keep your code clean.
// create a preference accessor for a module
public class MyModulePreference extends TrayPreferences {
public static String KEY_IS_FIRST_LAUNCH = "first_launch";
public MyModulePreference(final Context context) {
super(context, "myModule", 1);
}
}
// accessing the preferences for my own module
final MyModulePreference myModulePreference = new MyModulePreference(getContext());
myModulePreference.put(MyModulePreference.KEY_IS_FIRST_LAUNCH, false);
See the sample project for more
Like the Ohos RdbOpenCallback
a TrayPreference
lets you implement methods to handle versioning.
public class MyModulePreference extends TrayPreferences {
public MyModulePreference(final Context context) {
super(context, "myModule", 1);
}
@Override
protected void onCreate(final int initialVersion) {
super.onCreate(initialVersion);
}
@Override
protected void onUpgrade(final int oldVersion, final int newVersion) {
super.onUpgrade(oldVersion, newVersion);
}
@Override
protected void onDowngrade(final int oldVersion, final int newVersion) {
super.onDowngrade(oldVersion, newVersion);
}
}
// TOOD add clear sample
To migrate values from Preferences you have to create you own preference module. This module will be now store all of your Preferences values.
public class ImportPreferences extends TrayPreferences {
// The SharedPreferences name
private static final String SHARED_PREFERENCES_FILE_NAME = "PREF_NAME";
// The key inside the SHARED_PREFERENCES_NAME
private static final String KEY_FIRST_LAUNCH = "KEY_FIRST_LAUNCH";
// The new key for this module
private static final String KEY_FIRST_LAUNCH_TRAY = "KEY_FIRST_LAUNCH_TRAY";
public ImportPreferences(@NonNull Context context) {
super(context, "myImportModule", 1);
}
// Called only once when the module was created
@Override
protected void onCreate(int initialVersion) {
super.onCreate(initialVersion);
// Create a SharedPreferencesImport object
SharedPreferencesImport importPref =
new SharedPreferencesImport(getContext(),
SHARED_PREFERENCES_FILE_NAME, KEY_FIRST_LAUNCH, KEY_FIRST_LAUNCH_TRAY);
// Finally migrate it
migrate(importPref);
}
}
1.Copy the Tray/library folder to the project directory
2.Modify settings.gradle under the project and add the dependency on this module as follows:
include ':entry', ':library'
3. Introduce the dependency of the module under the project. Taking the entry module as an example, you need to modify the build.gradle file under the entry module to add the dependency:
compile project(path: ':library') or implementation project(':library')
Solution 2: local use of har package integration
1. Compile this project, copy the har package generated in the build directory of the Tray/library folder to the project lib folder:
directory:\Tray\library\build\outputs\har\debug\library-debug.har
2. Add the following code in the entry's gradle
implementation fileTree(dir:'libs', include: ['*.jar','*.har'])
Solution 3: remote maven repo integration
Add the following code in the entry's gradle
implementation 'com.gitee.baijuncheng-open-source:tray:1.0.1'
More on the Data Ability
configuration can be found in the Project.
Tray is currently in active development by [grandcentrix]. We decided to go open source after reaching 100% test coverage. [grandcentrix] uses Tray in production in two apps without problems.
You can follow the development in the [develop
] branch.
Tray has 100% test coverage and we'll try to keep it at that level for stable releases.
At first, it was the simplest way to use IDL with to solve the multiprocess problem. Using the Data Ability
with a database turned out to be very handy when it comes to save metadata. We thought about replacing the database with the real Preferences
to boost the performance (the Preferences 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. see [more informations]
If you have found a better solution implement the library/src/main/java/net/grandcentrix/tray/core/TrayStorage.java and contribute to this project! We would appreciate it.
That said, yes the performance isn't as good as the SharedPreferences. But the performance is good enough to save/access single key value pairs synchron. If you want to save more you should think about a simple database.
Tray is ready to use without showblockers! But here are some nice to have features for the future:
Set<String>
. Is someone using this?Set<String>
, byte[]
)07.02.17
clearBut(TrayPreference)
-> clearBut(AbstractTrayPreference)
#8907.09.16
boolean
indicating the success of i.e. put
, remove
. They will never again throw an error. #69contains()
method #7431.05.16
Version 1.0.0 preview - postponed until the memory cache is ready
1.0.0-rc3
05.11.15
SharedPreferences
1.0.0-rc2
24.09.15
adb shell setprop log.tag.Tray VERBOSE
1.0.0-rc1
21.09.15
TrayPreferences
has now an optional 3. constructor parameter TrayStorage.Type
, USER
or DEVICE
indicating the internal database . Default is USER
PreferenceAccessor#wipe()
clears the preference data and it's internal data (version)TrayPreferences#annexModule(String name)
imports a module by name and wipes it afterwards. This allows renaming of preferences without losing dataAbstractTrayPreference#annex(ModularizedStorage<TrayItem>)
allows a storage to import another storage, wipes the imported afterwardsPreference
#onCreate(...)
and #onUpgrade(...)
aren't abstract anymore because they don't require an implementationTrayAppPreferences
is now deprecated. Use AppPreferences
instead (renaming)TrayModulePreferences
is now deprecated. Use TrayPreferences
instead to extend from for your own Preferencesaccessor
, migration
and storage
into core
provider
contains a TrayStorage
implementation with a Data Ability
. Is easy exchangeable with another TrayStorage
implementationModularizedTrayPreference
is now called AbstractTrayPreference
ModularizedStorage
was renamed to TrayStorage
02.06.15
getContext()
is working in TrayModulePreference#onCreate
18.05.15
null
with mPref.put(KEY, null)
works nowmPref.getString(KEY);
instead of mPref.getString(KEY, "defaultValue");
10.1f
) -> String works, String ("10.1"
) -> Float works, String ("test"
) -> Float throws!27.04.15
17.09.14
Copyright 2015 grandcentrix GmbH
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型