Browse Source

序列化、SP数据相关扩展类

liuxiaolong 2 years ago
parent
commit
cb0daad0c2

+ 16 - 1
app/src/main/java/com/kdanmobile/android/lib/MainActivity.kt

@@ -2,11 +2,26 @@ package com.kdanmobile.android.lib
 
 import androidx.appcompat.app.AppCompatActivity
 import android.os.Bundle
+import android.util.Log
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.kdanmobile.android.common.extension.*
+import com.kdanmobile.android.common.utils.string.GsonUtil
+import com.kdanmobile.android.common.utils.string.SerializableUtil
+import com.kdanmobile.android.common.utils.string.SharedPreferencesSave
+import com.orhanobut.logger.Logger
+import java.io.Serializable
 
 class MainActivity : AppCompatActivity() {
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContentView(R.layout.activity_main)
+
     }
-}
+}
+
+data class TestBean(
+    val name : String,
+    val age : Int
+) : Serializable

+ 69 - 0
lib_common/src/main/java/com/kdanmobile/android/common/extension/SpExtensions.kt

@@ -0,0 +1,69 @@
+package com.kdanmobile.android.common.extension
+
+import android.content.Context
+import com.kdanmobile.android.common.utils.string.SharedPreferencesSave
+
+/**
+ * @classname:
+ * @auther: LiuXiaoLong
+ * @date: 2022/8/2
+ * description: SP 存储数据相关扩展类
+ */
+
+
+fun <T : Any> Context.spSave(key: String, value : T){
+    SharedPreferencesSave.instance.also {
+        when(value){
+            is String-> it.saveStringValue(context = this, key = key, value = value)
+            is Int -> it.saveIntValue(context = this, key = key, value = value)
+            is Float -> it.saveFloatValue(context = this, key = key, value = value)
+            is Boolean -> it.saveBooleanValue(context = this, key = key, value = value)
+            is Long -> it.saveLongValue(context = this, key = key, value = value)
+            is Map<*, *> -> it.saveMap(context = this, key = key, map = value)
+            is List<*> -> it.saveList(context = this, key = key, list = value)
+            else->{
+               it.saveObject(context = this, key = key, ob = value)
+            }
+        }
+    }
+}
+
+
+fun Context.removeKey(key: String){
+    SharedPreferencesSave.instance.removeKey(context = this, key = key)
+}
+
+
+fun Context.spGetString(key: String, defaultValue: String = "") : String{
+    return SharedPreferencesSave.instance.getStringValue(context = this, key = key, defaultValue = defaultValue)
+}
+
+fun Context.spGetInt(key: String, defaultValue: Int = 0) : Int{
+    return SharedPreferencesSave.instance.getIntValue(context = this, key = key, defaultValue = defaultValue)
+}
+
+fun Context.spGetBoolean(key: String, defaultValue: Boolean) : Boolean{
+    return SharedPreferencesSave.instance.getBooleanValue(context = this, key = key, defaultValue = defaultValue)
+}
+
+fun Context.spGetFloat(key: String, defaultValue: Float = 0F) : Float{
+    return SharedPreferencesSave.instance.getFloatValue(context = this, key = key,)
+}
+
+fun Context.spGetLong(key: String, defaultValue: Long = 0L) : Long{
+    return SharedPreferencesSave.instance.getLongValue(context = this, key = key, defaultValue = defaultValue)
+}
+
+fun <T> Context.spGetObj(key: String) : T?{
+    return SharedPreferencesSave.instance.getObject(context = this, key = key)
+}
+
+inline fun <reified K,reified V> Context.spGetMap(key: String) : Map<K,V>{
+    return SharedPreferencesSave.instance.getMap<K,V>(context = this, key = key)
+}
+
+inline fun <reified E> Context.spGetList(key: String) : List<E>{
+    return SharedPreferencesSave.instance.getList<E>(context = this, key = key)
+}
+
+

+ 79 - 5
lib_common/src/main/java/com/kdanmobile/android/common/extension/StringExtensions.kt

@@ -3,22 +3,27 @@ package com.kdanmobile.android.common.extension
 import android.os.Build
 import android.text.Html
 import android.text.Spanned
