Skip to content

Commit

Permalink
feat: 日志开关 (gkd-kit#176)
Browse files Browse the repository at this point in the history
  • Loading branch information
lisonge committed Oct 17, 2023
1 parent 3efe50d commit fe64a33
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 50 deletions.
11 changes: 5 additions & 6 deletions app/src/main/java/li/songe/gkd/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,18 @@ class App : Application() {
CrashReport.initCrashReport(applicationContext, "d0ce46b353", false)
MMKV.initialize(this)
LogUtils.getConfig().apply {
isLog2FileSwitch = true
setConsoleSwitch(BuildConfig.DEBUG)
saveDays = 7
}
ShizukuProvider.enableMultiProcessSupport(isMainProcess)
ShizukuProvider.requestBinderForNonProviderProcess(this)

if (isMainProcess) {
appScope.launchTry(Dispatchers.IO) {
appScope.launchTry(Dispatchers.IO) {
initStore()
initAppState()
initSubsState()
if (isMainProcess) {
initChannel()
initStore()
initAppState()
initSubsState()
initUpgrade()
clearHttpSubs()
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/li/songe/gkd/data/SubscriptionRaw.kt
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ data class SubscriptionRaw(
}

// 订阅文件状态: 文件不存在, 文件正常, 文件损坏(损坏原因)
fun stringify(source: SubscriptionRaw) = Singleton.omitJson.encodeToString(source)
fun stringify(source: SubscriptionRaw) = Singleton.json.encodeToString(source)

fun parse(source: String, json5: Boolean = true): SubscriptionRaw {
val text = if (json5) Jankson.builder().build().load(source).toJson() else source
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/li/songe/gkd/service/GkdAbService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import android.graphics.Bitmap
import android.os.Build
import android.view.Display
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.NetworkUtils
import com.blankj.utilcode.util.ScreenUtils
Expand Down
19 changes: 9 additions & 10 deletions app/src/main/java/li/songe/gkd/ui/AppItemPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ fun AppItemPage(
},
confirmButton = {
TextButton(onClick = {
val groupAppText = Singleton.omitJson.encodeToString(
val groupAppText = Singleton.json.encodeToString(
appRaw?.copy(
groups = listOf(showGroupItemVal)
)
Expand Down Expand Up @@ -259,14 +259,13 @@ fun AppItemPage(
.clickable {
vm.viewModelScope.launchTry(Dispatchers.IO) {
val subsRaw = subsIdToRawFlow.value[subsItemId] ?: return@launchTry
val newSubsRaw = subsRaw.copy(
apps = subsRaw.apps
.toMutableList()
.apply {
set(indexOfFirst { a -> a.id == appRawVal.id },
appRawVal.copy(groups = appRawVal.groups.filter { g -> g.key != menuGroupRaw.key })
)
})
val newSubsRaw = subsRaw.copy(apps = subsRaw.apps
.toMutableList()
.apply {
set(indexOfFirst { a -> a.id == appRawVal.id },
appRawVal.copy(groups = appRawVal.groups.filter { g -> g.key != menuGroupRaw.key })
)
})
subsItemVal.subsFile.writeText(
Singleton.json.encodeToString(
newSubsRaw
Expand All @@ -288,7 +287,7 @@ fun AppItemPage(

if (editGroupRaw != null && appRawVal != null && subsItemVal != null) {
var source by remember {
mutableStateOf(Singleton.omitJson.encodeToString(editGroupRaw))
mutableStateOf(Singleton.json.encodeToString(editGroupRaw))
}
Dialog(onDismissRequest = { setEditGroupRaw(null) }) {
Column(
Expand Down
22 changes: 22 additions & 0 deletions app/src/main/java/li/songe/gkd/ui/SettingsPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,28 @@ fun SettingsPage() {
}
})
Divider()
TextSwitch(name = "保存日志",
desc = "保存最近7天的日志",
checked = store.log2FileSwitch,
onCheckedChange = {
updateStorage(
storeFlow, store.copy(
log2FileSwitch = it
)
)
if (!it) {
appScope.launchTry(Dispatchers.IO) {
val logFiles = LogUtils.getLogFiles()
if (logFiles.isNotEmpty()) {
logFiles.forEach { f ->
f.delete()
}
ToastUtils.showShort("已删除全部日志")
}
}
}
})
Divider()
SettingItem(title = "分享日志", onClick = {
vm.viewModelScope.launchTry(Dispatchers.IO) {
val logFiles = LogUtils.getLogFiles()
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/li/songe/gkd/ui/SubsPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ fun SubsPage(
val editAppRawVal = editAppRaw
if (editAppRawVal != null && subsItemVal != null && subsRaw != null) {
var source by remember {
mutableStateOf(Singleton.omitJson.encodeToString(editAppRawVal))
mutableStateOf(Singleton.json.encodeToString(editAppRawVal))
}
Dialog(onDismissRequest = { editAppRaw = null }) {
Column(
Expand Down Expand Up @@ -369,7 +369,7 @@ fun SubsPage(
Text(text = "复制", modifier = Modifier
.clickable {
ClipboardUtils.copyText(
Singleton.omitJson.encodeToString(
Singleton.json.encodeToString(
menuAppRawVal
)
)
Expand Down
13 changes: 3 additions & 10 deletions app/src/main/java/li/songe/gkd/util/Singleton.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,20 @@ import io.ktor.client.engine.okhttp.OkHttp
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.http.ContentType
import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json

/**
* 所有单例及其属性必须是不可变属性,以保持多进程下的配置统一性
*/
@OptIn(ExperimentalSerializationApi::class)
object Singleton {

val json by lazy {
Json {
isLenient = true
ignoreUnknownKeys = true
explicitNulls = false
encodeDefaults = true
}
}
val omitJson by lazy {
Json {
isLenient = true
ignoreUnknownKeys = true
encodeDefaults = false
}
}

val client by lazy {
HttpClient(OkHttp) {
Expand Down
47 changes: 26 additions & 21 deletions app/src/main/java/li/songe/gkd/util/Store.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.os.Parcelable
import com.blankj.utilcode.util.LogUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import li.songe.gkd.app
import li.songe.gkd.appScope
import java.util.WeakHashMap
Expand All @@ -35,30 +37,32 @@ private val receiver by lazy {
}
}

private val stateFlowToKey by lazy { WeakHashMap<StateFlow<*>, String>() }
val stateFlowToKey by lazy { WeakHashMap<StateFlow<*>, String>() }

private inline fun <reified T : Parcelable> createStorageFlow(
private inline fun <reified T> createStorageFlow(
key: String,
crossinline init: () -> T,
): StateFlow<T> {
receiver
val stateFlow = MutableStateFlow(kv.decodeParcelable(key, T::class.java) ?: init())
val stateFlow =
MutableStateFlow(kv.getString(key, null)?.let { Singleton.json.decodeFromString<T>(it) }
?: init())
onReceives.add { _, intent ->
val extras = intent?.extras ?: return@add
val type = extras.getString("type") ?: return@add
val itKey = extras.getString("key") ?: return@add
if (type == "update_storage" && itKey == key) {
stateFlow.value = kv.decodeParcelable(key, T::class.java) ?: init()
stateFlow.value =
kv.getString(key, null)?.let { Singleton.json.decodeFromString<T>(it) } ?: init()
}
}
stateFlowToKey[stateFlow] = key
return stateFlow
}


fun <T : Parcelable> updateStorage(stateFlow: StateFlow<T>, newState: T) {
inline fun <reified T> updateStorage(stateFlow: StateFlow<T>, newState: T) {
val key = stateFlowToKey[stateFlow] ?: error("not found stateFlow key")
kv.encode(key, newState)
kv.encode(key, Singleton.json.encodeToString(newState))
app.sendBroadcast(Intent(app.packageName).apply {
`package` = app.packageName
putExtra("type", "update_storage")
Expand All @@ -67,13 +71,7 @@ fun <T : Parcelable> updateStorage(stateFlow: StateFlow<T>, newState: T) {
}


/**
* 属性不可删除,注释弃用即可
* 属性声明顺序不可变动
* 新增属性必须在尾部声明
* 否则导致序列化错误
*/
@Parcelize
@Serializable
data class Store(
val enableService: Boolean = true,
val excludeFromRecents: Boolean = false,
Expand All @@ -87,20 +85,21 @@ data class Store(
val autoClearMemorySubs: Boolean = true,
val hideSnapshotStatusBar: Boolean = false,
val enableShizuku: Boolean = false,
) : Parcelable
val log2FileSwitch: Boolean = true,
)

val storeFlow by lazy {
createStorageFlow("store") { Store() }
createStorageFlow("store-v2") { Store() }
}

@Parcelize
@Serializable
data class RecordStore(
val clickCount: Int = 0,
val snapshotIdMap: Map<Long, Int> = emptyMap(),
) : Parcelable
)

val recordStoreFlow by lazy {
createStorageFlow("record_store") { RecordStore() }
createStorageFlow("record_store-v2") { RecordStore() }
}

val clickCountFlow by lazy {
Expand All @@ -115,7 +114,13 @@ fun increaseClickCount(n: Int = 1) {
}

fun initStore() {
receiver
storeFlow.value
recordStoreFlow.value
appScope.launchTry(Dispatchers.IO) {
storeFlow.map(appScope) { s -> s.log2FileSwitch }.collect {
LogUtils.getConfig().isLog2FileSwitch = it
}
}
}

0 comments on commit fe64a33

Please sign in to comment.