欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Kotlin 封装万能SharedPreferences存取任何类型详解

程序员文章站 2023-11-29 11:31:58
kotlin 封装万能sharedpreferences存取任何类型详解 /** * author: smart * time: 2016/10/26...

kotlin 封装万能sharedpreferences存取任何类型详解

/**
 * author: smart
 * time: 2016/10/26
 * 封装好sharedpreferences 并使用 序列化和反序列化来存储数据
 * 注意要在全局环境使用
 */
class preference<t>(val context : context,val name : string,val default : t) : readwriteproperty<any?,t>{

  val prefs by lazy{context.getsharedpreferences("realnen",context.mode_private)}


  override fun getvalue(thisref: any?, property: kproperty<*>): t {
    return findpreference(name,default)
  }

  override fun setvalue(thisref: any?, property: kproperty<*>, value: t) {
    putpreference(name,value)
  }

  /**
   * 查找数据 返回给调用方法一个具体的对象
   * 如果查找不到类型就采用反序列化方法来返回类型
   * default是默认对象 以防止会返回空对象的异常
   * 即如果name没有查找到value 就返回默认的序列化对象,然后经过反序列化返回
   */
  private fun <a> findpreference(name :string,default: a) : a = with(prefs){
    val res : any = when(default){
      is long -> getlong(name,default)
      is string -> getstring(name,default)
      is int -> getint(name,default)
      is boolean -> getboolean(name,default)
      is float -> getfloat(name,default)
      else -> deserialization(getstring(name,serialize(default)))
    }
    res as a
  }

  private fun <a> putpreference(name :string,value: a) = with(prefs.edit()){
    when(value){
      is long -> putlong(name,value)
      is string -> putstring(name,value)
      is int -> putint(name,value)
      is boolean -> putboolean(name,value)
      is float -> putfloat(name,value)
      else -> putstring(name,serialize(value))
    }.apply()

  }

  /**
   * 删除全部数据
   */
  fun clearpreference(){
    prefs.edit().clear().commit()
  }

  /**
   * 根据key删除存储数据
   */
  fun clearpreference(key : string){
    prefs.edit().remove(key).commit()
  }

  /**
   * 序列化对象

   * @param person
   * *
   * @return
   * *
   * @throws ioexception
   */
  @throws(ioexception::class)
  private fun<a> serialize(obj: a): string {
    val bytearrayoutputstream = bytearrayoutputstream()
    val objectoutputstream = objectoutputstream(
        bytearrayoutputstream)
    objectoutputstream.writeobject(obj)
    var serstr = bytearrayoutputstream.tostring("iso-8859-1")
    serstr = java.net.urlencoder.encode(serstr, "utf-8")
    objectoutputstream.close()
    bytearrayoutputstream.close()
    return serstr
  }

  /**
   * 反序列化对象

   * @param str
   * *
   * @return
   * *
   * @throws ioexception
   * *
   * @throws classnotfoundexception
   */
  @throws(ioexception::class, classnotfoundexception::class)
  private fun<a> deserialization(str: string): a {
    val redstr = java.net.urldecoder.decode(str, "utf-8")
    val bytearrayinputstream = bytearrayinputstream(
        redstr.tobytearray(charset("iso-8859-1")))
    val objectinputstream = objectinputstream(
        bytearrayinputstream)
    val obj = objectinputstream.readobject() as a
    objectinputstream.close()
    bytearrayinputstream.close()
    return obj
  }
}

这里主要用的是代理模式,还有数据类要实现序列化serializable接口,使用方式:

 var save : loginsavebean by preference<loginsavebean>(app.getinstance(),constant.local_save_login_model_key, loginsavebean("0","0"))

注意 这条语句我们要放在全局变量来读取,当你改变值或者值被改变时,这里的值会自己提交和同步。

感谢 阅读,希望能帮助到大家,谢谢大家对本站的支持!