【问题标题】:App crash with user downloaded from Google Play用户从 Google Play 下载的应用程序崩溃
【发布时间】:2019-06-24 16:20:16
【问题描述】:

我在 Google Play 上有一个下载量超过 45k 的应用。该应用程序有 3% 的用户存在错误,但无法在调试或发布模式下重现。非常难以复制。任何有此错误经验的人请帮助我。

崩溃日志

致命异常:java.lang.NullPointerException:尝试调用 虚拟方法 'void android.view.View.sendAccessibilityEvent(int)' on 空对象引用 在 android.view.ViewRootImpl$AccessibilityInteractionConnectionManager.onAccessibilityStateChanged(ViewRootImpl.java:7712) 在 android.view.accessibility.AccessibilityManager.lambda$-android_view_accessibility_AccessibilityManager_36305(AccessibilityManager.java:1007) 在 android.view.accessibility.-$Lambda$T3m_l9_RA18vCOcakSWp1lZCy5g$1.$m$0(未知 来源:6) 在 android.view.accessibility.-$Lambda$T3m_l9_RA18vCOcakSWp1lZCy5g$1.run(未知 资源) 在 android.os.Handler.handleCallback(Handler.java:789) 在 android.os.Handler.dispatchMessage(Handler.java:98) 在 android.os.Looper.loop(Looper.java:172) 在 android.app.ActivityThread.main(ActivityThread.java:6637) 在 java.lang.reflect.Method.invoke(Method.java) 在 com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

【问题讨论】:

    标签: android google-play


    【解决方案1】:

    Android 的一大优点是它是开源的,因此您可以自己解决这些问题。

    先看看报错信息:

    尝试在空对象引用上调用虚拟方法“void android.view.View.sendAccessibilityEvent(int)”

    这意味着在某处有一些代码在做foo.sendAccessibilityEvent(anInt) 但 foo 是null(即 AKA 空对象引用)。它甚至会告诉你这段代码在哪里:

    android.view.ViewRootImpl$AccessibilityInteractionConnectionManager.onAccessibilityStateChanged(ViewRootImpl.java:7712)

    接下来您需要做的是查找源代码。您可以在 Android Studio 或网络中执行此操作。我会用谷歌搜索"AccessibilityInteractionConnectionManager android source code"

    顶部链接将我带到the code。我在我的网络浏览器中搜索方法名称“onAccessibilityStateChanged()”,以防用户有旧手机并且线路号码已更改。

    代码如下所示:

    public void onAccessibilityStateChanged(boolean enabled) {
      if (enabled) {
        ensureConnection();
        if (mAttachInfo.mHasWindowFocus) {
          mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
          View focusedView = mView.findFocus();
          if (focusedView != null && focusedView != mView) {
            focusedView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
          }
    

    如您所见,focusedView 被检查为 null,但 mView 不是。

    如果我们在该文件中搜索 mview =,我们会发现它可能以 3 种方式发生:

    • 如果在对象被视图初始化之前可访问性状态发生变化。不幸的是,这看起来是可能的。我在代码中看不到任何原因,但它不会发生。
    • 在第 607 行中,如果在将窗口添加到显示器时发生 RemoteException。如果发生这种情况,您可能会在崩溃中看到“添加窗口失败”RuntimeEception。这可能不太可能
    • 在第 3186 行,如果 dispatchDetachedFromWindow 将mView 设置为 null。

    无论如何,3% 的用户正在使用 AccessibilityManager 并更改状态似乎很奇怪。您的应用程序是否有可能使用辅助功能来做不应该做的事情,这会导致崩溃。可能是速度较慢的手机上的用户在可访问性开始起作用之前没有正确初始化视图。您可以尝试停止使用 Accessibility API,看看这是否会有所改善。

    另一种可能性是不是您的应用在使用辅助功能,而是另一个应用试图操纵您的应用。您的应用是否属于用户可能会使用无障碍服务作弊的应用,例如奖励点击速度非常快的游戏?

    【讨论】:

      最近更新 更多