+import com.kdanmobile.android.common.utils.string.GsonUtil
+import com.kdanmobile.android.common.utils.string.SerializableUtil
+import java.io.Serializable
 import java.util.regex.Pattern
 
 /**
  * @classname:
  * @auther: LiuXiaoLong
  * @date: 2022/7/29
- * description:
+ * description: 字符串相关扩展类
  */
 
-fun ByteArray.toHex() : String{
-    return joinToString(separator = ""){eachByte->
+fun ByteArray.toHex(): String {
+    return joinToString(separator = "") { eachByte ->
         "%02x".format(eachByte)
     }.uppercase()
 }
 
-
+/**
+ * 是否是邮箱
+ */
 fun CharSequence?.isEmail(): Boolean {
     fun isMatch(regex: String?, input: CharSequence?): Boolean {
         return input != null && input.isNotEmpty() && Pattern.matches(regex, input)
@@ -31,4 +36,73 @@ fun String.fromHtml(): Spanned? {
         Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY)
         else -> Html.fromHtml(this)
     }
-}
+}
+
+/**
+ * json 转bean对象
+ * "xxx".jsonToBean<Bean>() : Bean
+ */
+inline fun <reified T> String.jsonToBean(): T? = GsonUtil.jsonToBean(this, T::class.java)
+
+/**
+ * bean类转json
+ * bean.toJson() : String
+ */
+fun Any.toJson(): String? = GsonUtil.objectToJson(this)
+
+/**
+ * json 转list
+ * "xxx".jsonToList<Bean>() : List<Bean>
+ */
+inline fun <reified T> String.jsonToList(): List<T> {
+    return GsonUtil.jsonToList(jsonStr = this, T::class.java)
+}
+
+/**
+ * json 转map
+ * "xxx".jsonToMap<String, Any>() : Map<String, Any>
+ */
+inline fun <reified K, reified V> String.jsonToMap(): Map<K, V> = GsonUtil.jsonToMap(this)
+
+
+/**
+ * 获取json中 对应key的值
+ */
+fun <T : Any> String.getJsonValue(key: String): T? = GsonUtil.getJsonValue(this, key)
+
+
+/** -------- 序列化相关扩展 ---------**/
+/**
+ * 集合序列化
+ * @return 序列化后的字符串
+ */
+inline fun <reified E> List<E>.serializable(): String = SerializableUtil.listToString(this)
+
+/**
+ * map 序列化
+ */
+fun Map<Any, Any>.serializable(): String = SerializableUtil.mapToString(this)
+
+/**
+ * 序列化字符串转map
+ */
+fun String.serializableToMap(): Map<*, *>? = SerializableUtil.strToMap(this)
+
+/**
+ * 已实现序列化的Bean类进行序列化
+ * @return 序列化后的字符串
+ */
+fun Any.objSerializable(): String = SerializableUtil.objToStr(this)
+
+/**
+ * 序列化字符串转bean
+ */
+fun <E> String.serializableToBean(): E? {
+    return try {
+        SerializableUtil.strToObj<E>(this)
+    } catch (e: Exception) {
+        null
+    }
+}
+
+

+ 1 - 1
lib_common/src/main/java/com/kdanmobile/android/common/utils/file/CloseUtils.kt

@@ -24,7 +24,7 @@ object CloseUtils {
             for (closeable in closeables) {
                 closeable?.close()
             }
-        } catch (e: IOException) {
+        } catch (e: Exception) {
             e.printStackTrace()
         }
     }

+ 40 - 24
lib_common/src/main/java/com/kdanmobile/android/common/utils/net/NetUtil.kt

@@ -3,8 +3,11 @@ package com.kdanmobile.android.common.utils.net
 import android.content.Context
 import android.location.LocationManager
 import android.net.ConnectivityManager
+import android.net.NetworkCapabilities
 import android.net.NetworkInfo
+import android.os.Build
 import android.telephony.TelephonyManager
