dim.red
View Hierarchy
背景
在脚本录制回放过程中, 我们需要获取 View Hierarchy 的意图有三个.
- 将 View Hierarchy 结合 App 截图 发送给前端. 前端用这两个做可视化显示.
- 在录制中.需要获取 View Hierarchy 遍历控件, 对控件进行监听.
- 在回放中. 需要根据 View Hierarchy 找到 回放操作 对应的控件.
实现方式
方式一: activity onResume
原理: ContentView 在 Activity 的onResume 里添加到屏幕上.
优点: 实现简单
缺点: 获取的视图不全面. 类似Dialog , PopWindow
在 实例1 中只能获取 Activity 层级, 领圣诞礼卷的对话框就获取不到了.
方式二: hook LayoutInflater
原理: res 的 layout 资源通过 LayoutInflater 解析成 View.
优点: 覆盖了所有从layout资源里面加载的控件
缺点: 系统兼容性问题, 能兼容 90% 以上的情况.
方式三: hook WindowManager
原理: 一个View 要显示在屏幕上, 都需要调用 WindowManager.add(XX) 方法.
优点: 覆盖了所有情况
缺点: 系统兼容性问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| try { Class<?> windowManagerGlobal = Class.forName("android.view.WindowManagerGlobal"); Object windowManagerGlobalInstance = on(windowManagerGlobal).call("getInstance").get(); Object mViewsObject = on(windowManagerGlobalInstance).field("mViews").get(); Object mParamsObject = on(windowManagerGlobalInstance).field("mParams").get(); ArrayList<View> mViews = (ArrayList<View>) mViewsObject; ArrayList<WindowManager.LayoutParams> mParams = (ArrayList<WindowManager.LayoutParams>) mParamsObject; ObserverArrayList<View> observerArrayList = createViews(); ObserverArrayList<WindowManager.LayoutParams> paramsObserverArrayList = createParams(); observerArrayList.addAll(mViews); paramsObserverArrayList.addAll(mParams); on(windowManagerGlobalInstance).set("mViews", observerArrayList); on(windowManagerGlobalInstance).set("mParams", paramsObserverArrayList); } catch (Exception e) { e.printStackTrace(); }
|