Can';当系统的WebView为Chrome或Android系统WebView(均为84版)时,无法在基于WebView的应用程序上获得uiautomator转储
我从不同的应用程序中获取xml转储,这些应用程序在我构建的应用程序的服务中运行Can';当系统的WebView为Chrome或Android系统WebView(均为84版)时,无法在基于WebView的应用程序上获得uiautomator转储,android,android-webview,android-uiautomator,Android,Android Webview,Android Uiautomator,我从不同的应用程序中获取xml转储,这些应用程序在我构建的应用程序的服务中运行uiautomator dump命令,在根手机中。当Chrome或Android系统WebView被设置为WebView实现(版本不同于84)时,一切正常。当版本为84时,仅在WebView应用程序中,我无法获取视图,xml仅显示存在WebView,但不显示其子元素 我对Appium也做了同样的尝试(只是为了测试,以防我遗漏一些东西,因为我需要在我的应用程序中获取xml,而不需要连接到pc),并且行为是相同的(据我所知
uiautomator dump
命令,在根手机中。当Chrome或Android系统WebView被设置为WebView实现(版本不同于84)时,一切正常。当版本为84时,仅在WebView应用程序中,我无法获取视图,xml仅显示存在WebView,但不显示其子元素
我对Appium也做了同样的尝试(只是为了测试,以防我遗漏一些东西,因为我需要在我的应用程序中获取xml,而不需要连接到pc),并且行为是相同的(据我所知,Appium还使用uiautomator转储视图)
我已经用Chrome81.0.4044.138在安卓8上试用过,用安卓系统WebView 77.0.3865.92在安卓9上试用过,效果很好。当我将Android 9手机的Android系统WebView更新到最新版本(84.0.4147.125)时,无法从WebView应用程序中获取元素,Chrome也不能,只需获取WebView元素即可
我想知道的是,上一个Android WebView版本(Chrome和Android System,版本84)是否有我所缺少的新功能,这使得uiautomator无法从基于WebView的应用程序中正确转储xml文件。也许如果我必须做些别的事情,或者如果这是一个错误。谢谢大家! 我发现了一种更快、非根目录的获取视图层次结构的方法,这种方法在大多数Chrome版本(如果是基于webview的应用程序)中也能很好地工作,甚至在Chrome 80+中也是如此,它使用的是AccessibilityService 因此,我首先创建了一个扩展AccessibilityService的服务:
public class BasicAccessibilityService extends AccessibilityService {
private static BasicAccessibilityService instance;
public static BasicAccessibilityService getInstance(){
return instance;
}
@Override
protected void onServiceConnected() {
instance = this;
super.onServiceConnected();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
}
@Override
public void onInterrupt() {
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public AccessibilityNodeInfo getRootInActiveWindow() {
try {
return super.getRootInActiveWindow();
} catch (Throwable ignored) {
returenter code heren null;
}
}
}
在舱单中:
<service
android:name="BasicAccessibilityService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService"
/>
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/service_config" />
</service>
这将返回一个包含当前视图信息的AccessibilityNodeInfo
如果需要以XML形式获取视图层次结构,可以使用uiautomator源代码中的AccessibilityNodeInfoDumper
类,可以在以下位置找到:
此外,您还必须将以下内容中的AccessibilityNodeInfoHelper
添加到代码中:
当我实现上述代码将AccessibilityNodeInfo解析为XML时,我遇到了与以前使用uiautomator dump
获取视图时几乎相同的问题。我发现问题出在AccessibilityNodeInfoDumper
类中dumpNodeRec
中的isVisibleToUser
方法中
出于某种原因,对于某些应用程序,isVisibleToUser
方法返回false,其中的视图在基于webview的应用程序中可见,并且此行为会根据Chrome或System Web View版本的不同而变化。因此,一个可能的解决方案是不使用该方法并获取所有视图,即使是那些“不可见”的视图,或者另一个选择是使用您自己的方法来确定某个视图是否可见
对我来说,我对使用
isVisibleToUser
方法的行没有足够的评论。希望这能帮助任何需要做类似事情的人。我发现了一种更快、非根目录的方式来获取视图层次结构,这种方式在大多数Chrome版本(如果是基于webview的应用程序)中也能很好地工作,甚至在Chrome 80+中也是如此,它使用的是AccessibilityService
因此,我首先创建了一个扩展AccessibilityService的服务:
public class BasicAccessibilityService extends AccessibilityService {
private static BasicAccessibilityService instance;
public static BasicAccessibilityService getInstance(){
return instance;
}
@Override
protected void onServiceConnected() {
instance = this;
super.onServiceConnected();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
}
@Override
public void onInterrupt() {
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public AccessibilityNodeInfo getRootInActiveWindow() {
try {
return super.getRootInActiveWindow();
} catch (Throwable ignored) {
returenter code heren null;
}
}
}
在舱单中:
<service
android:name="BasicAccessibilityService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService"
/>
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/service_config" />
</service>
这将返回一个包含当前视图信息的AccessibilityNodeInfo
如果需要以XML形式获取视图层次结构,可以使用uiautomator源代码中的AccessibilityNodeInfoDumper
类,可以在以下位置找到:
此外,您还必须将以下内容中的AccessibilityNodeInfoHelper
添加到代码中:
当我实现上述代码将AccessibilityNodeInfo解析为XML时,我遇到了与以前使用uiautomator dump
获取视图时几乎相同的问题。我发现问题出在AccessibilityNodeInfoDumper
类中dumpNodeRec
中的isVisibleToUser
方法中
出于某种原因,对于某些应用程序,isVisibleToUser
方法返回false,其中的视图在基于webview的应用程序中可见,并且此行为会根据Chrome或System Web View版本的不同而变化。因此,一个可能的解决方案是不使用该方法并获取所有视图,即使是那些“不可见”的视图,或者另一个选择是使用您自己的方法来确定某个视图是否可见
对我来说,我对使用
isVisibleToUser
方法的行没有足够的评论。希望这对任何需要做类似事情的人都有帮助。您找到解决此问题的方法了吗?没有,目前唯一的“解决方案”是更改Chrome版本。我将尝试使用可访问性服务获取窗口转储,看看这种方法是否有效。我在Chrome版本83的多台设备上也遇到了同样的问题。我降低了chrome版本的等级,它在大多数设备上运行良好。但对于Android-11设备,chrome的默认版本是83,不能降级。您是否发现任何已报告的问题?没有发现任何问题,但找到了使用AccessibilityService获得更好结果的方法,我将发布一个答案。您是否找到解决此问题的方法?没有,目前唯一的“解决方案”是更改Chrome版本。我将尝试使用可访问性服务获取窗口转储,看看这种方法是否有效。我在Chrome版本83的多台设备上也遇到了同样的问题。我降低了chrome版本的等级,它在大多数设备上运行良好。但对于Android-11设备,chrome的默认版本是83,不能降级。您是否发现任何已经报告的问题?没有发现任何问题,但是找到了使用AccessibilityService获得更好结果的方法,我将发布一个答案。