Kotlin系列

Kotlin版本SharedPreferences数据保存

2020-04-07  本文已影响0人  狼性代码人
  • Java版数据保存
  • Kotlin版本数据保存
  • ContentProvider获取Context

一、Java版数据保存

  在android开发中通常我们会使用SharedPreferences进行少量数据的保存,并对SharedPreferences进行简单封装,代码可能如下:

import android.content.Context;
import android.content.SharedPreferences;

public class SharedPrefUtil {
    private SharedPreferences mSharedPrefs;
    private SharedPreferences.Editor mEditor;

    public SharedPrefUtil(Context ctx, String name) {
        mSharedPrefs = ctx.getSharedPreferences(name, Context.MODE_PRIVATE);
        mEditor = mSharedPrefs.edit();
    }

    public void putString(String name, String value) {
        mEditor.putString(name, value).apply();
    }

    public String getString(String name, String defaultValue) {
        return mSharedPrefs.getString(name, defaultValue);
    }

    public void putLong(String name, Long value) {
        mEditor.putLong(name, value).apply();
    }

    public Long getLong(String name, Long defaultValue) {
        return mSharedPrefs.getLong(name, defaultValue);
    }
    
    .......
}
import android.content.Context;

public class Setting {
    private static volatile Setting INSTANCE = null;

    private final SharedPrefUtil mUtil;

    private Setting(Context ctx) {
        mUtil = new SharedPrefUtil(ctx, "setting.json");
    }

    public static Setting getInstance(Context ctx) {
        if (INSTANCE == null) {
            synchronized (Setting.class) {
                if (INSTANCE == null) INSTANCE = new Setting(ctx);
            }
        }
        return INSTANCE;
    }

    private String name = null;
    private Long uid = -1L;

    public String getName() {
        if (name == null)
            name = mUtil.getString("name", "");
        return name;
    }

    public void setName(String name) {
        mUtil.putString("name", name == null ? "" : name);
        this.name = name;
    }

    public Long getUid() {
        if (uid == -1L)
            uid = mUtil.getLong("uid", -1L);
        return uid;
    }

    public void setUid(Long uid) {
        mUtil.putLong("uid", uid);
        this.uid = uid;
    }
}
final Context context = this.getBaseContext();
Setting.getInstance(context).setName("小三");
String name = Setting.getInstance(context).getName();

  上面的代码实现起来并不复杂,使用起来好像也不麻烦,但当我们需要增加保存的数据时,就需要在Setting对象中增加大量的setget方法,而且使用的时候都要先获去Setting实例。如果能像使用变量一样使用SharedPreferences会多么美好!!!

二、Kotlin版本数据保存

class SharedPref<T>(
    private val context: Context,
    private val name: String,
    private val defValue: T,
    private val pref: String = "default",
    private val commit: Boolean = false
) : ReadWriteProperty<Any?, T> {

    private val prefs by lazy {
        context.getSharedPreferences(pref, Context.MODE_PRIVATE)
    }

    override fun getValue(thisRef: Any?, property: KProperty<*>): T =
        findPreference(findProperName(property))

    override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) =
        putPreference(findProperName(property), value)

    private fun findProperName(property: KProperty<*>) = if (name.isEmpty()) property.name else name

    private fun findPreference(key: String): T = when (defValue) {
        is Int -> prefs.getInt(key, defValue)
        is Long -> prefs.getLong(key, defValue)
        is Float -> prefs.getFloat(key, defValue)
        is Boolean -> prefs.getBoolean(key, defValue)
        is String -> prefs.getString(key, defValue)
        else -> throw IllegalArgumentException("Unsupported type.")
    } as T

    private fun putPreference(key: String, value: T) {
        val edit = prefs.edit().apply {
            when (value) {
                is Int -> putInt(key, value)
                is Long -> putLong(key, value)
                is Float -> putFloat(key, value)
                is Boolean -> putBoolean(key, value)
                is String -> putString(key, value)
                else -> throw IllegalArgumentException("Unsupported type.")
            }
        }
        commit.yes { edit.commit() }.other { edit.apply() }
    }

}
private lateinit var APPCTX: Context

object Setting {
    var name by SharedPref(APPCTX, "", "")
    var uid by SharedPref(APPCTX, "uid", -1L)
}
Setting.name = "小三"
Log.e(Setting.name)

三、ContentProvider获取Context

  上面的Context来源都是通过外部传递过来的,如果在module中使用就会变得不方便。不过通过在AndroidManifest.xml中注册ContentProvider就可以解决这个问题。

class InitProvider : ContentProvider() {

    override fun onCreate(): Boolean {
        // 这里可以获得 context 属性
        return false
    }

    override fun insert(uri: Uri, values: ContentValues?): Uri? = null

    override fun query(
        uri: Uri,
        projection: Array<out String>?,
        selection: String?,
        selectionArgs: Array<out String>?,
        sortOrder: String?
    ): Cursor? = null

    override fun update(
        uri: Uri,
        values: ContentValues?,
        selection: String?,
        selectionArgs: Array<out String>?
    ): Int = 0

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int = 0

    override fun getType(uri: Uri): String? = null
}
    <application>
        <!-- 去context实现 -->
        <provider
            android:name=".init.InitProvider"
            android:authorities="${applicationId}.common.provider"
            android:exported="false"
            android:multiprocess="true" />
    </application>

  这样我们在主app:module中不用添加一句代码就已经可以在需要Contextmodule中或得到Context对象。

上一篇下一篇

猜你喜欢

热点阅读