+import kotlin.reflect.typeOf
 
 /**
  *    @author : hubowen
@@ -56,7 +59,7 @@ class NetUtil {
                         }
                     } else {
                         val subType = info.subtype
-                        when{
+                        when {
                             isMobile2G(subType) -> NETWORK_TYPE_2G
                             isMobile3G(subType) -> NETWORK_TYPE_3G
                             isMobile4G(subType) -> NETWORK_TYPE_4G
@@ -153,6 +156,20 @@ class NetUtil {
             }
         }
 
+        /**
+         * @方法说明:判断是否是手机网络
+         * @方法名称:is3GNet
+         * @param context
+         * @return 返回值:boolean
+         */
+        fun is3GNet(context: Context): Boolean {
+            val connectivityManager = context.applicationContext
+                .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+            val activeNetInfo = connectivityManager.activeNetworkInfo
+            return (activeNetInfo != null
+                    && activeNetInfo.type == ConnectivityManager.TYPE_MOBILE)
+        }
+
         /**
          * @方法说明:判断WIFI网络是否可用
          * @方法名称:isWifiConnected
@@ -266,7 +283,7 @@ class NetUtil {
                 val mNetworkInfo = mConnectivityManager
                     .activeNetworkInfo
                 if (mNetworkInfo != null) {
-                    return mNetworkInfo.isAvailable
+                    return mNetworkInfo.isConnected
                 }
             }
             return false
@@ -281,31 +298,30 @@ class NetUtil {
          */
         fun isNetworkAvailable(context: Context?): Boolean {
             if (context == null) return false
-            val mgr = context.applicationContext
-                .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
-            val info = mgr.allNetworkInfo
-            if (info != null) {
-                for (anInfo in info) {
-                    if (anInfo.state == NetworkInfo.State.CONNECTED) {
-                        return true
-                    }
+            val connectivityManager = context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+            return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+                val networkCapabilities = connectivityManager.activeNetwork ?: return false
+                val actNw = connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
+                when {
+                    actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
+                            actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
+                            actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
+                    else -> false
+                }
+            } else {
+                connectivityManager.run {
+                    activeNetworkInfo?.run {
+                        when (type) {
+                            ConnectivityManager.TYPE_WIFI,
+                            ConnectivityManager.TYPE_MOBILE,
+                            ConnectivityManager.TYPE_ETHERNET -> true
+                            else -> false
+                        }
+                    } ?: false
                 }
             }
-            return false
         }
 
-        /**
-         * @方法说明:判断是否是手机网络
-         * @方法名称:is3GNet
-         * @param context
-         * @return 返回值:boolean
-         */
-        fun is3GNet(context: Context): Boolean {
-            val connectivityManager = context.applicationContext
-                .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
-            val activeNetInfo = connectivityManager.activeNetworkInfo
-            return (activeNetInfo != null
-                    && activeNetInfo.type == ConnectivityManager.TYPE_MOBILE)
-        }
+
     }
 }

+ 151 - 0
lib_common/src/main/java/com/kdanmobile/android/common/utils/string/GsonUtil.kt

