mirror of
https://github.com/gkd-kit/gkd.git
synced 2024-11-15 19:22:26 +08:00
perf: log lifecycle
This commit is contained in:
parent
dc54864751
commit
724ff77c97
|
@ -10,6 +10,7 @@ import kotlinx.coroutines.launch
|
||||||
import li.songe.gkd.util.OnChangeListen
|
import li.songe.gkd.util.OnChangeListen
|
||||||
import li.songe.gkd.util.OnDestroy
|
import li.songe.gkd.util.OnDestroy
|
||||||
import li.songe.gkd.util.OnTileClick
|
import li.songe.gkd.util.OnTileClick
|
||||||
|
import li.songe.gkd.util.useLogLifecycle
|
||||||
|
|
||||||
class FloatingTileService : TileService(), OnDestroy, OnChangeListen, OnTileClick {
|
class FloatingTileService : TileService(), OnDestroy, OnChangeListen, OnTileClick {
|
||||||
override fun onStartListening() {
|
override fun onStartListening() {
|
||||||
|
@ -41,6 +42,7 @@ class FloatingTileService : TileService(), OnDestroy, OnChangeListen, OnTileClic
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
useLogLifecycle()
|
||||||
scope.launch {
|
scope.launch {
|
||||||
combine(
|
combine(
|
||||||
FloatingService.isRunning,
|
FloatingService.isRunning,
|
||||||
|
|
|
@ -45,6 +45,8 @@ import li.songe.gkd.notif.notifyService
|
||||||
import li.songe.gkd.permission.notificationState
|
import li.songe.gkd.permission.notificationState
|
||||||
import li.songe.gkd.service.A11yService
|
import li.songe.gkd.service.A11yService
|
||||||
import li.songe.gkd.util.LOCAL_HTTP_SUBS_ID
|
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.SERVER_SCRIPT_URL
|
||||||
import li.songe.gkd.util.getIpAddressInLocalNetwork
|
import li.songe.gkd.util.getIpAddressInLocalNetwork
|
||||||
import li.songe.gkd.util.keepNullJson
|
import li.songe.gkd.util.keepNullJson
|
||||||
|
@ -54,46 +56,62 @@ import li.songe.gkd.util.storeFlow
|
||||||
import li.songe.gkd.util.subsItemsFlow
|
import li.songe.gkd.util.subsItemsFlow
|
||||||
import li.songe.gkd.util.toast
|
import li.songe.gkd.util.toast
|
||||||
import li.songe.gkd.util.updateSubscription
|
import li.songe.gkd.util.updateSubscription
|
||||||
|
import li.songe.gkd.util.useAliveFlow
|
||||||
|
import li.songe.gkd.util.useLogLifecycle
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
class HttpService : Service() {
|
class HttpService : Service(), OnCreate, OnDestroy {
|
||||||
private val scope = MainScope()
|
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 val httpServerPortFlow = storeFlow.map(scope) { s -> s.httpServerPort }
|
||||||
|
|
||||||
private var server: EmbeddedServer<CIOApplicationEngine, CIOApplicationEngine.Configuration>? =
|
private var server: EmbeddedServer<CIOApplicationEngine, CIOApplicationEngine.Configuration>? =
|
||||||
null
|
null
|
||||||
|
|
||||||
override fun onCreate() {
|
init {
|
||||||
super.onCreate()
|
useLogLifecycle()
|
||||||
isRunning.value = true
|
useAliveFlow(isRunning)
|
||||||
localNetworkIpsFlow.value = getIpAddressInLocalNetwork()
|
|
||||||
scope.launchTry(Dispatchers.IO) {
|
onCreated { localNetworkIpsFlow.value = getIpAddressInLocalNetwork() }
|
||||||
httpServerPortFlow.collect { port ->
|
onDestroyed { localNetworkIpsFlow.value = emptyList() }
|
||||||
server?.stop()
|
|
||||||
server = try {
|
onDestroyed {
|
||||||
scope.createServer(port).apply { start() }
|
if (storeFlow.value.autoClearMemorySubs) {
|
||||||
} catch (e: Exception) {
|
deleteSubscription(LOCAL_HTTP_SUBS_ID)
|
||||||
LogUtils.d("HTTP服务启动失败", e)
|
|
||||||
null
|
|
||||||
}
|
|
||||||
if (server == null) {
|
|
||||||
toast("HTTP服务启动失败,您可以尝试切换端口后重新启动")
|
|
||||||
stopSelf()
|
|
||||||
return@collect
|
|
||||||
}
|
|
||||||
httpNotif.copy(text = "HTTP服务-$port").notifyService(this@HttpService)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
onCreated {
|
||||||
super.onDestroy()
|
scope.launchTry(Dispatchers.IO) {
|
||||||
scope.cancel()
|
httpServerPortFlow.collect { port ->
|
||||||
isRunning.value = false
|
server?.stop()
|
||||||
localNetworkIpsFlow.value = emptyList()
|
server = try {
|
||||||
if (storeFlow.value.autoClearMemorySubs) {
|
scope.createServer(port).apply { start() }
|
||||||
deleteSubscription(LOCAL_HTTP_SUBS_ID)
|
} catch (e: Exception) {
|
||||||
|
LogUtils.d("HTTP服务启动失败", e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
if (server == null) {
|
||||||
|
toast("HTTP服务启动失败,您可以尝试切换端口后重新启动")
|
||||||
|
stopSelf()
|
||||||
|
return@collect
|
||||||
|
}
|
||||||
|
httpNotif.copy(text = "HTTP服务-$port").notifyService(this@HttpService)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,8 +127,6 @@ class HttpService : Service() {
|
||||||
app.startForegroundService(Intent(app, HttpService::class.java))
|
app.startForegroundService(Intent(app, HttpService::class.java))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBind(intent: Intent?) = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
|
|
@ -10,6 +10,7 @@ import kotlinx.coroutines.launch
|
||||||
import li.songe.gkd.util.OnChangeListen
|
import li.songe.gkd.util.OnChangeListen
|
||||||
import li.songe.gkd.util.OnDestroy
|
import li.songe.gkd.util.OnDestroy
|
||||||
import li.songe.gkd.util.OnTileClick
|
import li.songe.gkd.util.OnTileClick
|
||||||
|
import li.songe.gkd.util.useLogLifecycle
|
||||||
|
|
||||||
class HttpTileService : TileService(), OnDestroy, OnChangeListen, OnTileClick {
|
class HttpTileService : TileService(), OnDestroy, OnChangeListen, OnTileClick {
|
||||||
override fun onStartListening() {
|
override fun onStartListening() {
|
||||||
|
@ -41,6 +42,7 @@ class HttpTileService : TileService(), OnDestroy, OnChangeListen, OnTileClick {
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
useLogLifecycle()
|
||||||
scope.launch {
|
scope.launch {
|
||||||
combine(
|
combine(
|
||||||
HttpService.isRunning,
|
HttpService.isRunning,
|
||||||
|
|
|
@ -1,26 +1,29 @@
|
||||||
package li.songe.gkd.debug
|
package li.songe.gkd.debug
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import com.blankj.utilcode.util.LogUtils
|
import com.blankj.utilcode.util.LogUtils
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import li.songe.gkd.app
|
import li.songe.gkd.app
|
||||||
import li.songe.gkd.notif.notifyService
|
import li.songe.gkd.notif.notifyService
|
||||||
import li.songe.gkd.notif.screenshotNotif
|
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.ScreenshotUtil
|
||||||
import li.songe.gkd.util.componentName
|
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 onBind(intent: Intent?) = null
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
isRunning.value = true
|
onCreated()
|
||||||
screenshotNotif.notifyService(this)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
try {
|
try {
|
||||||
return super.onStartCommand(intent, flags, startId)
|
return super.onStartCommand(intent, flags, startId)
|
||||||
|
@ -35,25 +38,31 @@ class ScreenshotService : Service() {
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
isRunning.value = false
|
onDestroyed()
|
||||||
screenshotUtil?.destroy()
|
}
|
||||||
screenshotUtil = null
|
|
||||||
|
private var screenshotUtil: ScreenshotUtil? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
useLogLifecycle()
|
||||||
|
useAliveFlow(isRunning)
|
||||||
|
onCreated { screenshotNotif.notifyService(this) }
|
||||||
|
onCreated { instance = WeakReference(this) }
|
||||||
|
onDestroyed { instance = WeakReference(null) }
|
||||||
|
onDestroyed { screenshotUtil?.destroy() }
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
suspend fun screenshot() = screenshotUtil?.execute()
|
private var instance = WeakReference<ScreenshotService>(null)
|
||||||
|
val isRunning = MutableStateFlow(false)
|
||||||
@SuppressLint("StaticFieldLeak")
|
suspend fun screenshot() = instance.get()?.screenshotUtil?.execute()
|
||||||
private var screenshotUtil: ScreenshotUtil? = null
|
fun start(intent: Intent) {
|
||||||
|
|
||||||
fun start(context: Context = app, intent: Intent) {
|
|
||||||
intent.component = ScreenshotService::class.componentName
|
intent.component = ScreenshotService::class.componentName
|
||||||
context.startForegroundService(intent)
|
app.startForegroundService(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
val isRunning = MutableStateFlow(false)
|
fun stop() {
|
||||||
fun stop(context: Context = app) {
|
app.stopService(Intent(app, ScreenshotService::class.java))
|
||||||
context.stopService(Intent(context, ScreenshotService::class.java))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -56,6 +56,7 @@ import li.songe.gkd.util.map
|
||||||
import li.songe.gkd.util.showActionToast
|
import li.songe.gkd.util.showActionToast
|
||||||
import li.songe.gkd.util.storeFlow
|
import li.songe.gkd.util.storeFlow
|
||||||
import li.songe.gkd.util.toast
|
import li.songe.gkd.util.toast
|
||||||
|
import li.songe.gkd.util.useLogLifecycle
|
||||||
import li.songe.selector.MatchOption
|
import li.songe.selector.MatchOption
|
||||||
import li.songe.selector.Selector
|
import li.songe.selector.Selector
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
@ -89,6 +90,7 @@ class A11yService : AccessibilityService(), OnCreate, OnA11yConnected, OnA11yEve
|
||||||
val scope = CoroutineScope(Dispatchers.Default).apply { onDestroyed { cancel() } }
|
val scope = CoroutineScope(Dispatchers.Default).apply { onDestroyed { cancel() } }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
useLogLifecycle()
|
||||||
useRunningState()
|
useRunningState()
|
||||||
useAliveView()
|
useAliveView()
|
||||||
useCaptureVolume()
|
useCaptureVolume()
|
||||||
|
@ -485,19 +487,19 @@ private fun A11yService.useRuleChangedLog() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun A11yService.useRunningState() {
|
private fun A11yService.useRunningState() {
|
||||||
A11yService.weakInstance = WeakReference(this)
|
onCreated {
|
||||||
A11yService.isRunning.value = true
|
A11yService.weakInstance = WeakReference(this)
|
||||||
if (!storeFlow.value.enableService) {
|
A11yService.isRunning.value = true
|
||||||
// https://github.com/gkd-kit/gkd/issues/754
|
if (!storeFlow.value.enableService) {
|
||||||
storeFlow.update { it.copy(enableService = true) }
|
// https://github.com/gkd-kit/gkd/issues/754
|
||||||
|
storeFlow.update { it.copy(enableService = true) }
|
||||||
|
}
|
||||||
|
ManageService.autoStart()
|
||||||
}
|
}
|
||||||
onDestroyed {
|
onDestroyed {
|
||||||
if (storeFlow.value.enableService) {
|
if (storeFlow.value.enableService) {
|
||||||
storeFlow.update { it.copy(enableService = false) }
|
storeFlow.update { it.copy(enableService = false) }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ManageService.autoStart()
|
|
||||||
onDestroyed {
|
|
||||||
A11yService.weakInstance = WeakReference(null)
|
A11yService.weakInstance = WeakReference(null)
|
||||||
A11yService.isRunning.value = false
|
A11yService.isRunning.value = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import li.songe.gkd.util.componentName
|
||||||
import li.songe.gkd.util.lastRestartA11yServiceTimeFlow
|
import li.songe.gkd.util.lastRestartA11yServiceTimeFlow
|
||||||
import li.songe.gkd.util.storeFlow
|
import li.songe.gkd.util.storeFlow
|
||||||
import li.songe.gkd.util.toast
|
import li.songe.gkd.util.toast
|
||||||
|
import li.songe.gkd.util.useLogLifecycle
|
||||||
|
|
||||||
class GkdTileService : TileService(), OnDestroy, OnChangeListen, OnTileClick {
|
class GkdTileService : TileService(), OnDestroy, OnChangeListen, OnTileClick {
|
||||||
override fun onStartListening() {
|
override fun onStartListening() {
|
||||||
|
@ -50,6 +51,7 @@ class GkdTileService : TileService(), OnDestroy, OnChangeListen, OnTileClick {
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
useLogLifecycle()
|
||||||
scope.launch {
|
scope.launch {
|
||||||
combine(
|
combine(
|
||||||
A11yService.isRunning,
|
A11yService.isRunning,
|
||||||
|
|
|
@ -2,8 +2,8 @@ package li.songe.gkd.service
|
||||||
|
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.MainScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
|
@ -14,45 +14,32 @@ import li.songe.gkd.app
|
||||||
import li.songe.gkd.notif.abNotif
|
import li.songe.gkd.notif.abNotif
|
||||||
import li.songe.gkd.notif.notifyService
|
import li.songe.gkd.notif.notifyService
|
||||||
import li.songe.gkd.permission.notificationState
|
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.actionCountFlow
|
||||||
import li.songe.gkd.util.getSubsStatus
|
import li.songe.gkd.util.getSubsStatus
|
||||||
import li.songe.gkd.util.ruleSummaryFlow
|
import li.songe.gkd.util.ruleSummaryFlow
|
||||||
import li.songe.gkd.util.storeFlow
|
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
|
override fun onBind(intent: Intent?) = null
|
||||||
val scope = CoroutineScope(Dispatchers.Default)
|
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
isRunning.value = true
|
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@ManageService)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
isRunning.value = false
|
onDestroyed()
|
||||||
|
}
|
||||||
|
|
||||||
|
val scope = MainScope().apply { onDestroyed { cancel() } }
|
||||||
|
|
||||||
|
init {
|
||||||
|
useAliveFlow(isRunning)
|
||||||
|
useNotif()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ package li.songe.gkd.util
|
||||||
|
|
||||||
|
|
||||||
import android.view.accessibility.AccessibilityEvent
|
import android.view.accessibility.AccessibilityEvent
|
||||||
|
import com.blankj.utilcode.util.LogUtils
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import java.util.WeakHashMap
|
import java.util.WeakHashMap
|
||||||
|
|
||||||
private val callbacksMap by lazy { WeakHashMap<Any, HashMap<Int, MutableList<Any>>>() }
|
private val callbacksMap by lazy { WeakHashMap<Any, HashMap<Int, MutableList<Any>>>() }
|
||||||
|
@ -15,13 +17,13 @@ private fun <T> Any.getCallbacks(method: Int): MutableList<T> {
|
||||||
interface CanOnCallback
|
interface CanOnCallback
|
||||||
|
|
||||||
interface OnCreate : CanOnCallback {
|
interface OnCreate : CanOnCallback {
|
||||||
fun onBeforeCreate(f: () -> Unit) {
|
// fun onBeforeCreate(f: () -> Unit) {
|
||||||
getCallbacks<() -> Unit>(1).add(f)
|
// getCallbacks<() -> Unit>(1).add(f)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fun onBeforeCreate() {
|
// fun onBeforeCreate() {
|
||||||
getCallbacks<() -> Unit>(1).forEach { it() }
|
// getCallbacks<() -> Unit>(1).forEach { it() }
|
||||||
}
|
// }
|
||||||
|
|
||||||
fun onCreated(f: () -> Unit) {
|
fun onCreated(f: () -> Unit) {
|
||||||
getCallbacks<() -> Unit>(2).add(f)
|
getCallbacks<() -> Unit>(2).add(f)
|
||||||
|
@ -83,7 +85,7 @@ interface OnChangeListen : CanOnCallback {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OnTileClick {
|
interface OnTileClick : CanOnCallback {
|
||||||
fun onTileClicked(f: () -> Unit) {
|
fun onTileClicked(f: () -> Unit) {
|
||||||
getCallbacks<() -> Unit>(14).add(f)
|
getCallbacks<() -> Unit>(14).add(f)
|
||||||
}
|
}
|
||||||
|
@ -91,4 +93,33 @@ interface OnTileClick {
|
||||||
fun onTileClicked() {
|
fun onTileClicked() {
|
||||||
getCallbacks<() -> Unit>(14).forEach { it() }
|
getCallbacks<() -> Unit>(14).forEach { it() }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CanOnCallback.useAliveFlow(stateFlow: MutableStateFlow<Boolean>) {
|
||||||
|
if (this is OnCreate) {
|
||||||
|
onCreated { stateFlow.value = true }
|
||||||
|
}
|
||||||
|
if (this is OnDestroy) {
|
||||||
|
onDestroyed { stateFlow.value = false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CanOnCallback.useLogLifecycle() {
|
||||||
|
LogUtils.d("useLogLifecycle", this)
|
||||||
|
if (this is OnCreate) {
|
||||||
|
onCreated { LogUtils.d("onCreated", this) }
|
||||||
|
}
|
||||||
|
if (this is OnDestroy) {
|
||||||
|
onDestroyed { LogUtils.d("onDestroyed", this) }
|
||||||
|
}
|
||||||
|
if (this is OnA11yConnected) {
|
||||||
|
onA11yConnected { LogUtils.d("onA11yConnected", this) }
|
||||||
|
}
|
||||||
|
if (this is OnChangeListen) {
|
||||||
|
onStartListened { LogUtils.d("onStartListened", this) }
|
||||||
|
onStopListened { LogUtils.d("onStopListened", this) }
|
||||||
|
}
|
||||||
|
if (this is OnTileClick) {
|
||||||
|
onTileClicked { LogUtils.d("onTileClicked", this) }
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package li.songe.gkd.util
|
package li.songe.gkd.util
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.Activity.RESULT_OK
|
import android.app.Activity.RESULT_OK
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
@ -22,8 +21,10 @@ import kotlin.coroutines.suspendCoroutine
|
||||||
|
|
||||||
// https://github.com/npes87184/ScreenShareTile/blob/master/app/src/main/java/com/npes87184/screenshottile/ScreenshotService.kt
|
// https://github.com/npes87184/ScreenShareTile/blob/master/app/src/main/java/com/npes87184/screenshottile/ScreenshotService.kt
|
||||||
|
|
||||||
@SuppressLint("WrongConstant")
|
class ScreenshotUtil(
|
||||||
class ScreenshotUtil(private val context: Context, private val screenshotIntent: Intent) {
|
private val context: Context,
|
||||||
|
private val screenshotIntent: Intent
|
||||||
|
) {
|
||||||
|
|
||||||
private val handler by lazy { Handler(Looper.getMainLooper()) }
|
private val handler by lazy { Handler(Looper.getMainLooper()) }
|
||||||
private var virtualDisplay: VirtualDisplay? = null
|
private var virtualDisplay: VirtualDisplay? = null
|
||||||
|
@ -37,6 +38,13 @@ class ScreenshotUtil(private val context: Context, private val screenshotIntent:
|
||||||
) as MediaProjectionManager
|
) as MediaProjectionManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val width: Int
|
||||||
|
get() = ScreenUtils.getScreenWidth()
|
||||||
|
private val height: Int
|
||||||
|
get() = ScreenUtils.getScreenHeight()
|
||||||
|
private val dpi: Int
|
||||||
|
get() = ScreenUtils.getScreenDensityDpi()
|
||||||
|
|
||||||
fun destroy() {
|
fun destroy() {
|
||||||
imageReader?.setOnImageAvailableListener(null, null)
|
imageReader?.setOnImageAvailableListener(null, null)
|
||||||
virtualDisplay?.release()
|
virtualDisplay?.release()
|
||||||
|
@ -101,10 +109,4 @@ class ScreenshotUtil(private val context: Context, private val screenshotIntent:
|
||||||
}
|
}
|
||||||
}, handler)
|
}, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val width by lazy { ScreenUtils.getScreenWidth() }
|
|
||||||
private val height by lazy { ScreenUtils.getScreenHeight() }
|
|
||||||
private val dpi by lazy { ScreenUtils.getScreenDensityDpi() }
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user