优化 findOnce()和findOne()等的效率

This commit is contained in:
hyb1996
2018-11-30 13:41:51 +08:00
parent 9d30996ae8
commit ada179690b
16 changed files with 112 additions and 93 deletions

View File

@@ -68,7 +68,7 @@
android:layout_weight="1" android:layout_weight="1"
android:hint="@string/text_source_file_path"> android:hint="@string/text_source_file_path">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/source_path" android:id="@+id/source_path"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -98,7 +98,7 @@
android:layout_weight="1" android:layout_weight="1"
android:hint="@string/text_output_apk_path"> android:hint="@string/text_output_apk_path">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/output_path" android:id="@+id/output_path"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -147,7 +147,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/text_app_name"> android:hint="@string/text_app_name">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/app_name" android:id="@+id/app_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
@@ -159,7 +159,7 @@
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:hint="@string/text_package_name"> android:hint="@string/text_package_name">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/package_name" android:id="@+id/package_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -183,7 +183,7 @@
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:hint="@string/text_version_name"> android:hint="@string/text_version_name">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/version_name" android:id="@+id/version_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -197,7 +197,7 @@
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:hint="@string/text_version_code"> android:hint="@string/text_version_code">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/version_code" android:id="@+id/version_code"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@@ -37,7 +37,7 @@
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:hint="@string/text_username"> android:hint="@string/text_username">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/username" android:id="@+id/username"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -53,7 +53,7 @@
android:layout_marginRight="8dp" android:layout_marginRight="8dp"
android:hint="@string/text_password"> android:hint="@string/text_password">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/password" android:id="@+id/password"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@@ -61,7 +61,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/text_app_name"> android:hint="@string/text_app_name">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/app_name" android:id="@+id/app_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
@@ -73,7 +73,7 @@
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:hint="@string/text_package_name"> android:hint="@string/text_package_name">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/package_name" android:id="@+id/package_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -97,7 +97,7 @@
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:hint="@string/text_version_name"> android:hint="@string/text_version_name">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/version_name" android:id="@+id/version_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -111,7 +111,7 @@
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:hint="@string/text_version_code"> android:hint="@string/text_version_code">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/version_code" android:id="@+id/version_code"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -153,7 +153,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/text_project_location"> android:hint="@string/text_project_location">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/project_location" android:id="@+id/project_location"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -192,7 +192,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/text_main_file_name"> android:hint="@string/text_main_file_name">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/main_file_name" android:id="@+id/main_file_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@@ -37,7 +37,7 @@
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:hint="@string/text_email"> android:hint="@string/text_email">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/email" android:id="@+id/email"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -54,7 +54,7 @@
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:hint="@string/text_username"> android:hint="@string/text_username">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/username" android:id="@+id/username"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -69,7 +69,7 @@
android:layout_marginRight="8dp" android:layout_marginRight="8dp"
android:hint="@string/text_password"> android:hint="@string/text_password">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/password" android:id="@+id/password"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@@ -417,7 +417,7 @@
android:hint="@string/text_broadcast_action"> android:hint="@string/text_broadcast_action">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/action" android:id="@+id/action"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@@ -77,7 +77,7 @@
android:layout_marginTop="@dimen/air_baseline_half" android:layout_marginTop="@dimen/air_baseline_half"
android:hint="@string/air_label_username"> android:hint="@string/air_label_username">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/air_inputUsername" android:id="@+id/air_inputUsername"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -93,7 +93,7 @@
android:hint="@string/air_label_password" android:hint="@string/air_label_password"
app:passwordToggleEnabled="true"> app:passwordToggleEnabled="true">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/air_inputPassword" android:id="@+id/air_inputPassword"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -137,7 +137,7 @@
android:layout_marginTop="@dimen/air_baseline_half" android:layout_marginTop="@dimen/air_baseline_half"
android:hint="@string/air_label_email_optional"> android:hint="@string/air_label_email_optional">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/air_inputEmail" android:id="@+id/air_inputEmail"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@@ -47,7 +47,7 @@
android:layout_marginTop="@dimen/air_baseline" android:layout_marginTop="@dimen/air_baseline"
android:hint="@string/air_label_issue_title"> android:hint="@string/air_label_issue_title">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/air_inputTitle" android:id="@+id/air_inputTitle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -62,7 +62,7 @@
android:layout_marginTop="@dimen/air_baseline_half" android:layout_marginTop="@dimen/air_baseline_half"
android:hint="@string/air_label_issue_description"> android:hint="@string/air_label_issue_description">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/air_inputDescription" android:id="@+id/air_inputDescription"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@@ -9,7 +9,7 @@
android:hint="@string/text_class_or_package_name" android:hint="@string/text_class_or_package_name"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/keywords" android:id="@+id/keywords"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>

