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

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"))

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

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

(0)

相关推荐

  • kotlin基础教程之类和继承

    kotlin基础教程之类和继承 类声明 使用class关键字声明类,查看其声明格式: : modifiers ("class" | "interface") SimpleName typeParameters? primaryConstructor? (":" annotations delegationSpecifier{","})? typeConstraints (classBody? | enumClassBody)

  • 详解Kotlin中如何实现类似Java或C#中的静态方法

    大家可以在网络上搜到不少这样的文章,官方推荐是包级函数,也有人说用伴生对象(companion class).这些都是不错的选择,但并不完善,我们在不同的情况下有更好的选择.我总结了几种方法,分别是:包级函数.伴生对象.扩展函数和对象声明.这需要大家根据不同的情况进行选择. 一.包级函数 Kotlin和Java及C#不同的是,可以在包里面直接声明函数.做法和类中是一样的,这里就不多说了,的确是一个非常好的选择.适用于函数不需要不包内部的类进行数据共享的方法. 二.伴生对象 从语义上来讲,伴生函数

  • Kotlin 的注解类详解及实例

    Kotlin 的注解类详解及实例 注解声明 注解是将元数据附加到代码的方法.要声明注解,请将 annotation 修饰符放在类的前面: annotation class Fancy 注解的附加属性可以通过用元注解标注注解类来指定: @Target 指定可以用 该注解标注的元素的可能的类型(类.函数.属性.表达式等): @Retention 指定该注解是否 存储在编译后的 class 文件中,以及它在运行时能否通过反射可见 (默认都是 true): @Repeatable 允许 在单个元素上多次

  • Kotlin教程之基本数据类型

    Kotlin教程之基本数据类型的学习 基本类型 我们知道java的基本类型分为基本数据类型: int 普通整型 float 浮点型 char 字符型 short 短整型 byte 字节型 long 长整型 double 双精度 boolean 布尔型 和引用数据类型: class Type 类类型 interface Type 接口类型 array Type 数组类型 null Type 空类型 在 Kotlin 中,所有变量的成员方法和属性都是一个对象.一些类型是内建的,因为它们的实现是优化过

  • Kotlin 基础教程之类、对象、接口

    Kotlin 基础教程之类.对象.接口 Kotlin中类.接口相关概念与Java一样,包括类名.属性.方法.继承等,如下示例: interface A { fun bar() fun foo() { // 可选方法体 } } class Child: A { override fun bar() { // todo } override fun foo() { super.foo() } } class 构造器 Kotlin 中的类可以有一个 主构造器, 以及一个或多个次构造器, 主构造器是类头

  • Kotlin基础教程之伴生对象,getter,setter,内部,局部,匿名类,可变参数

    先来看一个名为Message的类 在这个类中有一段包含在companion object中的代码,需要说一下的是,Kotlin的class并不支持static变量,所以需要使用companion object来声明static变量,其实这个platformStatic变量也不是真正的static变量,而是一个伴生对象, 这个伴生对象位于Message类中定义的一个叫做Companion的内部类中,如图: 可以看到在Kotlin中编译器自动生成类是很常见的事情,那么这个伴生对象作何理解呢? 我的理

  • Kotlin基础教程之数据类型

    Kotlin基础教程之数据类型 一切都是对象. 在Kotlin中一切都是对象.Kotlin有一些基本类型Boolean,Byte,Shot,Int,Long,Float,Double 在Kotlin中没有原始类型,以上这些类型都是对象,比如 运行结果如下 Kotlin支持16进制字面值,二进制字面值和科学记数法,官方文档中没有提到8进制 所有基本的几个数据类型不会进行显式类型转换,这一点尤为重要!那么如何进行转换呢?如下: 可以使用toLong,toInt,toShort,toChar等函数进行

  • Kotlin基础教程之dataclass,objectclass,use函数,类扩展,socket

    Kotlin基础教程之dataclass,objectclass,use函数,类扩展,socket Kotlin提供了一些机制来扩展已有的类,如下: 还记得我们之前写过的Point3D类吗?(将其略作修改,将成员变量改为Double类型) 让我们为其扩展一个length函数 扩展的方法很简单,只要在函数名前面加上类名就行了. 这样Point3D的对象就有了一个名为length的方法. 运行的结果不出所料: 除此之外,在Kotlin中还有一些特殊的类,比如Data Class: 有些类只包含数据,

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

    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

  • Java基本数据类型与封装类型详解(int和Integer区别)

    int是java提供的8种原始数据类型之一. Java为每个原始类型提供了封装类,Integer是java为int提供的封装类(即Integer是一个java对象,而int只是一个基本数据类型).int的默认值为0,而Integer的默认值为null,即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的情况,例如,要想表达出没有参加考试和考试成绩为0的区别,则只能使用Integer.在JSP开发中,Integer的默认为null,所以用el表达式在文本框中显示时,值为空白字

  • Kotlin协程launch启动流程原理详解

    目录 1.launch启动流程 反编译后的Java代码 2.协程是如何被启动的 1.launch启动流程 已知协程的启动方式之一是Globalscope.launch,那么Globalscope.launch的流程是怎样的呢,直接进入launch的源码开始看起. fun main() { coroutineTest() Thread.sleep(2000L) } val block = suspend { println("Hello") delay(1000L) println(&q

  • Kotlin 语言中调用 JavaScript 方法实例详解

    Kotlin 语言中调用 JavaScript 方法实例详解 Kotlin 已被设计为能够与 Java 平台轻松互操作.它将 Java 类视为 Kotlin 类,并且 Java 也将 Kotlin 类视为 Java 类.但是,JavaScript 是一种动态类型语言,这意味着它不会在编译期检查类型.你可以通过动态类型在 Kotlin 中自由地与 JavaScript 交流,但是如果你想要 Kotlin 类型系统的全部威力 ,你可以为 JavaScript 库创建 Kotlin 头文件. 内联 J

  • kotlin 官方学习教程之基础语法详解

    kotlin 官方学习教程之基础语法详解 Google 在今天的举行了 I/O 大会,大会主要主要展示内有容 Android O(Android 8.0)系统.Google Assistant 语音助手.Google 智能音箱.人工智能.机器学习.虚拟现实等.作为一个 Android 开发者,我关心的当然是 Android O(Android 8.0)系统了,那么关于 Android O 系统的一个重要消息是全面支持 Kotlin 编程语言,使得 Kotlin 成为了 Android 开发的官方

  • Python 变量类型详解

    变量存储在内存中的值.这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同的数据类型,这些变量可以存储整数,小数或字符. 变量赋值 Python 中的变量赋值不需要类型声明. 每个变量在内存中创建,都包括变量的标识,名称和数据这些信息. 每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建. 等号(=)用来给变量赋值. 等号(=)运算符左边是一个变量名,等号(=)运算符右边是存储在变量中的值. 例

  • Kotlin修饰符lateinit(延迟初始化)案例详解

    Kotlin定义变量一般有如下写法 lateinit var name: String var age: String? = null 那么用lateinit 修饰和下面那种有什么区别呢,我们来看一下这两行代码反编译成java代码是什么样子的. @NotNull public String name; @Nullable private String age; @NotNull public final String getName() { String var10000 = this.name

  • Kotlin startActivity跳转Activity实现流程详解

    目录 带参数的调整 自定义数据传输 startActivityForResult 小结 从一个Activity跳到另一个Activity 在编写安卓代码是最常见的事情了.我们不可能在一个页面中,把所有的事情都做完. 在kotlin中跳转的程序也比较简单,跟java差不多.如果熟悉java代码的话,只需要把代码改变过来而已. 带参数的调整 从一个Activity跳到另一个Activity 中,如同调用函数一样,可以把数据传递给另外的Activity中,Activity在接受到这个数据后,可以根据数

  • Golang拾遗之实现一个不可复制类型详解

    目录 如何复制一个对象 为什么要禁止复制 运行时检测实现禁止复制 初步尝试 更好的实现 性能 优点和缺点 静态检测实现禁止复制 利用Locker接口不可复制实现静态检测 优点和缺点 更进一步 利用package和interface进行封装 优点和缺点 总结 如何复制一个对象 不考虑IDE提供的代码分析和go vet之类的静态分析工具,golang里几乎所有的类型都能被复制. // 基本标量类型和指针 var i int = 1 iCopy := i str := "string" st

  • Javascript类型系统之String字符串类型详解

    javascript没有表示单个字符的字符型,只有字符串String类型,字符型相当于仅包含一个字符的字符串 字符串String是javascript基本数据类型,同时javascript也支持String对象,它是一个原始值的包装对象.在需要时,javascript会自动在原始形式和对象形式之间转换.本文将介绍字符串String原始类型及String包装对象 定义 字符串String类型是由引号括起来的一组由16位Unicode字符组成的字符序列 字符串类型常被用于表示文本数据,此时字符串中的

随机推荐