Easy SharedPreference Engine foR ANDROid

Related tags

Utility esperandro
Overview

Maven Central Build Status

esperandro

Easy SharedPreference Engine foR ANDROid

What?

esperandro makes it simple to use SharedPreferences in a nicer and less error-prone way.

Without esperandro a key is referenced by a string:

  • String myPreference = preferences.getString("myPreference", "default value") // load preference
  • preferences.edit().putString("myPreference", myPreference).commit() // store preference

With esperandro you adhere to an interface that you defined:

@SharedPreferences
interface MyPreferences {
    String getMyPreference();
    void setMyPreference(String myPreference);
}
  • String myPreference = preferences.getMyPreference() // load preference
  • preferences.setMyPreference(myPreference) // store preference

Type safe, easy, less error-prone.

Interested? Get Started

Tell me more!

Please refer to the wiki for in-depth examples and all available features.

See the changelog for a brief overview of recent changes.

Gradle artifacts

// essential dependencies
implementation 'de.devland.esperandro:esperandro-api:<insert version>'
annotationProcessor 'de.devland.esperandro:esperandro-preference-gen:<insert version>'

// optional, if object serialization is needed via gson
implementation 'de.devland.esperandro:esperandro-gson-addon:<insert version>'

// optional, if object serialization is needed via jackson
implementation 'de.devland.esperandro:esperandro-jackson-addon:<insert version>'

// additional processor to generate a file with all keys as string constants
annotationProcessor 'de.devland.esperandro:esperandro-keys-gen:<insert version>'