@@ -0,0 +1,151 @@
+package com.kdanmobile.android.common.utils.string
+
+import android.annotation.SuppressLint
+import android.provider.ContactsContract
+import com.google.gson.*
+import com.google.gson.internal.LinkedTreeMap
+import com.google.gson.reflect.TypeToken
+import java.lang.reflect.Type
+import java.text.ParseException
+import java.text.SimpleDateFormat
+import java.util.*
+import java.util.concurrent.locks.Lock
+
+/**
+ *    @author : hubowen
+ *    @e-mail : hubowen@kdanmobile.com
+ *    @date   : 2020/10/26  4:41 PM
+ *    @description:
+ */
+object GsonUtil {
+
+    private var gson: Gson? = null
+
+    init {
+        if (gson == null) {
+            /*gson = new Gson();*/
+            gson = GsonBuilder().setExclusionStrategies(ParseExclusion()).create()
+        }
+    }
+
+    fun objectToJson(ts: Any?): String? {
+        if (gson == null) return null
+        return gson?.toJson(ts)
+    }
+
+
+    fun objectToJson(ts: Any?, type: Type?): String? {
+        if (gson == null) return null
+        return gson?.toJson(ts, type)
+    }
+
+    @SuppressLint("SimpleDateFormat")
+    fun objectToJsonDateSerializer(ts: Any?, dateFormat: String): String? {
+        var jsonStr: String? = null
+        gson = GsonBuilder()
+            .registerTypeHierarchyAdapter(Date::class.java, JsonSerializer<Date> { src, _, _ ->
+                val format = SimpleDateFormat(dateFormat)
+                JsonPrimitive(format.format(src))
+            }).setDateFormat(dateFormat).create()
+        if (gson != null) jsonStr = gson?.toJson(ts)
+        return jsonStr
+    }
+
+    fun <T> jsonToList(jsonStr: String?, clz : Class<T>): List<T> {
+        return try {
+            if (gson != null) {
+                val list = mutableListOf<T>()
+                val array = JsonParser.parseString(jsonStr).asJsonArray
+                for (jsonElement in array) {
+                    list.add(gson!!.fromJson(jsonElement, clz))
+                }
+                list
+            }else{
+                emptyList()
+            }
+        }catch (e : Exception){
+            emptyList()
+        }
+    }
+
+
+    fun <K, V> jsonToMap(jsonStr: String?): Map<K, V> {
+        return try {
+            if (gson != null) {
+                val type = object : TypeToken<Map<K, V>>() {}.type
+                gson!!.fromJson(jsonStr, type)
+            } else {
+                emptyMap<K, V>()
+            }
+        }catch (e : Exception){
+            emptyMap<K,V>()
+        }
+    }
+
+
+    fun <T> jsonToBean(jsonStr: String?, cl: Class<T>): T? {
+        try {
+            if (gson != null) {
+                return gson!!.fromJson(jsonStr, cl)
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return null
+    }
+
+    fun <T> jsonToBeanDateSerializer(jsonStr: String?, cl: Class<T>, pattern: String): T? {
+        var obj: T? = null
+        gson = GsonBuilder()
+            .registerTypeAdapter(Date::class.java, JsonDeserializer { json, _, _ ->
+                val format = SimpleDateFormat(pattern)
+                val dateStr = json.asString
+                try {
+                    return@JsonDeserializer format.parse(dateStr)
+                } catch (e: ParseException) {
+                    e.printStackTrace()
+                }
+                null
+            }).setDateFormat(pattern).create()
+        if (gson != null) {
+            obj = gson!!.fromJson(jsonStr, cl)
+        }
+        return obj
+    }
+
+
+    @Synchronized
+    fun getObjectJson(map: LinkedTreeMap<*, *>, key: String?): String {
+        val value = map[key]
+        return gson?.toJsonTree(value)?.asJsonObject.toString()
+    }
+
+    @Synchronized
+    fun <T> getObjectJson(map: LinkedTreeMap<*, *>, key: String?, cls: Class<T>): T? {
+        val value = map[key]
+        val json = gson?.toJsonTree(value)?.asJsonObject.toString()
+        return jsonToBean(json, cls)
+    }
+
+
+    fun <T: Any> getJsonValue(jsonStr: String?, key: String?): T? {
+        var rulesObj: T? = null
+        val rulesMap = jsonToMap<String, T>(jsonStr)
+        if (rulesMap.isNotEmpty()) {
+            rulesObj = rulesMap[key]
+        }
+        return rulesObj
+    }
+
+    private class ParseExclusion : ExclusionStrategy {
+        override fun shouldSkipClass(arg0: Class<*>?): Boolean {
+            return false
+        }
+
+        override fun shouldSkipField(f: FieldAttributes): Boolean {
+            return f.declaredClass == Lock::class.java
+        }
+    }
+
+
+}

+ 184 - 0
lib_common/src/main/java/com/kdanmobile/android/common/utils/string/SerializableUtil.kt

@@ -0,0 +1,184 @@
+package com.kdanmobile.android.common.utils.string
+
+import android.util.Base64
+import com.kdanmobile.android.common.utils.file.CloseUtils
+import java.io.*
+import java.util.*
+import kotlin.collections.AbstractMap
+
+/**
+ *    @author : hubowen
+ *    @e-mail : hubowen@kdanmobile.com
+ *    @date   : 2020/10/19  1:56 PM
+ *    @description:
+ */
+
+object SerializableUtil {
+
+    /**
+     * @param list
+     * @return
+     * @throws IOException
+     * @方法说明:将集合转换成String类型
+     * @方法名称:listToString
+     * @返回值:String
+     */
+    fun <E> listToString(list: List<E>?): String {
+        var baos: ByteArrayOutputStream? = null
+        var oos: ObjectOutputStream? = null
+        var listString = ""
+        try {
+            // 实例化一个ByteArrayOutputStream对象,用来装载压缩后的字节文件
+            baos = ByteArrayOutputStream()
+            // 然后将得到的字符数据封装到ObjectOutputStream(baos)
+            oos = ObjectOutputStream(baos)
+            // writeObject 方法负责写入特定类的对象的状态,以便相应的readObject可以还原他
+            oos.writeObject(list)
+            // 最后,用Base64.encode将字节文件转换成Base64编码,并以String形式保存
+            listString = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT)
+        } catch (e: Exception) {
+            e.printStackTrace()
+        } finally {
+            CloseUtils.closeIO(oos, baos)
+        }
+        return listString.trim { it <= ' ' }
+    }
+
+    /**
+     * @return
+     * @throws IOException
+     * @方法说明:将数组转换成String类型
+     * @方法名称:listToString
+     * @返回值:String
+     */
+    fun mapToString(map: Map<Any, Any>?): String {
+        var baos: ByteArrayOutputStream? = null
+        var oos: ObjectOutputStream? = null
+        var listString = ""
+        try {
+            // 实例化一个ByteArrayOutputStream对象,用来装载压缩后的字节文件
+            baos = ByteArrayOutputStream()
+            // 然后将得到的字符数据封装到ObjectOutputStream(baos)
+            oos = ObjectOutputStream(baos)
+            // writeObject 方法负责写入特定类的对象的状态,以便相应的readObject可以还原他
+            oos.writeObject(map)
+            // 最后,用Base64.encode将字节文件转换成Base64编码,并以String形式保存
+            listString = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT)
+        } catch (e: Exception) {
+            e.printStackTrace()
+        } finally {
+            CloseUtils.closeIO(oos, baos)
+        }
+        return listString.trim { it <= ' ' }
+    }
+
+    /**
+     * @param obj
+     * @return
+     * @throws IOException
+     * @方法说明:将对象转换成String类型
+     * @方法名称:objToStr
+     * @返回值:String
+     */
+    @Deprecated("")
+    fun objToStr(obj: Any?): String {
+        if (obj == null) {
+            return ""
+        }
+        var baos: ByteArrayOutputStream? = null
+        var oos: ObjectOutputStream? = null
+        var listString = ""
+        try {
+            // 实例化一个ByteArrayOutputStream对象,用来装载压缩后的字节文件
+            baos = ByteArrayOutputStream()
+            // 然后将得到的字符数据装载到ObjectOutputStream
+            oos = ObjectOutputStream(baos)
+            // writeObject 方法负责写入特定类的对象的状态,以便相应的readObject可以还原它
+            oos.writeObject(obj)
+            // 最后,用Base64.encode将字节文件转换成Base64编码,并以String形式保存
+            listString = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT)
+        } catch (e: Exception) {
+            e.printStackTrace()
+        } finally {
+            CloseUtils.closeIO(oos, baos)
+        }
+        return listString.trim { it <= ' ' }
+    }
+
+    /**
+     * @param str
+     * @return
+     * @throws StreamCorruptedException
+     * @throws IOException
+     * @方法说明:将String转换成Obj
+     * @方法名称:strToObj
+     * @返回值:Object
+     */
+    @Deprecated("")
+    @Throws(IOException::class)
+    fun <T> strToObj(str: String?): T? {
+        var ois: ObjectInputStream? = null
+        var bais: ByteArrayInputStream? = null
+        try {
+            val mByte = Base64.decode(str, Base64.DEFAULT)
+            bais = ByteArrayInputStream(mByte)
+            ois = ObjectInputStream(bais)
+            return ois.readObject() as? T
+        } catch (e: Exception) {
+            e.printStackTrace()
+        } finally {
+            CloseUtils.closeIO(ois, bais)
+        }
+        return null
+    }
+
+    /**
+     * @param str
+     * @return
+     * @throws StreamCorruptedException
+     * @throws IOException
+     * @方法说明:将String转换成List<E>
+     * @方法名称:strToList
+     * @返回值:List<E>
+    </E></E> */
+    @Throws(IOException::class)
+    fun <E> strToList(str: String?): ArrayList<E>? {
+        val mByte = Base64.decode(str, Base64.DEFAULT)
+        var bais: ByteArrayInputStream? = ByteArrayInputStream(mByte)
+        var ois: ObjectInputStream? = null
+        var stringList: ArrayList<E>? = null
+        try {
+            ois = ObjectInputStream(bais)
+            stringList = ois.readObject() as ArrayList<E>
+        } catch (ignored: Exception) {
+        } finally {
+            CloseUtils.closeIO(ois, bais)
+        }
+        return stringList
+    }
+
+    /**
+     * @param str
+     * @return
+     * @throws StreamCorruptedException
+     * @throws IOException
+     * @方法说明:将String转换成List<E>
+     * @方法名称:strToList
+     * @返回值:List<E>
+    </E></E> */
+    @Throws(IOException::class)
+    fun strToMap(str: String?): Map<*, *>? {
+        val mByte = Base64.decode(str, Base64.DEFAULT)
+        var bais: ByteArrayInputStream? = ByteArrayInputStream(mByte)
+        var ois: ObjectInputStream? = null
+        var stringList: Map<*, *>? = null
+        try {
+            ois = ObjectInputStream(bais)
+            stringList = ois.readObject() as Map<*, *>
+        } catch (ignored: Exception) {
+        } finally {
+            CloseUtils.closeIO(ois, bais)
+        }
+        return stringList
+    }
+}

+ 255 - 0
lib_common/src/main/java/com/kdanmobile/android/common/utils/string/SharedPreferencesSave.kt

@@ -0,0 +1,255 @@
+package com.kdanmobile.android.common.utils.string
+
+import android.content.Context
+import com.google.gson.ExclusionStrategy
+import com.google.gson.FieldAttributes
+import com.google.gson.Gson
+import com.google.gson.GsonBuilder
+import com.kdanmobile.android.common.extension.*
+import java.io.IOException
+import java.io.StreamCorruptedException
+import java.util.concurrent.locks.Lock
+
+
+/**
+ *    @author : hubowen
+ *    @e-mail : hubowen@kdanmobile.com
+ *    @date   : 2020/10/19  1:53 PM
+ *    @description:Sp数据保存相关
+ */
+class SharedPreferencesSave {
+
+    companion object {
+
+        const val DEFAULT_SP_NAME = "app.pref"
+
+        val instance by lazy {
+            SharedPreferencesSave()
+        }
+
+    }
+
+    /**
+     * @param context
+     * @param spName
+     * @param key
+     * @param ob
+     * @方法说明:保存对象
+     * @方法名称:savaObject
+     * @返回void
+     */
+    fun saveObject(context: Context, spName: String = DEFAULT_SP_NAME, key: String, ob: Any?) {
+        if (ob == null) {
+            return
+        }
+        val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+        preferences.edit().putString(key, ob.objSerializable()).commit()
+    }
+
+
+    /**
+     * @param context
+     * @param spName
+     * @param key
+     * @return
+     * @方法说明:获取存储的对象
+     * @方法名称:getObject
+     * @返回值:Object
+     */
+    fun <T> getObject(context: Context, spName: String = DEFAULT_SP_NAME, key: String): T? {
+
+        return try {
+            val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+            val productBase64 = preferences.getString(key, "")
+            productBase64?.serializableToBean<T>()
+        } catch (e1: Exception) {
+            e1.printStackTrace()
+            null
+        }
+    }
+
+    /**
+     * 移除对应的key
+     */
+    fun removeKey(context: Context, spName: String = DEFAULT_SP_NAME, key: String) {
+        val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+        preferences.edit().remove(key)
+    }
+
+    /**
+     * @param context
+     * @param spName
+     * @param key
+     * @param value
+     * @方法说明:存储int数据
+     * @方法名称:savaIntValue
+     * @返回void
+     */
+    fun saveIntValue(context: Context, spName: String = DEFAULT_SP_NAME, key: String, value: Int) {
+        val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+        preferences.edit().putInt(key, value).commit()
+    }
+
+
+    /**
+     * @param context
+     * @param spName
+     * @param key
+     * @param defaultValue
+     * @return
+     * @方法说明:获取int数据
+     * @方法名称:getIntValue
+     * @返回int
+     */
+    fun getIntValue(context: Context, spName: String = DEFAULT_SP_NAME, key: String, defaultValue: Int = 0): Int {
+        val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+        return preferences.getInt(key, defaultValue)
+    }
+
+    /**
+     * @param context
+     * @param spName
+     * @param key
+     * @param value
+     * @方法说明:存储float数据
+     * @方法名称:savaFloatValue
+     * @返回void
+     */
+    fun saveFloatValue(context: Context, spName: String = DEFAULT_SP_NAME, key: String?, value: Float) {
+        val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+        preferences.edit().putFloat(key, value).commit()
+    }
+
+    /**
+     * @param context
+     * @param spName
+     * @param key
+     * @return
+     * @方法说明:获取float数据
+     * @方法名称:getFloatValue
+     * @返回float
+     */
+    fun getFloatValue(context: Context, spName: String = DEFAULT_SP_NAME, key: String?, defaultValue: Float = 0F): Float {
+        val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+        return preferences.getFloat(key, defaultValue)
+    }
+
+    /**
+     * @param context
+     * @param spName
+     * @param key
+     * @param value
+     * @方法说明:存储boolean数据
+     * @方法名称:savaBooleanValue
+     * @返回void
+     */
+    fun saveBooleanValue(context: Context, spName: String = DEFAULT_SP_NAME, key: String, value: Boolean) {
+        val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+        preferences.edit().putBoolean(key, value).commit()
+    }
+
+
+
+    /**
+     * @param context
+     * @param spName
+     * @param key
+     * @param defaultValue 默认值
+     * @return
+     * @方法说明:获取boolean数据
+     * @方法名称:getBooleanValue
+     * @返回boolean
+     */
+    fun getBooleanValue(context: Context, spName: String = DEFAULT_SP_NAME, key: String, defaultValue: Boolean = false): Boolean {
+        val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+        return preferences.getBoolean(key, defaultValue)
+    }
+
+    /**
+     * @param context
+     * @param spName
+     * @param key
+     * @param value
+     * @方法说明:存储long数据
+     * @方法名称:savaLongValue
+     * @返回void
+     */
+    fun saveLongValue(context: Context, spName: String = DEFAULT_SP_NAME, key: String, value: Long) {
+        val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+        preferences.edit().putLong(key, value).commit()
+    }
+
+    /**
+     * @param context
+     * @param spName
+     * @param key
+     * @return
+     * @方法说明:获取long数据
+     * @方法名称:getLongValue
+     * @返回long
+     */
+    fun getLongValue(context: Context, spName: String = DEFAULT_SP_NAME, key: String, defaultValue : Long = 0L) : Long {
+        val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+        return preferences.getLong(key, defaultValue)
+    }
+
+    /**
+     * @param context
+     * @param spName
+     * @param key
+     * @param value
+     * @方法说明:存储String数据
+     * @方法名称:savaStringValue
+     * @返回void
+     */
+    fun saveStringValue(context: Context, spName: String = DEFAULT_SP_NAME, key: String, value: String?) {
+        val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+        preferences.edit().putString(key, value).commit()
+    }
+
+    /**
+     * @param context
+     * @param spName
+     * @param key
+     * @return
+     * @方法说明:获取String数据
+     * @方法名称:getStringValue
+     * @返回String
+     */
+    fun getStringValue(context: Context, spName: String = DEFAULT_SP_NAME, key: String?, defaultValue: String = ""): String {
+        val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+        return preferences.getString(key, defaultValue)?:defaultValue
+    }
+
+
+    fun saveMap(context: Context, spName: String = DEFAULT_SP_NAME, key: String, map: Map<*, *>?): Boolean {
+        if (map == null) {
+            return false
+        }
+        val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+        return preferences.edit().putString(key, map.toJson()).commit()
+    }
+
+
+    inline fun <reified K, reified V> getMap(context: Context, spName: String = DEFAULT_SP_NAME, key: String?): Map<K, V> {
+        val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+        val mapStr = preferences.getString(key, "")
+        return mapStr?.jsonToMap<K,V>()?: emptyMap()
+    }
+
+
+    fun <E> saveList(context: Context, spName: String = DEFAULT_SP_NAME, key: String, list: List<E>?): Boolean {
+        if (list.isNullOrEmpty()) {
+            return false
+        }
+        val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+        return preferences.edit().putString(key, list.toJson()).commit()
+    }
+
+
+    inline fun <reified E> getList(context: Context, spName: String = DEFAULT_SP_NAME, key: String): List<E> {
+        val preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE)
+        val productBase64 = preferences.getString(key, "")
+        return productBase64?.jsonToList<E>()?: emptyList()
+    }
+}