使用 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 ....
显然你会通过你的拦截器构建数据包
如果问题看起来难以理解,我提前道歉,因为 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 ....
显然你会通过你的拦截器构建数据包