Android Framework Learning; A Smart and Powerful Key-Value Management Framework

DoKV

DoKV is a compact and powerful Key-Value management framework designed to solve all kinds of tedious and ugly configuration class codes on Android platform.

Download

dependencies {
    implementation 'leavesc.hello:dokv:0.1.8'
    annotationProcessor 'leavesc.hello:dokv-compiler:0.1.8'
}

If you don't want to customize the serialization scheme, you can use my other open source implementation

dependencies {
    implementation 'leavesc.hello:dokv-impl:0.1.8'
}

I. Introduction

It's small because the implementation of DoKV only relies on one annotation, one interface and four classes. Of course, the foundation of its implementation is not only that, but also the support of APT technology, which relies on APT to generate some intermediate code automatically.

It's powerful because you can basically discard the following types of code by using DoKV

SharedPreferences sharedPreferences = getSharedPreferences("SharedPreferencesName", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString("IP", "192.168.0.1");
        editor.commit();
        String userName = sharedPreferences.getString("userName", "");
        String ip = sharedPreferences.getString("IP", "");

Usually, our applications have many configuration items that need to be cached, such as user information, settings switch, server IP address, etc. If implemented with native Shared Preferences, it's easy to write ugly code like the one shown above, which not only needs to maintain the key value of multiple data items, but also has a large amount of duplicate code every time data is stored and retrieved, which is not easy to maintain.

What about the performance of DoKV?

It's simple!!!

Suppose your application contains a User class for caching user information. First, add a comment to this class: @DoKV

/**
 * Author: leavesC
 * Time: 2019/03/170:12
 * Description:
 * GitHub: https://github.com/leavesC
 * Blog: https://www.jianshu.com/u/9df45b87cfdf
 */
@DoKV
public class User {

    private String name;

    private int age;

    private String sex;

    private Book book;

    private List<String> stringList;

	···

}

build, DoKV will automatically generate a Java class (UserDoKV) ending with the class name + DoKV for you, then you can access the data in the form of the following, and you don't need to care about how it is stored internally (of course, its internal caching mechanism can be customized by you)

//Caching the entire object
        User user = new User();
        user.setAge(24);
        user.setName("leavesC");
        UserDoKV.get().setUser(user);

        //Get the cached object
        User user1 = UserDoKV.get().getUser();

        //Update a settings item for locally cached data
        //If you haven't cached before, an object is automatically new and automatically assigned.
        //Because DoKV requires that annotation classes must contain a parametric constructor and contain fields with corresponding Get and Set methods
        UserDoKV.get().setName("leavesCZY");
        UserDoKV.get().setAge(28);

        //Remove cached data
        UserDoKV.get().remove();

        //Remove all cached data
        DoKV.clear();

As mentioned above, DoKV relies on APT technology, and its actual principle is that developers define the rules of target code by inheriting AbstractProcessor, and the compiler generates the target code according to this rule. So the execution efficiency of DoKv is just like the construction of a general Java class, and there is no situation that depends on reflection to reduce performance.

The UserDoKV class is defined as follows:

public class UserDoKV extends User {

    private static final String KEY = "leavesc.hello.dokv.model.UserDoKV";

    private UserDoKV() {
    }

    public static UserDoKV get() {
        return new UserDoKV();
    }

    private IDoKVHolder getDoKVHolder() {
        return DoKV.getInstance().getDoKVHolder();
    }

    private String serialize(String _KEY, User _User) {
        return getDoKVHolder().serialize(_KEY, _User);
    }

    private User deserialize(String _KEY) {
        return getDoKVHolder().deserialize(_KEY, User.class);
    }

    public User getUser() {
        return deserialize(KEY);
    }

    private User getUserNotNull() {
        User variable = deserialize(KEY);
        if (variable != null) {
            return variable;
        }
        return new User();
    }

    public String setUser(User instance) {
        if (instance == null) {
            remove();
            return "";
        }
        return serialize(KEY, instance);
    }

    public void remove() {
        getDoKVHolder().remove(KEY);
    }

    @Override
    public String getName() {
        User variable = getUser();
        if (variable != null) {
            return variable.getName();
        }
        return super.getName();
    }

    @Override
    public void setName(String _name) {
        User _user = getUserNotNull();
        _user.setName(_name);
        serialize(KEY, _user);
    }

	//Eliminate similar Get/Set methods
}

Custom Cache Key

Before v0.1.7, DoKV defaulted to the class path of annotated classes as the cache Key to ensure the uniqueness of the Key value, but considering that annotated classes may be moved to other packages in subsequent development, resulting in the loss of cached data, because in v0.1.7, the Key attribute was added to annotated DoKV, and if the developer assigned a value to the attribute, the Key attribute can be used. Values are cached as keys, and the uniqueness of that Key needs to be guaranteed by the developer himself

@DoKV(key = "CustomKeyUser_Key")
public class CustomKeyUser {

   ···

}
public class CustomKeyUserDoKV extends CustomKeyUser {

    private static final String KEY = "CustomKeyUser_Key";

    ```

}

Three. Introduction

In order to achieve higher degrees of freedom, DoKV defaults to external implementation of data persistence, i.e. the user decides how to serialize objects to local storage, at which point you can choose to rely only on the following two references

dependencies {
    implementation 'leavesc.hello:dokv:xxx'
    annotationProcessor 'leavesc.hello:dokv-compiler:xxx'
}

Then, the IDoKVHolder instance can be passed to DoKV externally.

DoKV.init(new IDoKVHolder() {

            //serialize
            [@Override](https://my.oschina.net/u/1162528)
            public String serialize(String key, Object src) {
                return null;
            }

            //De serialization
            [@Override](https://my.oschina.net/u/1162528)
            public <T> T deserialize(String key, Class<T> classOfT) {
                return null;
            }

            //Remove the specified object
            [@Override](https://my.oschina.net/u/1162528)
            public void remove(String key) {

            }

            //Delete global cache data
            [@Override](https://my.oschina.net/u/1162528)
            public void clear() {

            }
        });

If you don't want to implement IDoKVHolder on your own, DoKV also provides a default implementation, at which point you just need to refer to the following dependencies, which are internally serialized through Gson + MMKV

dependencies {
    implementation 'leavesc.hello:dokv-impl:xxx'
}

After initialization, you can play freely.

DoKV.init(new MMKVDoKVHolder(Context));

Last

If you see it here and think it's a good article, give it a compliment! _____________ Welcome to comment and discuss! If you think it's worth improving, please leave me a message. We will seriously enquire, correct deficiencies, and regularly share free dry goods. Interested small partners can pay attention to it. Thank you!

Keywords: Mobile Attribute Java github Android

Added by Jezza22 on Sat, 05 Oct 2019 14:35:22 +0300