View File

@@ -13,7 +13,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/text_find"> android:hint="@string/text_find">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/keywords" android:id="@+id/keywords"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
@@ -30,7 +30,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/text_replace"> android:hint="@string/text_replace">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/replacement" android:id="@+id/replacement"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>

View File

@@ -13,7 +13,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/text_loop_times"> android:hint="@string/text_loop_times">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/loop_times" android:id="@+id/loop_times"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -37,7 +37,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/text_loop_interval"> android:hint="@string/text_loop_interval">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/loop_interval" android:id="@+id/loop_interval"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -52,7 +52,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/text_loop_delay"> android:hint="@string/text_loop_delay">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/loop_delay" android:id="@+id/loop_delay"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@@ -26,7 +26,7 @@
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:hint="@string/text_name"> android:hint="@string/text_name">
<android.support.v7.widget.AppCompatEditText <androidx.appcompat.widget.AppCompatEditText
android:id="@+id/name" android:id="@+id/name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>

View File

@@ -4,6 +4,8 @@ import com.stardust.automator.UiGlobalSelector;
import com.stardust.automator.UiObject; import com.stardust.automator.UiObject;
import com.stardust.util.Consumer; import com.stardust.util.Consumer;
import androidx.appcompat.widget.AppCompatEditText;
import static com.stardust.autojs.codegeneration.CodeGenerator.FIND_ONE; import static com.stardust.autojs.codegeneration.CodeGenerator.FIND_ONE;
import static com.stardust.autojs.codegeneration.CodeGenerator.UNTIL_FIND; import static com.stardust.autojs.codegeneration.CodeGenerator.UNTIL_FIND;
import static com.stardust.autojs.codegeneration.CodeGenerator.WAIT_FOR; import static com.stardust.autojs.codegeneration.CodeGenerator.WAIT_FOR;
@@ -115,9 +117,9 @@ public class UiSelectorGenerator {
private boolean shouldStopGeneration(UiGlobalSelector selector) { private boolean shouldStopGeneration(UiGlobalSelector selector) {
if (mSearchMode == UNTIL_FIND) { if (mSearchMode == UNTIL_FIND) {
return !selector.findAndReturnList(mRoot).isEmpty(); return !selector.findAndReturnList(mRoot, 1).isEmpty();
} else { } else {
return selector.findAndReturnList(mRoot).size() == 1; return selector.findAndReturnList(mRoot, 2).size() == 1;
} }
} }

View File

@@ -2,7 +2,9 @@ package com.stardust.autojs.core.accessibility;
import android.os.Looper; import android.os.Looper;
import android.os.SystemClock; import android.os.SystemClock;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import android.util.Log; import android.util.Log;
import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo;
@@ -70,22 +72,26 @@ public class UiSelector extends UiGlobalSelector {
mAllocator = allocator; mAllocator = allocator;
} }
@NonNull protected UiObjectCollection find(int max) {
@ScriptInterface
public UiObjectCollection find() {
ensureAccessibilityServiceEnabled(); ensureAccessibilityServiceEnabled();
if((mAccessibilityBridge.getFlags() & AccessibilityBridge.FLAG_FIND_ON_UI_THREAD)!=0 if ((mAccessibilityBridge.getFlags() & AccessibilityBridge.FLAG_FIND_ON_UI_THREAD) != 0
&& Looper.myLooper() != Looper.getMainLooper()){ && Looper.myLooper() != Looper.getMainLooper()) {
VolatileBox<UiObjectCollection> result = new VolatileBox<>(); VolatileBox<UiObjectCollection> result = new VolatileBox<>();
mAccessibilityBridge.post(() -> result.setAndNotify(findImpl())); mAccessibilityBridge.post(() -> result.setAndNotify(findImpl(max)));
return result.blockedGet(); return result.blockedGet();
} }
return findImpl(); return findImpl(max);
} }
@NonNull @NonNull
@ScriptInterface @ScriptInterface
protected UiObjectCollection findImpl() { public UiObjectCollection find() {
return find(Integer.MAX_VALUE);
}
@NonNull
@ScriptInterface
protected UiObjectCollection findImpl(int max) {
AccessibilityNodeInfo root = mAccessibilityBridge.getRootInCurrentWindow(); AccessibilityNodeInfo root = mAccessibilityBridge.getRootInCurrentWindow();
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG)
Log.d(TAG, "find: root = " + root); Log.d(TAG, "find: root = " + root);
@@ -96,7 +102,7 @@ public class UiSelector extends UiGlobalSelector {
Log.d(TAG, "package in white list, return null"); Log.d(TAG, "package in white list, return null");
return UiObjectCollection.Companion.getEMPTY(); return UiObjectCollection.Companion.getEMPTY();
} }
return findOf(UiObject.Companion.createRoot(root, mAllocator)); return findOf(UiObject.Companion.createRoot(root, mAllocator), max);
} }
@Override @Override
@@ -157,7 +163,7 @@ public class UiSelector extends UiGlobalSelector {
} }
private void ensureNonUiThread() { private void ensureNonUiThread() {
if(Looper.myLooper() == Looper.getMainLooper()){ if (Looper.myLooper() == Looper.getMainLooper()) {
// TODO: 2018/11/1 配置字符串 // TODO: 2018/11/1 配置字符串
throw new IllegalThreadStateException("不能在ui线程执行阻塞操作, 请在子线程或子脚本执行findOne()或untilFind()"); throw new IllegalThreadStateException("不能在ui线程执行阻塞操作, 请在子线程或子脚本执行findOne()或untilFind()");
} }
@@ -165,16 +171,13 @@ public class UiSelector extends UiGlobalSelector {
@ScriptInterface @ScriptInterface
public UiObject findOne(long timeout) { public UiObject findOne(long timeout) {
if (timeout == -1) { UiObjectCollection uiObjectCollection = find(1);
return untilFindOne();
}
UiObjectCollection uiObjectCollection = find();
long start = SystemClock.uptimeMillis(); long start = SystemClock.uptimeMillis();
while (uiObjectCollection.empty()) { while (uiObjectCollection.empty()) {
if (Thread.currentThread().isInterrupted()) { if (Thread.currentThread().isInterrupted()) {
throw new ScriptInterruptedException(); throw new ScriptInterruptedException();
} }
if (SystemClock.uptimeMillis() - start > timeout) { if (timeout > 0 && SystemClock.uptimeMillis() - start > timeout) {
return null; return null;
} }
try { try {
@@ -182,7 +185,7 @@ public class UiSelector extends UiGlobalSelector {
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new ScriptInterruptedException(); throw new ScriptInterruptedException();
} }
uiObjectCollection = find(); uiObjectCollection = find(1);
} }
return uiObjectCollection.get(0); return uiObjectCollection.get(0);
} }
@@ -192,7 +195,7 @@ public class UiSelector extends UiGlobalSelector {
} }
public UiObject findOnce(int index) { public UiObject findOnce(int index) {
UiObjectCollection uiObjectCollection = find(); UiObjectCollection uiObjectCollection = find(index + 1);
if (index >= uiObjectCollection.size()) { if (index >= uiObjectCollection.size()) {
return null; return null;
} }
@@ -212,8 +215,7 @@ public class UiSelector extends UiGlobalSelector {
@NonNull @NonNull
public UiObject untilFindOne() { public UiObject untilFindOne() {
UiObjectCollection collection = untilFind(); return findOne(-1);
return collection.get(0);
} }
@ScriptInterface @ScriptInterface

View File

@@ -186,172 +186,172 @@ open class UiGlobalSelector {
//// 第二类筛选条件 -able //// 第二类筛选条件 -able
fun checkable(b: Boolean): UiGlobalSelector { fun checkable(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.CHECKABLE, b)) mFilters.add(BooleanFilter[BooleanFilter.CHECKABLE, b])
return this return this
} }
fun checked(b: Boolean): UiGlobalSelector { fun checked(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.CHECKED, b)) mFilters.add(BooleanFilter[BooleanFilter.CHECKED, b])
return this return this
} }
fun focusable(b: Boolean): UiGlobalSelector { fun focusable(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.FOCUSABLE, b)) mFilters.add(BooleanFilter[BooleanFilter.FOCUSABLE, b])
return this return this
} }
fun focused(b: Boolean): UiGlobalSelector { fun focused(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.FOCUSED, b)) mFilters.add(BooleanFilter[BooleanFilter.FOCUSED, b])
return this return this
} }
fun visibleToUser(b: Boolean): UiGlobalSelector { fun visibleToUser(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.VISIBLE_TO_USER, b)) mFilters.add(BooleanFilter[BooleanFilter.VISIBLE_TO_USER, b])
return this return this
} }
fun accessibilityFocused(b: Boolean): UiGlobalSelector { fun accessibilityFocused(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.ACCESSIBILITY_FOCUSED, b)) mFilters.add(BooleanFilter[BooleanFilter.ACCESSIBILITY_FOCUSED, b])
return this return this
} }
fun selected(b: Boolean): UiGlobalSelector { fun selected(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.SELECTED, b)) mFilters.add(BooleanFilter[BooleanFilter.SELECTED, b])
return this return this
} }
fun clickable(b: Boolean): UiGlobalSelector { fun clickable(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.CLICKABLE, b)) mFilters.add(BooleanFilter[BooleanFilter.CLICKABLE, b])
return this return this
} }
fun longClickable(b: Boolean): UiGlobalSelector { fun longClickable(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.LONG_CLICKABLE, b)) mFilters.add(BooleanFilter[BooleanFilter.LONG_CLICKABLE, b])
return this return this
} }
fun enabled(b: Boolean): UiGlobalSelector { fun enabled(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.ENABLED, b)) mFilters.add(BooleanFilter[BooleanFilter.ENABLED, b])
return this return this
} }
fun password(b: Boolean): UiGlobalSelector { fun password(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.PASSWORD, b)) mFilters.add(BooleanFilter[BooleanFilter.PASSWORD, b])
return this return this
} }
fun scrollable(b: Boolean): UiGlobalSelector { fun scrollable(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.SCROLLABLE, b)) mFilters.add(BooleanFilter[BooleanFilter.SCROLLABLE, b])
return this return this
} }
fun editable(b: Boolean): UiGlobalSelector { fun editable(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.EDITABLE, b)) mFilters.add(BooleanFilter[BooleanFilter.EDITABLE, b])
return this return this
} }
fun contentInvalid(b: Boolean): UiGlobalSelector { fun contentInvalid(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.CONTENT_INVALID, b)) mFilters.add(BooleanFilter[BooleanFilter.CONTENT_INVALID, b])
return this return this
} }
fun contextClickable(b: Boolean): UiGlobalSelector { fun contextClickable(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.CONTEXT_CLICKABLE, b)) mFilters.add(BooleanFilter[BooleanFilter.CONTEXT_CLICKABLE, b])
return this return this
} }
fun multiLine(b: Boolean): UiGlobalSelector { fun multiLine(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.MULTI_LINE, b)) mFilters.add(BooleanFilter[BooleanFilter.MULTI_LINE, b])
return this return this
} }
fun dismissable(b: Boolean): UiGlobalSelector { fun dismissable(b: Boolean): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.DISMISSABLE, b)) mFilters.add(BooleanFilter[BooleanFilter.DISMISSABLE, b])
return this return this
} }
fun checkable(): UiGlobalSelector { fun checkable(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.CHECKABLE, true)) mFilters.add(BooleanFilter[BooleanFilter.CHECKABLE, true])
return this return this
} }
fun checked(): UiGlobalSelector { fun checked(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.CHECKED, true)) mFilters.add(BooleanFilter[BooleanFilter.CHECKED, true])
return this return this
} }
fun focusable(): UiGlobalSelector { fun focusable(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.FOCUSABLE, true)) mFilters.add(BooleanFilter[BooleanFilter.FOCUSABLE, true])
return this return this
} }
fun focused(): UiGlobalSelector { fun focused(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.FOCUSED, true)) mFilters.add(BooleanFilter[BooleanFilter.FOCUSED, true])
return this return this
} }
fun visibleToUser(): UiGlobalSelector { fun visibleToUser(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.VISIBLE_TO_USER, true)) mFilters.add(BooleanFilter[BooleanFilter.VISIBLE_TO_USER, true])
return this return this
} }
fun accessibilityFocused(): UiGlobalSelector { fun accessibilityFocused(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.ACCESSIBILITY_FOCUSED, true)) mFilters.add(BooleanFilter[BooleanFilter.ACCESSIBILITY_FOCUSED, true])
return this return this
} }
fun selected(): UiGlobalSelector { fun selected(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.SELECTED, true)) mFilters.add(BooleanFilter[BooleanFilter.SELECTED, true])
return this return this
} }
fun clickable(): UiGlobalSelector { fun clickable(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.CLICKABLE, true)) mFilters.add(BooleanFilter[BooleanFilter.CLICKABLE, true])
return this return this
} }
fun longClickable(): UiGlobalSelector { fun longClickable(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.LONG_CLICKABLE, true)) mFilters.add(BooleanFilter[BooleanFilter.LONG_CLICKABLE, true])
return this return this
} }
fun enabled(): UiGlobalSelector { fun enabled(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.ENABLED, true)) mFilters.add(BooleanFilter[BooleanFilter.ENABLED, true])
return this return this
} }
fun password(): UiGlobalSelector { fun password(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.PASSWORD, true)) mFilters.add(BooleanFilter[BooleanFilter.PASSWORD, true])
return this return this
} }
fun scrollable(): UiGlobalSelector { fun scrollable(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.SCROLLABLE, true)) mFilters.add(BooleanFilter[BooleanFilter.SCROLLABLE, true])
return this return this
} }
fun editable(): UiGlobalSelector { fun editable(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.EDITABLE, true)) mFilters.add(BooleanFilter[BooleanFilter.EDITABLE, true])
return this return this
} }
fun contentInvalid(): UiGlobalSelector { fun contentInvalid(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.CONTENT_INVALID, true)) mFilters.add(BooleanFilter[BooleanFilter.CONTENT_INVALID, true])
return this return this
} }
fun contextClickable(): UiGlobalSelector { fun contextClickable(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.CONTEXT_CLICKABLE, true)) mFilters.add(BooleanFilter[BooleanFilter.CONTEXT_CLICKABLE, true])
return this return this
} }
fun multiLine(): UiGlobalSelector { fun multiLine(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.MULTI_LINE, true)) mFilters.add(BooleanFilter[BooleanFilter.MULTI_LINE, true])
return this return this
} }
fun dismissable(): UiGlobalSelector { fun dismissable(): UiGlobalSelector {
mFilters.add(BooleanFilter.get(BooleanFilter.DISMISSABLE, true)) mFilters.add(BooleanFilter[BooleanFilter.DISMISSABLE, true])
return this return this
} }
@@ -401,30 +401,36 @@ open class UiGlobalSelector {
fun filter(filter: BooleanFilter.BooleanSupplier): UiGlobalSelector { fun filter(filter: BooleanFilter.BooleanSupplier): UiGlobalSelector {
mFilters.add(object : DfsFilter() { mFilters.add(object : DfsFilter() {
override fun isIncluded(nodeInfo: UiObject): Boolean { override fun isIncluded(nodeInfo: UiObject): Boolean {
return filter.get(nodeInfo) return filter[nodeInfo]
} }
}) })
return this return this
} }
fun findOf(node: UiObject): UiObjectCollection { fun findOf(node: UiObject, max: Int): UiObjectCollection {
return UiObjectCollection.of(findAndReturnList(node)) return UiObjectCollection.of(findAndReturnList(node, max))
} }
fun findAndReturnList(node: UiObject): List<UiObject> { fun findOf(node: UiObject): UiObjectCollection {
return findOf(node, Int.MAX_VALUE)
}
fun findAndReturnList(node: UiObject, max: Int = Int.MAX_VALUE): List<UiObject> {
var list: List<UiObject> = listOf(node) var list: List<UiObject> = listOf(node)
for (filter in mFilters) { for (filter in mFilters) {
val oldMax = filter.maxCount
filter.maxCount = max
list = filter.filter(list) list = filter.filter(list)
filter.maxCount = oldMax
} }
return list return list
} }
fun findOneOf(node: UiObject): UiObject? { fun findOneOf(node: UiObject): UiObject? {
// TODO: 2017/3/9 优化 val collection = findOf(node, 1)
val collection = findOf(node)
return if (collection.size() == 0) { return if (collection.size() == 0) {
null null
} else collection.get(0) } else collection[0]
} }
fun addFilter(filter: ListFilter): UiGlobalSelector { fun addFilter(filter: ListFilter): UiGlobalSelector {

View File

@@ -16,6 +16,9 @@ abstract class DfsFilter : ListFilter(), Filter {
if (isIncluded(node)) { if (isIncluded(node)) {
list.add(node) list.add(node)
} }
if (list.size >= maxCount) {
break
}
filterChildren(node, list) filterChildren(node, list)
} }
return list return list
@@ -26,6 +29,9 @@ abstract class DfsFilter : ListFilter(), Filter {
if (isIncluded(node)) { if (isIncluded(node)) {
list.add(node) list.add(node)
} }
if (list.size >= maxCount) {
return list
}
filterChildren(node, list) filterChildren(node, list)
return list return list
} }
@@ -37,6 +43,9 @@ abstract class DfsFilter : ListFilter(), Filter {
if (included) { if (included) {
list.add(child) list.add(child)
} }
if (list.size >= maxCount) {
break
}
filterChildren(child, list) filterChildren(child, list)
if (!included) { if (!included) {
child.recycle() child.recycle()

View File

@@ -20,7 +20,7 @@ abstract class ListFilter {
val list = ArrayList<UiObject>() val list = ArrayList<UiObject>()
for (node in nodes) { for (node in nodes) {
list.addAll(filter(node)) list.addAll(filter(node))
if (list.size > maxCount) { if (list.size >= maxCount) {
break break
} }
} }