mirror of
https://github.com/gkd-kit/gkd.git
synced 2024-11-16 03:32:38 +08:00
fix: 限制节点数量避免内存溢出
This commit is contained in:
parent
c029a38bb8
commit
8074175489
|
@ -96,47 +96,74 @@ private fun AccessibilityNodeInfo.getTempRect(): Rect {
|
||||||
return tempRect
|
return tempRect
|
||||||
}
|
}
|
||||||
|
|
||||||
val abTransform = Transform<AccessibilityNodeInfo>(
|
|
||||||
getAttr = { node, name ->
|
|
||||||
when (name) {
|
|
||||||
"id" -> node.viewIdResourceName
|
|
||||||
"name" -> node.className
|
|
||||||
"text" -> node.text
|
|
||||||
"text.length" -> node.text?.length
|
|
||||||
"desc" -> node.contentDescription
|
|
||||||
"desc.length" -> node.contentDescription?.length
|
|
||||||
|
|
||||||
"clickable" -> node.isClickable
|
// https://github.com/gkd-kit/gkd/issues/115
|
||||||
"checkable" -> node.isCheckable
|
private const val MAX_CHILD_SIZE = 256
|
||||||
"checked" -> node.isChecked
|
private const val MAX_DESCENDANTS_SIZE = 4096
|
||||||
"focusable" -> node.isFocusable
|
|
||||||
"visibleToUser" -> node.isVisibleToUser
|
|
||||||
|
|
||||||
"left" -> node.getTempRect().left
|
private val getChildren: (AccessibilityNodeInfo) -> Sequence<AccessibilityNodeInfo> = { node ->
|
||||||
"top" -> node.getTempRect().top
|
sequence {
|
||||||
"right" -> node.getTempRect().right
|
repeat(node.childCount.coerceAtMost(MAX_CHILD_SIZE)) { i ->
|
||||||
"bottom" -> node.getTempRect().bottom
|
val child = node.getChild(i) ?: return@sequence
|
||||||
|
yield(child)
|
||||||
"width" -> node.getTempRect().width()
|
|
||||||
"height" -> node.getTempRect().height()
|
|
||||||
|
|
||||||
"index" -> node.getIndex()
|
|
||||||
"depth" -> node.getDepth()
|
|
||||||
"childCount" -> node.childCount
|
|
||||||
else -> null
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val getAttr: (AccessibilityNodeInfo, String) -> Any? = { node, name ->
|
||||||
|
when (name) {
|
||||||
|
"id" -> node.viewIdResourceName
|
||||||
|
"name" -> node.className
|
||||||
|
"text" -> node.text
|
||||||
|
"text.length" -> node.text?.length
|
||||||
|
"desc" -> node.contentDescription
|
||||||
|
"desc.length" -> node.contentDescription?.length
|
||||||
|
|
||||||
|
"clickable" -> node.isClickable
|
||||||
|
"checkable" -> node.isCheckable
|
||||||
|
"checked" -> node.isChecked
|
||||||
|
"focusable" -> node.isFocusable
|
||||||
|
"visibleToUser" -> node.isVisibleToUser
|
||||||
|
|
||||||
|
"left" -> node.getTempRect().left
|
||||||
|
"top" -> node.getTempRect().top
|
||||||
|
"right" -> node.getTempRect().right
|
||||||
|
"bottom" -> node.getTempRect().bottom
|
||||||
|
|
||||||
|
"width" -> node.getTempRect().width()
|
||||||
|
"height" -> node.getTempRect().height()
|
||||||
|
|
||||||
|
"index" -> node.getIndex()
|
||||||
|
"depth" -> node.getDepth()
|
||||||
|
"childCount" -> node.childCount
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val abTransform = Transform(getAttr = getAttr,
|
||||||
getName = { node -> node.className },
|
getName = { node -> node.className },
|
||||||
getChildren = { node ->
|
getChildren = getChildren,
|
||||||
sequence {
|
|
||||||
repeat(node.childCount) { i ->
|
|
||||||
yield(node.getChild(i))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getChild = { node, index -> node.getChild(index) },
|
getChild = { node, index -> node.getChild(index) },
|
||||||
getParent = { node -> node.parent },
|
getParent = { node -> node.parent },
|
||||||
)
|
getDescendants = { node ->
|
||||||
|
sequence {
|
||||||
|
val stack = mutableListOf(node)
|
||||||
|
val tempNodes = mutableListOf<AccessibilityNodeInfo>()
|
||||||
|
do {
|
||||||
|
val top = stack.removeLast()
|
||||||
|
yield(top)
|
||||||
|
for (childNode in getChildren(top)) {
|
||||||
|
tempNodes.add(childNode)
|
||||||
|
}
|
||||||
|
if (tempNodes.isNotEmpty()) {
|
||||||
|
for (i in tempNodes.size - 1 downTo 0) {
|
||||||
|
stack.add(tempNodes[i])
|
||||||
|
}
|
||||||
|
tempNodes.clear()
|
||||||
|
}
|
||||||
|
} while (stack.isNotEmpty())
|
||||||
|
}.take(MAX_DESCENDANTS_SIZE)
|
||||||
|
})
|
||||||
|
|
||||||
private var lastToastTime = -1L
|
private var lastToastTime = -1L
|
||||||
fun toastClickTip() {
|
fun toastClickTip() {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import kotlin.js.JsExport
|
||||||
class CommonTransform<T : Any>(
|
class CommonTransform<T : Any>(
|
||||||
getAttr: (T, String) -> Any?,
|
getAttr: (T, String) -> Any?,
|
||||||
getName: (T) -> String?,
|
getName: (T) -> String?,
|
||||||
getChildren: (T) -> Array<T?>,
|
getChildren: (T) -> Array<T>,
|
||||||
getParent: (T) -> T?,
|
getParent: (T) -> T?,
|
||||||
) {
|
) {
|
||||||
internal val transform = Transform(
|
internal val transform = Transform(
|
||||||
|
@ -18,26 +18,27 @@ class CommonTransform<T : Any>(
|
||||||
getParent = getParent,
|
getParent = getParent,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST", "UNUSED")
|
||||||
val querySelectorAll: (T, CommonSelector) -> Array<T> = { node, selector ->
|
val querySelectorAll: (T, CommonSelector) -> Array<T> = { node, selector ->
|
||||||
val result =
|
val result =
|
||||||
transform.querySelectorAll(node, selector.selector).toList().toTypedArray<Any?>()
|
transform.querySelectorAll(node, selector.selector).toList().toTypedArray<Any?>()
|
||||||
result as Array<T>
|
result as Array<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNUSED")
|
||||||
val querySelector: (T, CommonSelector) -> T? = { node, selector ->
|
val querySelector: (T, CommonSelector) -> T? = { node, selector ->
|
||||||
transform.querySelectorAll(node, selector.selector).firstOrNull()
|
transform.querySelectorAll(node, selector.selector).firstOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST", "UNUSED")
|
||||||
val querySelectorTrackAll: (T, CommonSelector) -> Array<Array<T>> = { node, selector ->
|
val querySelectorTrackAll: (T, CommonSelector) -> Array<Array<T>> = { node, selector ->
|
||||||
val result = transform.querySelectorTrackAll(node, selector.selector)
|
val result = transform.querySelectorTrackAll(node, selector.selector)
|
||||||
.map { it.toTypedArray<Any?>() as Array<T> }.toList().toTypedArray<Any?>()
|
.map { it.toTypedArray<Any?>() as Array<T> }.toList().toTypedArray<Any?>()
|
||||||
result as Array<Array<T>>
|
result as Array<Array<T>>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST", "UNUSED")
|
||||||
val querySelectorTrack: (T, CommonSelector) -> Array<T>? = { node, selector ->
|
val querySelectorTrack: (T, CommonSelector) -> Array<T>? = { node, selector ->
|
||||||
transform.querySelectorTrackAll(node, selector.selector).firstOrNull()
|
transform.querySelectorTrackAll(node, selector.selector).firstOrNull()
|
||||||
?.toTypedArray<Any?>() as Array<T>?
|
?.toTypedArray<Any?>() as Array<T>?
|
||||||
|
|
|
@ -4,7 +4,7 @@ package li.songe.selector
|
||||||
class Transform<T>(
|
class Transform<T>(
|
||||||
val getAttr: (T, String) -> Any?,
|
val getAttr: (T, String) -> Any?,
|
||||||
val getName: (T) -> CharSequence?,
|
val getName: (T) -> CharSequence?,
|
||||||
val getChildren: (T) -> Sequence<T?>,
|
val getChildren: (T) -> Sequence<T>,
|
||||||
val getChild: (T, Int) -> T? = { node, offset -> getChildren(node).elementAtOrNull(offset) },
|
val getChild: (T, Int) -> T? = { node, offset -> getChildren(node).elementAtOrNull(offset) },
|
||||||
val getParent: (T) -> T?,
|
val getParent: (T) -> T?,
|
||||||
val getAncestors: (T) -> Sequence<T> = { node ->
|
val getAncestors: (T) -> Sequence<T> = { node ->
|
||||||
|
@ -55,9 +55,7 @@ class Transform<T>(
|
||||||
val top = stack.removeLast()
|
val top = stack.removeLast()
|
||||||
yield(top)
|
yield(top)
|
||||||
for (childNode in getChildren(top)) {
|
for (childNode in getChildren(top)) {
|
||||||
if (childNode != null) {
|
tempNodes.add(childNode)
|
||||||
tempNodes.add(childNode)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (tempNodes.isNotEmpty()) {
|
if (tempNodes.isNotEmpty()) {
|
||||||
for (i in tempNodes.size - 1 downTo 0) {
|
for (i in tempNodes.size - 1 downTo 0) {
|
||||||
|
@ -70,6 +68,7 @@ class Transform<T>(
|
||||||
},
|
},
|
||||||
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val querySelectorAll: (T, Selector) -> Sequence<T> = { node, selector ->
|
val querySelectorAll: (T, Selector) -> Sequence<T> = { node, selector ->
|
||||||
sequence {
|
sequence {
|
||||||
val trackNodes: MutableList<T> = mutableListOf()
|
val trackNodes: MutableList<T> = mutableListOf()
|
||||||
|
@ -95,6 +94,8 @@ class Transform<T>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNUSED")
|
||||||
val querySelectorTrack: (T, Selector) -> List<T>? = { node, selector ->
|
val querySelectorTrack: (T, Selector) -> List<T>? = { node, selector ->
|
||||||
querySelectorTrackAll(
|
querySelectorTrackAll(
|
||||||
node, selector
|
node, selector
|
||||||
|
|
Loading…
Reference in New Issue
Block a user