No more main thread SQL

This commit is contained in:
Mygod
2019-01-31 22:11:54 +08:00
parent 08ab6a54ff
commit 4de891b459
7 changed files with 30 additions and 12 deletions

View File

@@ -6,7 +6,7 @@ buildscript {
ext { ext {
kotlinVersion = '1.3.20' kotlinVersion = '1.3.20'
lifecycleVersion = '2.0.0' lifecycleVersion = '2.0.0'
roomVersion = '2.1.0-alpha03' roomVersion = '2.1.0-alpha04'
} }
repositories { repositories {
google() google()

View File

@@ -46,6 +46,7 @@ class App : Application() {
R.array.com_google_android_gms_fonts_certs)).apply { R.array.com_google_android_gms_fonts_certs)).apply {
setEmojiSpanIndicatorEnabled(BuildConfig.DEBUG) setEmojiSpanIndicatorEnabled(BuildConfig.DEBUG)
registerInitCallback(object : EmojiCompat.InitCallback() { registerInitCallback(object : EmojiCompat.InitCallback() {
override fun onInitialized() = DebugHelper.log("EmojiCompat", "Initialized")
override fun onFailed(throwable: Throwable?) = Timber.d(throwable) override fun onFailed(throwable: Throwable?) = Timber.d(throwable)
}) })
}) })

View File

@@ -137,7 +137,9 @@ class ClientsFragment : Fragment(), MainScope by MainScope.Supervisor() {
val wasWorking = TrafficRecorder.isWorking(client.mac) val wasWorking = TrafficRecorder.isWorking(client.mac)
client.obtainRecord().apply { client.obtainRecord().apply {
blocked = !blocked blocked = !blocked
AppDatabase.instance.clientRecordDao.update(this) GlobalScope.launch(Dispatchers.Main, CoroutineStart.UNDISPATCHED) {
AppDatabase.instance.clientRecordDao.update(this@apply)
}
} }
IpNeighbourMonitor.instance?.flush() IpNeighbourMonitor.instance?.flush()
if (!wasWorking && item.itemId == R.id.block) { if (!wasWorking && item.itemId == R.id.block) {

View File

@@ -10,6 +10,10 @@ import be.mygod.vpnhotspot.util.Event2
import be.mygod.vpnhotspot.util.RootSession import be.mygod.vpnhotspot.util.RootSession
import be.mygod.vpnhotspot.util.parseNumericAddress import be.mygod.vpnhotspot.util.parseNumericAddress
import be.mygod.vpnhotspot.widget.SmartSnackbar import be.mygod.vpnhotspot.widget.SmartSnackbar
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import java.net.InetAddress import java.net.InetAddress
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@@ -25,7 +29,9 @@ object TrafficRecorder {
fun register(ip: InetAddress, downstream: String, mac: Long) { fun register(ip: InetAddress, downstream: String, mac: Long) {
val record = TrafficRecord(mac = mac, ip = ip, downstream = downstream) val record = TrafficRecord(mac = mac, ip = ip, downstream = downstream)
AppDatabase.instance.trafficRecordDao.insert(record) GlobalScope.launch(Dispatchers.Main, CoroutineStart.UNDISPATCHED) {
AppDatabase.instance.trafficRecordDao.insert(record)
}
synchronized(this) { synchronized(this) {
DebugHelper.log(TAG, "Registering $ip%$downstream") DebugHelper.log(TAG, "Registering $ip%$downstream")
check(records.put(Pair(ip, downstream), record) == null) check(records.put(Pair(ip, downstream), record) == null)
@@ -117,7 +123,9 @@ object TrafficRecorder {
check(record.sentBytes >= 0) check(record.sentBytes >= 0)
check(record.receivedPackets >= 0) check(record.receivedPackets >= 0)
check(record.receivedBytes >= 0) check(record.receivedBytes >= 0)
AppDatabase.instance.trafficRecordDao.insert(record) GlobalScope.launch(Dispatchers.Main, CoroutineStart.UNDISPATCHED) {
AppDatabase.instance.trafficRecordDao.insert(record)
}
} }
foregroundListeners(records.values, oldRecords) foregroundListeners(records.values, oldRecords)
} }

View File

@@ -19,7 +19,6 @@ abstract class AppDatabase : RoomDatabase() {
.addMigrations( .addMigrations(
Migration2 Migration2
) )
.allowMainThreadQueries()
.build() .build()
} }
} }

View File

@@ -2,6 +2,10 @@ package be.mygod.vpnhotspot.room
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.room.* import androidx.room.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
@Entity @Entity
data class ClientRecord(@PrimaryKey data class ClientRecord(@PrimaryKey
@@ -20,13 +24,17 @@ data class ClientRecord(@PrimaryKey
abstract fun lookupSync(mac: Long): LiveData<ClientRecord> abstract fun lookupSync(mac: Long): LiveData<ClientRecord>
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
protected abstract fun updateInternal(value: ClientRecord): Long protected abstract suspend fun updateInternal(value: ClientRecord): Long
fun update(value: ClientRecord) = check(updateInternal(value) == value.mac) suspend fun update(value: ClientRecord) = check(updateInternal(value) == value.mac)
@Transaction @Transaction
open suspend fun upsert(mac: Long, operation: ClientRecord.() -> Unit) = lookupOrDefault(mac).apply { protected open fun upsertSync(mac: Long, operation: ClientRecord.() -> Unit) = runBlocking {
operation() lookupOrDefault(mac).apply {
update(this) operation()
update(this)
}
} }
fun upsert(mac: Long, operation: ClientRecord.() -> Unit) =
GlobalScope.async(Dispatchers.IO) { upsertSync(mac, operation) }
} }
} }

View File

@@ -40,8 +40,8 @@ data class TrafficRecord(
@androidx.room.Dao @androidx.room.Dao
abstract class Dao { abstract class Dao {
@Insert @Insert
protected abstract fun insertInternal(value: TrafficRecord): Long protected abstract suspend fun insertInternal(value: TrafficRecord): Long
fun insert(value: TrafficRecord) { suspend fun insert(value: TrafficRecord) {
check(value.id == null) check(value.id == null)
value.id = insertInternal(value) value.id = insertInternal(value)
} }