Android实现private/final类继承
发布网友
发布时间:2024-09-28 21:09
我来回答
共1个回答
热心网友
时间:2024-10-25 19:26
在最近的项目中,为了实现Android Accessibility功能,我们需要在后台获取当前前台页面的节点,即AccessibilityNodeInfo。Android系统通过AccessibilityService中的“List getWindows()”方法获取当前屏幕的所有window列表,再通过每个AccessibilityWindowInfo的“AccessibilityNodeInfo getRoot()”获取每个window对应的布局根节点。
然而,对接方的接口只能传递一个AccessibilityNodeInfo节点,很多时候,又无法确认对接方需要的window究竟是哪一个。因此,我们需要创建一个AccessibilityNodeInfo的子类,命名为FakeAccessibilityNodeInfo,将获取的所有window列表的根节点都设置为FakeAccessibilityNodeInfo的子节点,这样就不会丢失需要查找的节点。
但是,直接创建FakeAccessibilityNodeInfo继承系统的AccessibilityNodeInfo类时,app会崩溃,报错信息显示在创建FakeAccessibilityNodeInfo对象时,构造函数中触发父类构造函数,但父类AccessibilityNodeInfo的构造函数对于子类FakeAccessibilityNodeInfo是不可访问的。
经过排查,我们发现该问题并非在所有机型上都存在,目前发现该问题的机型为一台三星A21,怀疑与Android系统版本有关。检查后发现测试过的手机中,仅有该测试机为Android10。通过查阅所有Android 6~14版本的代码发现,AccessibilityNodeInfo的构造函数,是在Android11开始开放给开发者的,之前的所有版本都是private方法且被标识为@hide,不开放给开发者。
为了解决这个问题,我们尝试了多种方法,包括在FakeAccessibilityNodeInfo构造方法中不调用父类AccessibilityNodeInfo构造方法、反射父类AccessibilityNodeInfo的构造方法等,但都失败了。最后,我们通过修改Java方法对应在C/C++层的ArtMethod的access_flags_来实现继承private类型的类。