SharePreference saves objects and collections

Reprint https://blog.csdn.net/qq_21937107/article/details/79735236

In Android, we often need to persist data. At this time, we can use files, SharePreference, and SQLite. What if I want to save an object? Some people will immediately think of using the ORM framework, but I probably don't want to rely on this framework. In fact, if the amount of data is not large, using SharePreference may be more suitable. We can completely implement a SharePreference version of the tool class for persisting objects.

look directly at the code

public class SpUtils {
    //此处设置默认文件名
    private static final String DEFAULT_SP_NAME = "default_sp";

    public static <T> T getObject(Context context, Class<T> clazz) {
        String key = getKey(clazz);
        String json = getString(context, key, null);
        if (TextUtils.isEmpty(json)) {
            return null;
        }
        try {
            Gson gson = new Gson();
            return gson.fromJson(json, clazz);
        } catch (Exception e) {
            return null;
        }
    }

    public static void putObject(Context context, Object object) {
        String key = getKey(object.getClass());
        Gson gson = new Gson();
        String json = gson.toJson(object);
        putString(context, key, json);
    }

    public static void removeObject(Context context, Class<?> clazz){
        remove(context, getKey(clazz));
    }

    public static String getKey(Class<?> clazz) {
        return clazz.getName();
    }

    public static void remove(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(DEFAULT_SP_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor edit = sp.edit();
        edit.remove(key);
        edit.commit();
    }

    public static void putString(Context context, String key, String value) {
        SharedPreferences sp = context.getSharedPreferences(DEFAULT_SP_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor edit = sp.edit();
        edit.putString(key, value);
        edit.commit();
    }

    public static String getString(Context context, String key, String defValue) {
        SharedPreferences sp = context.getSharedPreferences(DEFAULT_SP_NAME, Context.MODE_PRIVATE);
        return sp.getString(key, defValue);
    }

}
  • In the putObject() method, we use the object's class name as the key and the object's json string as the value to save it to SharePreference.
  • In the getObject() method, we first get the name of the class, then use it as the key, then get the corresponding string from SharePreference, and then convert the json string into an object through Gson.

If the class I want to save is a generic type, for example List<Person>, the above method will definitely not work, because the generic type will be erased, List<String>and List<Person>both are the same class. For generic erasure, please refer to: Java's Generic Erasure and Runtime Generic Information Acquisition .

So how to deal with generics?

Looking back at parsing generic classes with Gson, we may have written code like the following:

String json = result;
Gson gson = new Gson();
Type type =  new TypeToken<List<Person>>() {/*注意这里有个大括号*/}.getType());
List<Person> list = gson.fromJson(json, type);

Here, TypeToken is used to obtain generic information.

Ok, we already have an idea

public class SpUtils {
    // 获取一个泛型的对象
    public static <T> T getObject(Context context, Type type) {
        String key = getKey(type);
        String json = getString(context, key, null);
        if (TextUtils.isEmpty(json)) {
            return null;
        }
        try {
            Gson gson = new Gson();
            return gson.fromJson(json, type);
        } catch (Exception e) {
            return null;
        }
    }
    // 保存一个泛型的对象
    public static void putObject(Context context, Object object, Type type) {
        String key = getKey(type);
        Gson gson = new Gson();
        String json = gson.toJson(object);
        putString(context, key, json);
    }

    public static void removeObject(Context context, Type type) {
        remove(context, getKey(type));
    }

    public static String getKey(Type type) {
        return type.toString();
    }

}
  • In the getObject() method, use the Type parameter instead of the original Class
  • In the putObject() method, a Type parameter is added to obtain the key in the SharePreference.

It's also not difficult to use:

List<Person> list = new ArrayList<>();
Person p = new Person(20, "张三1");
list.add(p);

p = new Person(20, "张三2");
list.add(p);
// 保存一个泛型对象
SpUtils.putObject(context, list,
        new TypeToken<List<Person>>() { }.getType());

// 获取一个泛型对象
List<Person> list2 = SpUtils.getObject(context,
        new TypeToken<List<Person>>() { }.getType());

The complete code is as follows:

import android.content.Context;
import android.content.SharedPreferences;
import android.text.TextUtils;

import com.google.gson.Gson;

import java.lang.reflect.Type;

public class SpUtils {

    private static final String DEFAULT_SP_NAME = "default_sp";

    // 通过类名字去获取一个对象
    public static <T> T getObject(Context context, Class<T> clazz) {
        String key = getKey(clazz);
        String json = getString(context, key, null);
        if (TextUtils.isEmpty(json)) {
            return null;
        }
        try {
            Gson gson = new Gson();
            return gson.fromJson(json, clazz);
        } catch (Exception e) {
            return null;
        }
    }

    // 通过Type去获取一个泛型对象
    public static <T> T getObject(Context context, Type type) {
        String key = getKey(type);
        String json = getString(context, key, null);
        if (TextUtils.isEmpty(json)) {
            return null;
        }
        try {
            Gson gson = new Gson();
            return gson.fromJson(json, type);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 保存一个对象,object必须是普通类,而不是泛型,如果是泛型,请使用 {@link SpUtils#putObject(Context, Object, Type)}
     *
     * @param context
     * @param object
     */
    public static void putObject(Context context, Object object) {
        String key = getKey(object.getClass());
        Gson gson = new Gson();
        String json = gson.toJson(object);
        putString(context, key, json);
    }

    /**
     * 保存一个泛型对象
     *
     * @param context
     * @param object
     * @param type    如果你要保存 List<Person> 这个类, type应该 传入 new TypeToken<List<Person>>() {}.getType()
     */
    public static void putObject(Context context, Object object, Type type) {
        String key = getKey(type);
        Gson gson = new Gson();
        String json = gson.toJson(object);
        putString(context, key, json);
    }

    public static void removeObject(Context context, Class<?> clazz) {
        remove(context, getKey(clazz));
    }

    public static void removeObject(Context context, Type type) {
        remove(context, getKey(type));
    }

    public static String getKey(Class<?> clazz) {
        return clazz.getName();
    }

    public static String getKey(Type type) {
        return type.toString();
    }

    public static void remove(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(DEFAULT_SP_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor edit = sp.edit();
        edit.remove(key);
        edit.commit();
    }

    public static void putString(Context context, String key, String value) {
        SharedPreferences sp = context.getSharedPreferences(DEFAULT_SP_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor edit = sp.edit();
        edit.putString(key, value);
        edit.commit();
    }

    public static String getString(Context context, String key, String defValue) {
        SharedPreferences sp = context.getSharedPreferences(DEFAULT_SP_NAME, Context.MODE_PRIVATE);
        return sp.getString(key, defValue);
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325868482&siteId=291194637