使用 Room 将数据保存到本地存储

Save data to local storage using Room

如果问题看起来难以理解,我提前道歉,因为 android 开发和 kotlin 不是我的主要堆栈。我会尽量用通俗易懂的语言来解释。

我有一个 class 负责拦截来自 HTTP 请求的数据。此实现反映了以下代码

    class PocketScoutInterceptor() : Interceptor {


    fun buildPacket(timestamp: Long, duration: Double, request: Request, response: Response) {
        val reqBody = request.body
        val respBody = response.body?.string()

        val packet = Packet(
            id = 0,
            userId = PocketScoutConfig.userId,
            deviceId = PocketScoutConfig.deviceId,
            sessionId = PocketScoutConfig.sessionId,
            timestamp = timestamp,
            duration = duration.roundToInt(),
            protocol = "http",
            request = room.entities.Request(
                request_method = request.method,
                request_url = request.url.toUrl().toString(),
                request_headers = request.headers.toMultimap() as Mapping,
                request_body = (reqBody?.toString() ?: ""),
                request_size = (reqBody?.toString()?.length ?: 0),
            ),
            room.entities.Response(
                response_code = response.code,
                response_headers = response.headers.toMultimap() as Mapping,
                response_body = (respBody ?: ""),
                response_size = (respBody?.length ?: 0),
            )
        )
    }
}

此外,我需要将此数据保存在本地数据库中,我选择了房间。

接下来我创建了一个数据库class

    @TypeConverters(value = [RoomTypeConverters::class])
@Database(
    version = 1,
    entities = [Packet::class],
    exportSchema = false
)
abstract class NetworkDatabase : RoomDatabase() {
    abstract fun packetDao(): PacketDao
}

我只需要学习如何在本地存储中保存数据。我看过几个关于这个主题的视频,也多次阅读文档,但就我的例子而言,我找不到答案。也许你能帮帮我

1). 您需要通过 Room databaseBuilder function/method 建立数据库。对注释为 class 的 @Database 的以下更改将执行此操作并且 return 一个单例:-

@TypeConverters(value = [RoomTypeConverters::class])
@Database(entities = [Packet::class], version = 1, exportSchema = false)
abstract class NetworkDatabase: RoomDatabase() {
    abstract fun packetDao(): PacketDao

    companion object {
        @Volatile
        private var instance: NetworkDatabase? = null;
        fun getInstance(context: Context): NetworkDatabase {
            if (instance == null) {
                instance = Room.databaseBuilder(context,NetworkDatabase::class.java,"the_database.db")
                    .allowMainThreadQueries() /* for brevity/convenience but shouldn't really run stuff on the main thread */
                    .build()
            }
            return instance as NetworkDatabase
        }
    }
}
  • 请注意,理想情况下您将在主线程之外访问数据库。然而,上面允许通过主线程访问数据库,因此更容易演示。

2). 下一阶段是实际 使用上面的 ,例如考虑以下 activity 代码(工作示例):-

class MainActivity : AppCompatActivity() {
    lateinit var db: NetworkDatabase
    lateinit var dao: PacketDao
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        /* Get an instance of NetworkDatabase  and the packetDao */
        db = NetworkDatabase.getInstance(this)
        dao = db.packetDao()

        /* add some data (1 row)*/
        val m1 = Mapping(header = mapOf())
        dao.add(
            Packet(
                id = 10,
                deviceId =
                "device10",
                sessionId = "session100",
                timestamp = System.currentTimeMillis(),
                protocol = "HTML",
                request = Request(requestMethod = "the method", requestUrl = "blah", requestHeaders = m1,
                    requestBody = "ReqBody", requestSize = 10),
                userId = "userxxx",
                duration = 200,
                response = Response(100,m1,"RspBody",210)
        )
        )
        /* Extract all rows and write to the log */
        for(p in dao.getAll()) {
            Log.d("DBINFO","Packet ID is ${p.id} DeviceId is ${p.deviceId} Duration is ${p.duration} ....")
        }
    }
}

以上,当运行(第一次)导致日志包含:-

D/DBINFO: Packet ID is 10 DeviceId is device10 Duration is 200 ....

显然你会通过你的拦截器构建数据包