8月 242016
 

app上线前遇到一个很诡异的问题,同一款型号的手机,一台手机没问题,另一台手机则在显示首页后假死、然后直接闪退。经过排查,确定是自定义GridView惹的祸,异常信息如下:

 java.lang.IllegalArgumentException: parameter must be a descendant of this view
 at android.view.ViewGroup.offsetRectBetweenParentAndChild(ViewGroup.java:5353)
 at android.view.ViewGroup.offsetDescendantRectToMyCoords(ViewGroup.java:5282)
 at android.view.ViewGroup$ViewLocationHolder.init(ViewGroup.java:7755)
 at android.view.ViewGroup$ViewLocationHolder.obtain(ViewGroup.java:7689)
 at android.view.ViewGroup$ChildListForAccessibility.init(ViewGroup.java:7624)
 at android.view.ViewGroup$ChildListForAccessibility.obtain(ViewGroup.java:7592)
 at android.view.ViewGroup.addChildrenForAccessibility(ViewGroup.java:1927)
 at android.view.ViewGroup.onInitializeAccessibilityNodeInfoInternal(ViewGroup.java:2982)
 at android.widget.AdapterView.onInitializeAccessibilityNodeInfoInternal(AdapterView.java:983)
 at android.widget.AbsListView.onInitializeAccessibilityNodeInfoInternal(AbsListView.java:1509)
 at android.widget.GridView.onInitializeAccessibilityNodeInfoInternal(GridView.java:2361)
 at android.view.View.onInitializeAccessibilityNodeInfo(View.java:6151)
 at android.view.View.createAccessibilityNodeInfoInternal(View.java:6110)
 at android.view.View.createAccessibilityNodeInfo(View.java:6095)
 at android.view.accessibility.AccessibilityRecord.setSource(AccessibilityRecord.java:145)
 at android.view.accessibility.AccessibilityRecord.setSource(AccessibilityRecord.java:119)
 at android.view.View.onInitializeAccessibilityEventInternal(View.java:6047)
 at android.widget.AdapterView.onInitializeAccessibilityEventInternal(AdapterView.java:994)
 at android.view.View.onInitializeAccessibilityEvent(View.java:6035)
 at android.view.View.sendAccessibilityEventUncheckedInternal(View.java:5896)
 at android.view.View.sendAccessibilityEventUnchecked(View.java:5881)
 at android.view.View$SendViewStateChangedAccessibilityEvent.run(View.java:22468)
 at android.os.Handler.handleCallback(Handler.java:743)
 at android.os.Handler.dispatchMessage(Handler.java:95)
 at android.os.Looper.loop(Looper.java:150)
 at android.app.ActivityThread.main(ActivityThread.java:5546)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)


直接在网上搜这个异常信息,会出来类似的问题,比如这个帖子,这些帖子给出的异常信息相似,最后给出的解决方案也类似,都是说焦点问题,只要调用clearFocus就可以了(这个清楚焦点的操作可以在多个地方进行),但我都试过,发现这些方法都没法解决我遇到的问题。后来通过同事试用app反馈,发现只要打开android系统的辅助功能(android accessibility 比如开关控制、放大手势之类的,不同手机菜单名可能不一样,比如MIUI中是在“无障碍”中的那些功能),就会出现这个问题。然后重新搜,发现是“检测窗口内容(检查您正与其他互动的窗口的内容)”这个功能导致的,在React项目也存在该问题,参考如下链接 传送门  以我的使用场景为例,在我修改GridView后,添加view似乎并不是像其他控件那样,把新添加的View加到整个ViewTree中,而使用辅助功能时,需要从ViewTree的根遍历到所有叶子View,到GridView这一层没法往下走,才导致了上述问题。实际上,看异常也可以看到是在涉及accessibility相关方法时出错,所以只要在GridView中添加如下代码即可解决:

 @Override
 public void addChildrenForAccessibility(ArrayList<View> outChildren) {
 // Explicitly override this to prevent accessibility events being passed down to children
 // Those will be handled by the mHostView which lives in the dialog
 }

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)