有时候有些View是第三方的或者其他sdk的,显示在我们自己应用界面上,拿不到对象,这时可以通过如下方法。
/**
* 获取界面中的所有View
*/
private fun hookView() {
Handler().post {
val wmGlobalClass = Class.forName("android.view.WindowManagerGlobal")
//获取mView字段
val viewsField = wmGlobalClass.getDeclaredField("mViews")
viewsField?.isAccessible = true
//获取getInstance方法
val getInstanceMethod = wmGlobalClass.getDeclaredMethod("getInstance")
//调用getInstance方法获取Window
val wmGlobalInstance = getInstanceMethod.invoke(null)
//获取当前屏幕上的View列表
val views = viewsField.get(wmGlobalInstance) as? ArrayList<View>
val size = views?.size ?: 0
for (i in 0..size) {
// 假设某个条件满足时退出循环
val targetView = getTargetView(getDecorView(views?.get(i))) ?: break
Log.d("tanyl", "targetView =$targetView")
}
}
}
第二种就是需要获取界面的某个View,我们可以抓布局知道id。
/**
* 从View列表里面中获取DecorView
*/
private fun getDecorView(view: View?): View? {
if (view == null) {
return null
}
if (view.javaClass.simpleName.startsWith("DecorView")) {
return view
}
return null
}
/**
* 获取目标View targetView
*/
private fun getTargetView(view: View?): View? {
val targetView = view?.findViewById<View>(R.id.button)
if (targetView?.id == R.id.button) {
return targetView
}
return null
}
运行结果: