Kotlin 本地化存储 3 种常用方案

xzbxzb 安卓 2025-12-29 32 0
适配 Android 开发场景,提供可直接复用的 Kotlin 实现,兼顾简洁性和实用性,优先覆盖高频使用场景。

一、 轻量键值对存储(SharedPreferences)

最常用的本地存储方案,适合存少量简单数据(如用户配置、登录状态),Kotlin 可通过扩展函数简化调用,无需重复写模板代码。

1. 核心工具类(可直接复用)

import android.content.Contextimport android.content.SharedPreferences/**
 * SharedPreferences 本地化存储工具类
 */object SpUtil {
    // 存储文件名
    private const val SP_NAME = "AppLocalStorage"
    private lateinit var sp: SharedPreferences    // 初始化(建议在Application中调用)
    fun init(context: Context) {
        sp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE)
    }

    // 存值 通用方法
    fun put(key: String, value: Any) {
        val editor = sp.edit()
        when (value) {
            is String -> editor.putString(key, value)
            is Int -> editor.putInt(key, value)
            is Boolean -> editor.putBoolean(key, value)
            is Float -> editor.putFloat(key, value)
            is Long -> editor.putLong(key, value)
            else -> throw IllegalArgumentException("不支持该数据类型存储")
        }
        editor.apply() // 异步提交(推荐),同步用 commit()
    }

    // 取值 带默认值,避免空指针
    fun getString(key: String, defValue: String = "") = sp.getString(key, defValue) ?: defValue    fun getInt(key: String, defValue: Int = 0) = sp.getInt(key, defValue)
    fun getBoolean(key: String, defValue: Boolean = false) = sp.getBoolean(key, defValue)
    fun getFloat(key: String, defValue: Float = 0f) = sp.getFloat(key, defValue)
    fun getLong(key: String, defValue: Long = 0L) = sp.getLong(key, defValue)

    // 删除单个key
    fun remove(key: String) = sp.edit().remove(key).apply()
    // 清空所有数据
    fun clear() = sp.edit().clear().apply()}

2. 使用步骤

  1. 在 Application 中初始化(全局只执行一次)

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        SpUtil.init(this)
    }}
  1. 项目中直接调用(简洁无冗余)

// 存值SpUtil.put("user_name", "张三")SpUtil.put("is_login", true)SpUtil.put("user_age", 28)// 取值val userName = SpUtil.getString("user_name")val isLogin = SpUtil.getBoolean("is_login")val userAge = SpUtil.getInt("user_age")

二、 本地文件存储(File)

适合存大量文本数据(如日志文件、JSON 字符串、大段文本),Kotlin 提供了简洁的文件读写扩展函数,无需手动处理流关闭。

1. 文本文件读写(核心代码)

import android.content.Contextimport java.io.File/**
 * 本地文件存储工具类
 */object FileUtil {
    // 存储路径:应用私有目录(无需权限),外部存储需申请读写权限
    private fun getFile(context: Context, fileName: String): File {
        return File(context.filesDir, fileName)
    }

    // 写入文本
    fun writeText(context: Context, fileName: String, content: String) {
        getFile(context, fileName).writeText(content, Charsets.UTF_8)
    }

    // 读取文本
    fun readText(context: Context, fileName: String): String {
        val file = getFile(context, fileName)
        return if (file.exists()) file.readText(Charsets.UTF_8) else ""
    }

    // 追加文本(如日志追加)
    fun appendText(context: Context, fileName: String, content: String) {
        getFile(context, fileName).appendText(content + "\n", Charsets.UTF_8)
    }}

2. 使用示例

// 写入文本FileUtil.writeText(this, "user_info.txt", "{\"name\":\"张三\",\"age\":28}")// 读取文本val userInfo = FileUtil.readText(this, "user_info.txt")// 追加日志FileUtil.appendText(this, "app_log.txt", "2025-12-29 10:00: 应用启动成功")

三、 数据库存储(Room)

适合存结构化、大量数据(如本地列表数据、用户明细),Google 官方推荐,基于 SQLite 封装,Kotlin 支持协程、LiveData,无需手动写 SQL 原生语句。

1. 第一步:添加依赖(build.gradle (Module))

dependencies {
    // Room 核心库
    implementation "androidx.room:room-runtime:2.5.0"
    // Kotlin 注解处理器
    kapt "androidx.room:room-compiler:2.5.0"
    // 协程支持(可选,推荐)
    implementation "androidx.room:room-ktx:2.5.0"}

2. 第二步:3 个核心组件实现(实体 + Dao + 数据库)

(1) 实体类(对应数据库表)

import androidx.room.Entityimport androidx.room.PrimaryKey// 出差记录实体(对应表名:business_trip)@Entity(tableName = "business_trip")data class BusinessTripEntity(
    @PrimaryKey(autoGenerate = true) val id: Int = 0, // 自增主键
    val tripNo: String, // 出差单号
    val tripPerson: String, // 出差人
    val startDate: String, // 出差开始时间
    val endDate: String, // 出差结束时间
    val destination: String // 出差目的地)

(2) Dao 接口(数据操作接口,无需实现)

import androidx.room.Daoimport androidx.room.Deleteimport androidx.room.Insertimport androidx.room.Queryimport kotlinx.coroutines.flow.Flow@Daointerface BusinessTripDao {
    // 插入数据(可批量)
    @Insert
    suspend fun insertTrip(vararg trip: BusinessTripEntity)

    // 删除数据
    @Delete
    suspend fun deleteTrip(trip: BusinessTripEntity)

    // 查询所有出差记录(返回Flow,数据变化自动回调)
    @Query("SELECT * FROM business_trip")
    fun getAllTrips(): Flow<List<BusinessTripEntity>>

    // 按出差人查询
    @Query("SELECT * FROM business_trip WHERE tripPerson = :person")
    suspend fun getTripByPerson(person: String): List<BusinessTripEntity>}

(3) 数据库单例类(全局唯一)

import androidx.room.Databaseimport androidx.room.Roomimport androidx.room.RoomDatabaseimport android.content.Context// 数据库版本号,升级时需修改@Database(entities = [BusinessTripEntity::class], version = 1, exportSchema = false)abstract class AppDatabase : RoomDatabase() {
    // 暴露Dao接口
    abstract fun businessTripDao(): BusinessTripDao    // 单例模式
    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null

        fun getInstance(context: Context): AppDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java,
                    "app_local_db" // 数据库文件名
                ).build()
                INSTANCE = instance
                instance            }
        }
    }}

3. 使用示例(协程中调用,避免主线程阻塞)

import kotlinx.coroutines.Dispatchersimport kotlinx.coroutines.GlobalScopeimport kotlinx.coroutines.launchimport kotlinx.coroutines.flow.collect// 1. 插入出差记录GlobalScope.launch(Dispatchers.IO) {
    val trip = BusinessTripEntity(
        tripNo = "TRIP20251229001",
        tripPerson = "张三",
        startDate = "2025-12-29",
        endDate = "2025-01-05",
        destination = "上海"
    )
    AppDatabase.getInstance(this@MainActivity).businessTripDao().insertTrip(trip)}// 2. 查询所有记录并监听变化GlobalScope.launch(Dispatchers.Main) {
    AppDatabase.getInstance(this@MainActivity).businessTripDao().getAllTrips()
        .collect { tripList ->
            // 数据变化时回调,直接更新UI
            Log.d("Room数据", "出差记录:$tripList")
        }}

四、 三种方案选型建议

  1. 存简单键值对(配置、状态)→ 用 SharedPreferences(最轻量、开发最快)

  2. 存大段文本 / 文件(日志、JSON)→ 用 File 存储(灵活,适合非结构化数据)

  3. 存结构化大量数据(列表、明细)→ 用 Room(安全、支持协程,适配复杂业务)

 您阅读本篇文章共花了: 

版权声明

本文章如果涉及侵权,请联系我。
部分文章系本人原创未经许可,不得转载。

喜欢0发布评论

评论列表

发表评论

  • 昵称(必填)
  • 邮箱
  • 网址