Skip to content

Commit

Permalink
perf: log lifecycle
Browse files Browse the repository at this point in the history
  • Loading branch information
lisonge committed Oct 20, 2024
1 parent dc54864 commit 724ff77
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 101 deletions.
2 changes: 2 additions & 0 deletions app/src/main/kotlin/li/songe/gkd/debug/FloatingTileService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import kotlinx.coroutines.launch
import li.songe.gkd.util.OnChangeListen
import li.songe.gkd.util.OnDestroy
import li.songe.gkd.util.OnTileClick
import li.songe.gkd.util.useLogLifecycle

class FloatingTileService : TileService(), OnDestroy, OnChangeListen, OnTileClick {
override fun onStartListening() {
Expand Down Expand Up @@ -41,6 +42,7 @@ class FloatingTileService : TileService(), OnDestroy, OnChangeListen, OnTileClic
}

init {
useLogLifecycle()
scope.launch {
combine(
FloatingService.isRunning,
Expand Down
78 changes: 47 additions & 31 deletions app/src/main/kotlin/li/songe/gkd/debug/HttpService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ import li.songe.gkd.notif.notifyService
import li.songe.gkd.permission.notificationState
import li.songe.gkd.service.A11yService
import li.songe.gkd.util.LOCAL_HTTP_SUBS_ID
import li.songe.gkd.util.OnCreate
import li.songe.gkd.util.OnDestroy
import li.songe.gkd.util.SERVER_SCRIPT_URL
import li.songe.gkd.util.getIpAddressInLocalNetwork
import li.songe.gkd.util.keepNullJson
Expand All @@ -54,46 +56,62 @@ import li.songe.gkd.util.storeFlow
import li.songe.gkd.util.subsItemsFlow
import li.songe.gkd.util.toast
import li.songe.gkd.util.updateSubscription
import li.songe.gkd.util.useAliveFlow
import li.songe.gkd.util.useLogLifecycle
import java.io.File


class HttpService : Service() {
private val scope = MainScope()
class HttpService : Service(), OnCreate, OnDestroy {
override fun onBind(intent: Intent?) = null

override fun onCreate() {
super.onCreate()
onCreated()
}

override fun onDestroy() {
super.onDestroy()
onDestroyed()
}

val scope = MainScope().apply { onDestroyed { cancel() } }

private val httpServerPortFlow = storeFlow.map(scope) { s -> s.httpServerPort }

private var server: EmbeddedServer<CIOApplicationEngine, CIOApplicationEngine.Configuration>? =
null

override fun onCreate() {
super.onCreate()
isRunning.value = true
localNetworkIpsFlow.value = getIpAddressInLocalNetwork()
scope.launchTry(Dispatchers.IO) {
httpServerPortFlow.collect { port ->
server?.stop()
server = try {
scope.createServer(port).apply { start() }
} catch (e: Exception) {
LogUtils.d("HTTP服务启动失败", e)
null
}
if (server == null) {
toast("HTTP服务启动失败,您可以尝试切换端口后重新启动")
stopSelf()
return@collect
}
httpNotif.copy(text = "HTTP服务-$port").notifyService(this@HttpService)
init {
useLogLifecycle()
useAliveFlow(isRunning)

onCreated { localNetworkIpsFlow.value = getIpAddressInLocalNetwork() }
onDestroyed { localNetworkIpsFlow.value = emptyList() }

onDestroyed {
if (storeFlow.value.autoClearMemorySubs) {
deleteSubscription(LOCAL_HTTP_SUBS_ID)
}
}
}

override fun onDestroy() {
super.onDestroy()
scope.cancel()
isRunning.value = false
localNetworkIpsFlow.value = emptyList()
if (storeFlow.value.autoClearMemorySubs) {
deleteSubscription(LOCAL_HTTP_SUBS_ID)
onCreated {
scope.launchTry(Dispatchers.IO) {
httpServerPortFlow.collect { port ->
server?.stop()
server = try {
scope.createServer(port).apply { start() }
} catch (e: Exception) {
LogUtils.d("HTTP服务启动失败", e)
null
}
if (server == null) {
toast("HTTP服务启动失败,您可以尝试切换端口后重新启动")
stopSelf()
return@collect
}
httpNotif.copy(text = "HTTP服务-$port").notifyService(this@HttpService)
}
}
}
}

Expand All @@ -109,8 +127,6 @@ class HttpService : Service() {
app.startForegroundService(Intent(app, HttpService::class.java))
}
}

override fun onBind(intent: Intent?) = null
}

@Serializable
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/kotlin/li/songe/gkd/debug/HttpTileService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import kotlinx.coroutines.launch
import li.songe.gkd.util.OnChangeListen
import li.songe.gkd.util.OnDestroy
import li.songe.gkd.util.OnTileClick
import li.songe.gkd.util.useLogLifecycle

class HttpTileService : TileService(), OnDestroy, OnChangeListen, OnTileClick {
override fun onStartListening() {
Expand Down Expand Up @@ -41,6 +42,7 @@ class HttpTileService : TileService(), OnDestroy, OnChangeListen, OnTileClick {
}

init {
useLogLifecycle()
scope.launch {
combine(
HttpService.isRunning,
Expand Down
43 changes: 26 additions & 17 deletions app/src/main/kotlin/li/songe/gkd/debug/ScreenshotService.kt
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
package li.songe.gkd.debug

import android.annotation.SuppressLint
import android.app.Service
import android.content.Context
import android.content.Intent
import com.blankj.utilcode.util.LogUtils
import kotlinx.coroutines.flow.MutableStateFlow
import li.songe.gkd.app
import li.songe.gkd.notif.notifyService
import li.songe.gkd.notif.screenshotNotif
import li.songe.gkd.util.OnCreate
import li.songe.gkd.util.OnDestroy
import li.songe.gkd.util.ScreenshotUtil
import li.songe.gkd.util.componentName
import li.songe.gkd.util.useAliveFlow
import li.songe.gkd.util.useLogLifecycle
import java.lang.ref.WeakReference

class ScreenshotService : Service() {
class ScreenshotService : Service(), OnCreate, OnDestroy {
override fun onBind(intent: Intent?) = null

override fun onCreate() {
super.onCreate()
isRunning.value = true
screenshotNotif.notifyService(this)
onCreated()
}


override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
try {
return super.onStartCommand(intent, flags, startId)
Expand All @@ -35,25 +38,31 @@ class ScreenshotService : Service() {

override fun onDestroy() {
super.onDestroy()
isRunning.value = false
screenshotUtil?.destroy()
screenshotUtil = null
onDestroyed()
}

companion object {
suspend fun screenshot() = screenshotUtil?.execute()
private var screenshotUtil: ScreenshotUtil? = null

@SuppressLint("StaticFieldLeak")
private var screenshotUtil: ScreenshotUtil? = null
init {
useLogLifecycle()
useAliveFlow(isRunning)
onCreated { screenshotNotif.notifyService(this) }
onCreated { instance = WeakReference(this) }
onDestroyed { instance = WeakReference(null) }
onDestroyed { screenshotUtil?.destroy() }
}

fun start(context: Context = app, intent: Intent) {
companion object {
private var instance = WeakReference<ScreenshotService>(null)
val isRunning = MutableStateFlow(false)
suspend fun screenshot() = instance.get()?.screenshotUtil?.execute()
fun start(intent: Intent) {
intent.component = ScreenshotService::class.componentName
context.startForegroundService(intent)
app.startForegroundService(intent)
}

val isRunning = MutableStateFlow(false)
fun stop(context: Context = app) {
context.stopService(Intent(context, ScreenshotService::class.java))
fun stop() {
app.stopService(Intent(app, ScreenshotService::class.java))
}
}
}
18 changes: 10 additions & 8 deletions app/src/main/kotlin/li/songe/gkd/service/A11yService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import li.songe.gkd.util.map
import li.songe.gkd.util.showActionToast
import li.songe.gkd.util.storeFlow
import li.songe.gkd.util.toast
import li.songe.gkd.util.useLogLifecycle
import li.songe.selector.MatchOption
import li.songe.selector.Selector
import java.lang.ref.WeakReference
Expand Down Expand Up @@ -89,6 +90,7 @@ class A11yService : AccessibilityService(), OnCreate, OnA11yConnected, OnA11yEve
val scope = CoroutineScope(Dispatchers.Default).apply { onDestroyed { cancel() } }

init {
useLogLifecycle()
useRunningState()
useAliveView()
useCaptureVolume()
Expand Down Expand Up @@ -485,19 +487,19 @@ private fun A11yService.useRuleChangedLog() {
}

private fun A11yService.useRunningState() {
A11yService.weakInstance = WeakReference(this)
A11yService.isRunning.value = true
if (!storeFlow.value.enableService) {
// https://github.com/gkd-kit/gkd/issues/754
storeFlow.update { it.copy(enableService = true) }
onCreated {
A11yService.weakInstance = WeakReference(this)
A11yService.isRunning.value = true
if (!storeFlow.value.enableService) {
// https://github.com/gkd-kit/gkd/issues/754
storeFlow.update { it.copy(enableService = true) }
}
ManageService.autoStart()
}
onDestroyed {
if (storeFlow.value.enableService) {
storeFlow.update { it.copy(enableService = false) }
}
}
ManageService.autoStart()
onDestroyed {
A11yService.weakInstance = WeakReference(null)
A11yService.isRunning.value = false
}
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/kotlin/li/songe/gkd/service/GkdTileService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import li.songe.gkd.util.componentName
import li.songe.gkd.util.lastRestartA11yServiceTimeFlow
import li.songe.gkd.util.storeFlow
import li.songe.gkd.util.toast
import li.songe.gkd.util.useLogLifecycle

class GkdTileService : TileService(), OnDestroy, OnChangeListen, OnTileClick {
override fun onStartListening() {
Expand Down Expand Up @@ -50,6 +51,7 @@ class GkdTileService : TileService(), OnDestroy, OnChangeListen, OnTileClick {
}

init {
useLogLifecycle()
scope.launch {
combine(
A11yService.isRunning,
Expand Down
69 changes: 41 additions & 28 deletions app/src/main/kotlin/li/songe/gkd/service/ManageService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package li.songe.gkd.service

import android.app.Service
import android.content.Intent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.combine
Expand All @@ -14,45 +14,32 @@ import li.songe.gkd.app
import li.songe.gkd.notif.abNotif
import li.songe.gkd.notif.notifyService
import li.songe.gkd.permission.notificationState
import li.songe.gkd.util.OnCreate
import li.songe.gkd.util.OnDestroy
import li.songe.gkd.util.actionCountFlow
import li.songe.gkd.util.getSubsStatus
import li.songe.gkd.util.ruleSummaryFlow
import li.songe.gkd.util.storeFlow
import li.songe.gkd.util.useAliveFlow

class ManageService : Service() {
class ManageService : Service(), OnCreate, OnDestroy {
override fun onBind(intent: Intent?) = null
val scope = CoroutineScope(Dispatchers.Default)

override fun onCreate() {
super.onCreate()
isRunning.value = true
abNotif.notifyService(this)
scope.launch {
combine(
A11yService.isRunning,
storeFlow,
ruleSummaryFlow,
actionCountFlow,
) { abRunning, store, ruleSummary, count ->
if (!abRunning) return@combine "无障碍未授权"
if (!store.enableMatch) return@combine "暂停规则匹配"
if (store.useCustomNotifText) {
return@combine store.customNotifText
.replace("\${i}", ruleSummary.globalGroups.size.toString())
.replace("\${k}", ruleSummary.appSize.toString())
.replace("\${u}", ruleSummary.appGroupSize.toString())
.replace("\${n}", count.toString())
}
return@combine getSubsStatus(ruleSummary, count)
}.debounce(500L).stateIn(scope, SharingStarted.Eagerly, "").collect { text ->
abNotif.copy(text = text).notifyService(this@ManageService)
}
}
onCreated()
}

override fun onDestroy() {
super.onDestroy()
isRunning.value = false
onDestroyed()
}

val scope = MainScope().apply { onDestroyed { cancel() } }

init {
useAliveFlow(isRunning)
useNotif()
}

companion object {
Expand All @@ -79,3 +66,29 @@ class ManageService : Service() {
}
}

private fun ManageService.useNotif() {
onCreated {
abNotif.notifyService(this)
scope.launch {
combine(
A11yService.isRunning,
storeFlow,
ruleSummaryFlow,
actionCountFlow,
) { abRunning, store, ruleSummary, count ->
if (!abRunning) return@combine "无障碍未授权"
if (!store.enableMatch) return@combine "暂停规则匹配"
if (store.useCustomNotifText) {
return@combine store.customNotifText
.replace("\${i}", ruleSummary.globalGroups.size.toString())
.replace("\${k}", ruleSummary.appSize.toString())
.replace("\${u}", ruleSummary.appGroupSize.toString())
.replace("\${n}", count.toString())
}
return@combine getSubsStatus(ruleSummary, count)
}.debounce(500L).stateIn(scope, SharingStarted.Eagerly, "").collect { text ->
abNotif.copy(text = text).notifyService(this@useNotif)
}
}
}
}
Loading

0 comments on commit 724ff77

Please sign in to comment.