// additional processor to generate a file with all keys as string resources
annotationProcessor 'de.devland.esperandro:esperandro-resources-gen:<insert version>'
Comments
  • XML Preference Screen support

    XML Preference Screen support

    Is it possible to use esperandro type safe with PreferenceScreens written in xml?

    A simple solution for me would be that you just generate string resources for each preference key... So that I can reference them in the xml

    Any ideas to that?

    opened by MFlisar 24
  • Improvement - enable caching

    Improvement - enable caching

    It would be nice if I could enable a cache, so that I can fastly recheck a setting without reading the settings file again.

    A simple HashMap would be enough and an annotation like @SharedPreferences(..., enableCaching= true). And if the user enables caching, a static HashMap is always kept in sync when writing values and reading is done by accessing the HashMap...

    enhancement 
    opened by MFlisar 13
  • Serialized object cannot be cast to type

    Serialized object cannot be cast to type

    java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com.example.data.Item at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2215) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2265)

    When reading an ArrayList<Item> from SharedPreferences, objects stored in the ArrayList cannot be cast to their initial type (are not de-serialized).

    Item class implements Serializable, Esperandro is using its default serializer.

    public class Item implements Serializable {
        String title;
        String desc;
    }
    
    @SharedPreferences
    public interface LocalStorageInterface {
        ArrayList<Item> localItems();
        void localItems(ArrayList<Item> items);
    }
    
    bug 
    opened by ghost 11
  • Get dynamic default values

    Get dynamic default values

    Currently one can define default values at compile time using @Default annotation. Unfortunately this works only for simple types and at compile time. If user wants to specify default value for complex object, that can't be passed to annotation, he can't do that.

    My propose is to introduce getters with additional parameter that should be used as default. The library can have a convention that such methods should end with *Default

    @SharedPreferences
    interface MySettings{
        List getMyList(); //common usage
        List getMyListDefault(List defaultValue); //using default value if neccessary
    }
    

    The generated code would be not much more complex. Seems that the library would have to check for existence of the value for complex objects. For simple objects it can just pass parameter to shared prefs.

    opened by naixx 11
  • Memory leak in ProcessingMessager

    Memory leak in ProcessingMessager

    Recently we start hitting quite constantly "GC overhead limit exceeded" error on building our application.

    We managed to take heap dump of kotlin deamon process when this happens and, after analyzing it, we saw that ProcessingMessager consumes a lot of kotlin daemon heap memory.

    Seems main issue that ProcessingMessager itself is singleton and holds a reference to JavacProcessingEnvironment here https://github.com/dkunzler/esperandro/blob/d88d8e7cee508a24af921190802412167dc2175e/base/src/main/java/de/devland/esperandro/base/processing/ProcessingMessager.java#L37. This prevents GC to remove a lot of portions of heap.

    opened by Tapchicoma 8
  • Get rid of repeated SDK version checks

    Get rid of repeated SDK version checks

    Thanks for creating this project. We're using it in our and and we're quite happy with it.

    There's one thing I'd like to get rid of if possible. In all of the editing calls, since #11, there's a check of the current SDK version to see if it's possible to call apply():

    @Override
    @SuppressLint("NewApi")
    public void registrationId(String registrationId) {
      if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
        preferences.edit().putString("registrationId", registrationId).commit();
      } else {
        preferences.edit().putString("registrationId", registrationId).apply();
      }
    }
    

    Our app is has a minSdkVersion of 15, so these calls are useless. I figure there are three ways to get rid of them:

    1. Generate 2 implementations of the preference interface: one for Gingerbread containing apply() and one for pre-Gingerbread containing commit(). In the constructor of Esperandro, the current SDK could be checked and the suffix could be determined to be $$GingerbreadImpl or $$PreGingerbreadImpl. The benefit of this approach is that there would only be one SDK check per execution. The downside is that there would be twice as many classes generated and deployed with the APK. A note could be added to the README with the necessary ProGuard lines to delete the pre-Gingerbread implementations if the minSdkVersion is 9 or above.
    2. Instead of, or in addition to approach 1 would be to detect the minSdkVersion in the annotation processor and not generate the commit() calls if the minSdkVersion is 9 or above. I'm not sure how easy it is to get the minSdkVersion from the processor, so this might be impossible.
    3. Just get rid of the calls to commit() completely and say that Esperandro can only be used when minSdkVersion is 9 or above. :-)

    If you have a preferred approach, I'd be willing to implement it if it would be merged.

    opened by scompt 7
  • Poll: Change method names to Java Bean Accessor Syntax

    Poll: Change method names to Java Bean Accessor Syntax

    After seeing the discussion in #62 I think about adding the required naming scheme as additional possibility or changing the syntax completely in a new release.

    So this poll is about: a) add the possibility to use set and get additionally to the current method names where only the parameter determine the set/get operation. b) completely remove support for access via only method names and completely change it to set/get

    Pros/Cons for the set/get naming scheme:

    • (+) compliant to Java Bean Naming Convention and therefore better compatibility with potential other technologies like Kotlin
    • (+) more visible distinction between getter and setter
    • (-/+) getters with runtime defaults do not necessarily need a prefix and therefore a different name (getProperty(String default) would work whereas now it is property$Default(String default))
    • (-) extreme breaking API change
    • (-) understanding what the actual name of the preference will be is quite harder. (take the case into account: setProperty would still save into property not Property)

    Apologize for tagging you people, but you are the only ones I know that use the library, so to get feedback I specifically ask: @danielneu @mflisar @dmo60 @rguthor2 @anthony3444 @naixx @asadkt Hopefully you are not mad about this :D

    Thanks in Advance for feedback

    question 
    opened by dkunzler 6
  • Serializable problem

    Serializable problem

    Currently, if I use serializable lists, they are not working, as the generated code is wrapping a list in a container, that is NOT implementing serializable itself...

    NOT Working: Using following does crash, as the wrapper class is not serializable:

    ArrayList<String> existingSources();
    boolean existingSources(ArrayList<String>existingSources);
    

    working

    OwnWrapper existingSources();
    boolean existingSources(OwnWrapper  existingSources);
    

    With OwnWrapper like following:

    public static class OwnWrapper implements Serializable
    {
        public ArrayList<String> sources;
    
        public OwnWrapper ()
        {
            sources = new ArrayList<>();
        }
    }
    
    bug 
    opened by MFlisar 6
  • Deprecation warnings after migration to CompileSDK 29

    Deprecation warnings after migration to CompileSDK 29

    After migration to the compilesdk 29 lots of deprecation warnings regarding the use of android.preference.PreferenceManager are generated. The reason seems to be in the generated files of the annotation processor. Can this be configured to use androidx.preference.PreferenceManager or does this need a new esperandro version?

    opened by rguthor2 4
  • Serialisation bug

    Serialisation bug

    I have a field like following in my preferences to show some info cards to my users and to know which one they have already seen and dismissed:

    List<String> hiddenInfos();
    boolean hiddenInfos(List<String> hiddenInfos);
    void hiddenInfos$Add(String toAdd);
    void hiddenInfos$Remove(String toRemove);
    

    After my last relase I suddenly got a lot of crash reports like following:

    [SerializationUtil:43 deserialize]: java.io.InvalidClassException: com.my.app.prefs.PreferenceManager$$Impl$HiddenInfos; Incompatible class (SUID): com.my.app.prefs.PreferenceManager$$Impl$HiddenInfos: static final long serialVersionUID =8736114807095266538L; but expected com.my.app.prefs.PreferenceManager$$Impl$HiddenInfos: static final long serialVersionUID =3661852850784779536L;
    	at java.io.ObjectInputStream.verifyAndInit(ObjectInputStream.java:2343)
    	at java.io.ObjectInputStream.readNewClassDesc(ObjectInputStream.java:1643)
    	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:657)
    	at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1784)
    	at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:761)
    	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1985)
    	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1942)
    	at com.swissarmy.utils.SerializationUtil.deserialize(SerializationUtil.java:40)
    	at com.my.app.MainApp$1.deserialize(MainApp.java:76)
    	at com.my.app.prefs.PreferenceManager$$Impl.hiddenInfos(PreferenceManager$$Impl.java:1182)
    	at com.my.app.managers.UpdateManager.onAppStart(UpdateManager.java:208)
    	at com.my.app.MainApp.onAfterOnCreate(MainApp.java:151)
    	...
    

    I would expect that the serialVersionUID is constant... Maybe it makes sense to define a custom one via annotations? To avoid that the serialVersionUID is constant as this is essential for deserialisation...

    opened by MFlisar 4
  • Support functions or non constant values for default values

    Support functions or non constant values for default values

    Not sure if this is possible, but following (or something functional equivalent) would be nice:

    @Default(ofInt = Color.argb(100, 0, 0, 0))
    int handleColor();
    boolean handleColor(int handleColor);
    

    Any ideas on this?

    enhancement 
    opened by MFlisar 4
  • Bump gson from 2.8.5 to 2.8.9

    Bump gson from 2.8.5 to 2.8.9

    Bumps gson from 2.8.5 to 2.8.9.

    Release notes

    Sourced from gson's releases.

    Gson 2.8.9

    • Make OSGi bundle's dependency on sun.misc optional (#1993).
    • Deprecate Gson.excluder() exposing internal Excluder class (#1986).
    • Prevent Java deserialization of internal classes (#1991).
    • Improve number strategy implementation (#1987).
    • Fix LongSerializationPolicy null handling being inconsistent with Gson (#1990).
    • Support arbitrary Number implementation for Object and Number deserialization (#1290).
    • Bump proguard-maven-plugin from 2.4.0 to 2.5.1 (#1980).
    • Don't exclude static local classes (#1969).
    • Fix RuntimeTypeAdapterFactory depending on internal Streams class (#1959).
    • Improve Maven build (#1964).
    • Make dependency on java.sql optional (#1707).

    Gson 2.8.8

    • Fixed issue with recursive types (#1390).
    • Better behaviour with Java 9+ and Unsafe if there is a security manager (#1712).
    • EnumTypeAdapter now works better when ProGuard has obfuscated enum fields (#1495).
    Changelog

    Sourced from gson's changelog.

    Version 2.8.9

    • Make OSGi bundle's dependency on sun.misc optional (#1993).
    • Deprecate Gson.excluder() exposing internal Excluder class (#1986).
    • Prevent Java deserialization of internal classes (#1991).
    • Improve number strategy implementation (#1987).
    • Fix LongSerializationPolicy null handling being inconsistent with Gson (#1990).
    • Support arbitrary Number implementation for Object and Number deserialization (#1290).
    • Bump proguard-maven-plugin from 2.4.0 to 2.5.1 (#1980).
    • Don't exclude static local classes (#1969).
    • Fix RuntimeTypeAdapterFactory depending on internal Streams class (#1959).
    • Improve Maven build (#1964).
    • Make dependency on java.sql optional (#1707).

    Version 2.8.8

    • Fixed issue with recursive types (#1390).
    • Better behaviour with Java 9+ and Unsafe if there is a security manager (#1712).
    • EnumTypeAdapter now works better when ProGuard has obfuscated enum fields (#1495).

    Version 2.8.7

    • Fixed ISO8601UtilsTest failing on systems with UTC+X.
    • Improved javadoc for JsonStreamParser.
    • Updated proguard.cfg (#1693).
    • Fixed IllegalStateException in JsonTreeWriter (#1592).
    • Added JsonArray.isEmpty() (#1640).
    • Added new test cases (#1638).
    • Fixed OSGi metadata generation to work on JavaSE < 9 (#1603).

    Version 2.8.6

    2019-10-04 GitHub Diff

    • Added static methods JsonParser.parseString and JsonParser.parseReader and deprecated instance method JsonParser.parse
    • Java 9 module-info support
    Commits
    • 6a368d8 [maven-release-plugin] prepare release gson-parent-2.8.9
    • ba96d53 Fix missing bounds checks for JsonTreeReader.getPath() (#2001)
    • ca1df7f #1981: Optional OSGi bundle's dependency on sun.misc package (#1993)
    • c54caf3 Deprecate Gson.excluder() exposing internal Excluder class (#1986)
    • e6fae59 Prevent Java deserialization of internal classes (#1991)
    • bda2e3d Improve number strategy implementation (#1987)
    • cd748df Fix LongSerializationPolicy null handling being inconsistent with Gson (#1990)
    • fe30b85 Support arbitrary Number implementation for Object and Number deserialization...
    • 1cc1627 Fix incorrect feature request template label (#1982)
    • 7b9a283 Bump bnd-maven-plugin from 5.3.0 to 6.0.0 (#1985)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • 4.0.x changelog items

    4.0.x changelog items

    Very much appreciate what you're doing here. A couple of minor items:

    • The changelog link on README.md is incorrect ('changelog' in the link needs to be uppercase)
    • The changelog itself seems to be lagging the latest 4.0.x release(s). After digging, I found some info on the Migration wiki page, but unsure what other changes have taken place.
    opened by ghost 1
  • Add operations for ALL preference classes

    Add operations for ALL preference classes

    Add another processor that generates a class with all known (means same compilation unit) Shared Preference classes.

    We then can operate on all of them for example clear all, init defaults for all. This will add some interesting possibilities.

    opened by dkunzler 0
Releases(2.2.0)
Owner
David Kunzler
Android Expert, Flutter Dev, Security Enthusiast
David Kunzler
Android library which makes it easy to handle the different obstacles while calling an API (Web Service) in Android App.

API Calling Flow API Calling Flow is a Android library which can help you to simplify handling different conditions while calling an API (Web Service)

Rohit Surwase 19 Nov 9, 2021
:iphone: [Android Library] Get device information in a super easy way.

EasyDeviceInfo Android library to get device information in a super easy way. The library is built for simplicity and approachability. It not only eli

Nishant Srivastava 1.7k Dec 22, 2022
[] Easy async loading for Android's ListView/GridView

NOTE: Smoothie's API is not final yet. Although the library is fairly funcional, this is still beta-quality code. Do not rely on it for production cod

Lucas Rocha 988 Dec 22, 2022
Very easy to use wrapper library for Android SharePreferences

Treasure English document Treasure是一个Android平台上基于SharePreferences的偏好存储库,只需要定义接口,无需编写实现,默认支持Serializable和Parcelable。运行时0反射,不仅使用方便而且性能和原生写法几乎无差别。 使用方法 1

星一 507 Nov 12, 2022
Access and process various types of personal data in Android with a set of easy, uniform, and privacy-friendly APIs.

PrivacyStreams PrivacyStreams is an Android library for easy and privacy-friendly personal data access and processing. It offers a functional programm

null 269 Dec 1, 2022
It's finally easy to take photos/videos via camera or get photos/videos from gallery on Android.

Shutter-Android It's finally easy to take photos/videos via camera or get photos/videos from gallery on Android. What is Shutter? Shutter is an Androi

Levi Bostian 56 Oct 3, 2022
A simple and easy to use stopwatch and timer library for android

TimeIt Now with Timer support! A simple and easy to use stopwatch and timer library for android Introduction A stopwatch can be a very important widge

Yashovardhan Dhanania 35 Dec 10, 2022
An easy-to-use, cross-platform measurement tool that pulls data out of CD pipelines and analysis the four key metrics for you.

Maintained by SEA team, ThoughtWorks Inc. Read this in other languages: English, 简体中文 Table of Contents About the Project Usage How to Compute Contrib

Thoughtworks 277 Jan 7, 2023
Compose easy forms validation library

Compose EasyForms Focus on building your form UI while the library do the heavy work for you. Features Built in support for most of the Form widgets i

Kosh Sergani 24 Jul 18, 2022
Interactive prompts made easy!

Interactive prompts made easy!

David Simon 1 Nov 1, 2021
This is a easy way to publish MQTT message and receive MQTT message

SMQ-CLIENT This is a easy way to publish MQTT message and receive MQTT message This is provider a spring stater for quick use Recive message form the

SUDA 1 Apr 25, 2022
Android Shared preference wrapper than encrypts the values of Shared Preferences. It's not bullet proof security but rather a quick win for incrementally making your android app more secure.

Secure-preferences - Deprecated Please use EncryptedSharedPreferences from androidx.security in preferenced to secure-preference. (There are no active

Scott Alexander-Bown 1.5k Dec 24, 2022
Gesture detector framework for multitouch handling on Android, based on Android's ScaleGestureDetector

Android Gesture Detectors Framework Introduction Since I was amazed Android has a ScaleGestureDetector since API level 8 but (still) no such thing as

null 1.1k Nov 30, 2022
Use Android as Rubber Ducky against another Android device

Use Android as Rubber Ducky against another Android device

null 1.4k Jan 9, 2023
Android Utilities Library build in kotlin Provide user 100 of pre defined method to create advanced native android app.

Android Utilities Library build in kotlin Provide user 100 of pre defined method to create advanced native android app.

Shahid Iqbal 4 Nov 29, 2022
A util for setting status bar style on Android App.

StatusBarUtil A util for setting status bar style on Android App. It can work above API 19(KitKat 4.4). 中文版点我 Sample Download StatusBarUtil-Demo Chang

Jaeger 8.8k Jan 6, 2023
A logger with a small, extensible API which provides utility on top of Android's normal Log class.

This is a logger with a small, extensible API which provides utility on top of Android's normal Log class. I copy this class into all the little apps

Jake Wharton 9.8k Dec 30, 2022
Java implementation of a Disk-based LRU cache which specifically targets Android compatibility.

Disk LRU Cache A cache that uses a bounded amount of space on a filesystem. Each cache entry has a string key and a fixed number of values. Each key m

Jake Wharton 5.7k Dec 31, 2022
a simple cache for android and java

ASimpleCache ASimpleCache 是一个为android制定的 轻量级的 开源缓存框架。轻量到只有一个java文件(由十几个类精简而来)。 1、它可以缓存什么东西? 普通的字符串、JsonObject、JsonArray、Bitmap、Drawable、序列化的java对象,和 b

Michael Yang 3.7k Dec 14, 2022