Skip to content

Commit

Permalink
perf: 优化查询速度
Browse files Browse the repository at this point in the history
  • Loading branch information
lisonge committed Dec 24, 2023
1 parent 8e56d29 commit b105be7
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 38 deletions.
10 changes: 6 additions & 4 deletions app/src/main/kotlin/li/songe/gkd/data/ResolvedRule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ package li.songe.gkd.data
import android.view.accessibility.AccessibilityNodeInfo
import kotlinx.coroutines.Job
import li.songe.gkd.service.TopActivity
import li.songe.gkd.service.lastTriggerAppRule
import li.songe.gkd.service.lastTriggerRule
import li.songe.gkd.service.lastTriggerTime
import li.songe.gkd.service.querySelector
import li.songe.selector.Selector

Expand Down Expand Up @@ -47,10 +48,11 @@ sealed class ResolvedRule(
var actionTriggerTime = Value(0L)
fun trigger() {
actionTriggerTime.value = System.currentTimeMillis()
lastTriggerTime = actionTriggerTime.value
// 重置延迟点
actionDelayTriggerTime = 0L
actionCount.value++
lastTriggerAppRule = this
lastTriggerRule = this
}

val actionMaximum = ((if (rule.actionMaximumKey != null) {
Expand Down Expand Up @@ -96,8 +98,8 @@ sealed class ResolvedRule(
}
}
if (preAppRules.isNotEmpty()) { // 需要提前点击某个规则
lastTriggerAppRule ?: return 2
return if (preAppRules.any { it === lastTriggerAppRule }) {
lastTriggerRule ?: return 2
return if (preAppRules.any { it === lastTriggerRule }) {
0
} else {
3 // 上一个点击的规则不在当前需要点击的列表
Expand Down
12 changes: 6 additions & 6 deletions app/src/main/kotlin/li/songe/gkd/service/AbEvent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ package li.songe.gkd.service
import android.view.accessibility.AccessibilityEvent

data class AbEvent(
val eventType: Int,
val eventTime: Long,
val packageName: String,
val type: Int,
val time: Long,
val appId: String,
val className: String,
)

fun AccessibilityEvent.toAbEvent(): AbEvent? {
return AbEvent(
eventType = eventType,
eventTime = eventTime,
packageName = packageName?.toString() ?: return null,
type = eventType,
time = System.currentTimeMillis(),
appId = packageName?.toString() ?: return null,
className = className?.toString() ?: return null
)
}
3 changes: 2 additions & 1 deletion app/src/main/kotlin/li/songe/gkd/service/AbState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ fun getCurrentRules(): ActivityRule {
return activityRuleFlow.value
}

var lastTriggerAppRule: ResolvedRule? = null
var lastTriggerRule: ResolvedRule? = null
var lastTriggerTime = 0L
var appChangeTime = 0L

fun insertClickLog(appRule: ResolvedRule) {
Expand Down
75 changes: 48 additions & 27 deletions app/src/main/kotlin/li/songe/gkd/service/GkdAbService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import android.view.Display
import android.view.View
import android.view.WindowManager
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ScreenUtils
import com.blankj.utilcode.util.ToastUtils
Expand All @@ -32,8 +33,8 @@ import li.songe.gkd.composition.CompositionAbService
import li.songe.gkd.composition.CompositionExt.useLifeCycleLog
import li.songe.gkd.composition.CompositionExt.useScope
import li.songe.gkd.data.ActionResult
import li.songe.gkd.data.AttrInfo
import li.songe.gkd.data.GkdAction
import li.songe.gkd.data.NodeInfo
import li.songe.gkd.data.RawSubscription
import li.songe.gkd.data.RpcError
import li.songe.gkd.data.SubsVersion
Expand Down Expand Up @@ -98,8 +99,14 @@ class GkdAbService : CompositionAbService({
onDestroy {
singleThread.cancel()
}
fun newQueryTask() {
scope.launchTry(singleThread) {
val loopCheckTask = MutableStateFlow(0)
fun newQueryTask(eventNode: AccessibilityNodeInfo? = null) {
val ctx = if (System.currentTimeMillis() - appChangeTime < 5000L) {
Dispatchers.IO
} else {
singleThread
}
scope.launchTry(ctx) {
val activityRule = getCurrentRules()
for (rule in (activityRule.currentRules)) {
val statusCode = rule.statusCode
Expand All @@ -111,7 +118,7 @@ class GkdAbService : CompositionAbService({
}
}
if (statusCode != 0) continue
val nodeVal = safeActiveWindow ?: continue
val nodeVal = (eventNode ?: safeActiveWindow) ?: continue
val target = rule.query(nodeVal) ?: continue
if (activityRule !== getCurrentRules()) break
if (rule.checkDelay() && rule.actionDelayJob == null) {
Expand All @@ -122,16 +129,27 @@ class GkdAbService : CompositionAbService({
}
continue
}
val actionResult = rule.performAction(context, target)
if (actionResult.result) {
LogUtils.d(
*rule.matches.toTypedArray(),
NodeInfo.abNodeToNode(nodeVal, target).attr,
actionResult
)
insertClickLog(rule)
scope.launch(singleThread) {
if (rule.statusCode != 0) return@launch
val actionResult = rule.performAction(context, target)
if (actionResult.result) {
insertClickLog(rule)
LogUtils.d(
*rule.matches.toTypedArray(),
AttrInfo.info2data(nodeVal, 0, 0),
actionResult
)
}
}
}
if (activityRule.currentRules.any { r -> r.statusCode != 5 }) {
loopCheckTask.value++
}
}
}
scope.launch(singleThread) {
loopCheckTask.debounce(5000).collect {
newQueryTask()
}
}

Expand All @@ -141,40 +159,43 @@ class GkdAbService : CompositionAbService({
if (!(event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED || event.eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED)) return@onAccessibilityEvent

if (event.eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED &&
skipAppIds.any { id ->
id.contentEquals(
event.packageName
)
}
skipAppIds.contains(event.packageName.toString())
) {
return@onAccessibilityEvent
}

if (event.eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
if (event.eventTime - lastContentEventTime < 100 && event.eventTime - appChangeTime > 5000) {
val fixedEvent = event.toAbEvent() ?: return@onAccessibilityEvent
if (fixedEvent.type == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
if (fixedEvent.time - lastContentEventTime < 100 && fixedEvent.time - appChangeTime > 5000 && fixedEvent.time - lastTriggerTime > 3000) {
return@onAccessibilityEvent
}
lastContentEventTime = event.eventTime
lastContentEventTime = fixedEvent.time
}

// AccessibilityEvent 的 clear 方法会在后续时间被系统调用导致内部数据丢失
// 因此不要在协程/子线程内传递引用, 此处使用 data class 保存数据
val fixedEvent = event.toAbEvent() ?: return@onAccessibilityEvent
val evAppId = fixedEvent.packageName
val evAppId = fixedEvent.appId
val evActivityId = fixedEvent.className


scope.launch(eventThread) {
val rightAppId = safeActiveWindow?.packageName?.toString() ?: return@launch
val eventNode = event.source ?: return@launch
val oldAppId = topActivityFlow.value.appId
val rightAppId = if (oldAppId == evAppId) {
oldAppId
} else {
safeActiveWindow?.packageName?.toString() ?: return@launch
}
if (rightAppId == evAppId) {
if (fixedEvent.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
if (fixedEvent.type == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
// tv.danmaku.bili, com.miui.home, com.miui.home.launcher.Launcher
if (isActivity(evAppId, evActivityId)) {
topActivityFlow.value = TopActivity(
evAppId, evActivityId, topActivityFlow.value.number + 1
)
}
} else {
if (fixedEvent.eventTime - lastTriggerShizukuTime > 300) {
if (fixedEvent.time - lastTriggerShizukuTime > 300) {
val shizukuTop = getShizukuTopActivity()
if (shizukuTop != null && shizukuTop.appId == rightAppId) {
if (shizukuTop.activityId == evActivityId) {
Expand All @@ -184,7 +205,7 @@ class GkdAbService : CompositionAbService({
}
topActivityFlow.value = shizukuTop
}
lastTriggerShizukuTime = fixedEvent.eventTime
lastTriggerShizukuTime = fixedEvent.time
}
}
}
Expand All @@ -209,7 +230,7 @@ class GkdAbService : CompositionAbService({

if (!storeFlow.value.enableService) return@launch

newQueryTask()
newQueryTask(eventNode)
}
}

Expand Down

0 comments on commit b105be7

Please sign in to comment.