【问题标题】:Android 7.0 and 7.1 getApplication() ClassCastExceptionAndroid 7.0 和 7.1 getApplication() ClassCastException
【发布时间】:2017-06-30 07:18:40
【问题描述】:

在开发者控制台中,我看到很多这样的堆栈跟踪崩溃

java.lang.RuntimeException: 
  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2984)
  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3045)
  at android.app.ActivityThread.-wrap14(ActivityThread.java:0)
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1642)
  at android.os.Handler.dispatchMessage(Handler.java:102)
  at android.os.Looper.loop(Looper.java:154)
  at android.app.ActivityThread.main(ActivityThread.java:6776)
  at java.lang.reflect.Method.invoke(Native Method:0)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
Caused by: java.lang.ClassCastException: 
  at com.myapp.ui.BaseActivity.getApp(BaseActivity.java:193)
  at com.myapp.ui.BaseActivity.onCreate(BaseActivity.java:275)
  at com.myapp.ui.CastActivity.onCreate(CastActivity.java:39)
  at com.myapp.ui.MainActivity.onCreate(MainActivity.java:268)
  at android.app.Activity.performCreate(Activity.java:6955)
  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126)
  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2927)

BaseActivity的getApp方法是

public App getApp() {
        return (App) getApplication();
    }

应用类是

public class App extends MultiDexApplication { ...

并且在清单应用程序标记中包含对此类的引用

 <application
        android:name="com.myapp.App"

98% 的崩溃是针对 android 7.0,其余的是 7.1。其他安卓版本不受影响。

编辑:我使用 proguard,所以它可以以某种方式相关但保持类

-keep class com.myapp.** { *;}
-keep interface com.myapp.** { *;}

注意:它可能不相关,但在相同的 android 版本中,看起来 App 的 onCreate 方法有时不会被调用。我观察到它是因为在 onCreate 中创建的某些对象在从 Service(由 AlarmManager 启动)或 BroadcastReceiver 访问时为空

有谁知道是什么原因造成的,如何解决或解决它?谢谢

编辑 2: 我最终得到了这样的结果:

   public App getApp() {

    Application application = getApplication();
    App app = null;

    try {
        app = (App) application;
    } catch (Exception e) {
        if (application != null) {
            Log.e(TAG, "getApp Exception: application class: " + application.getClass().getName());
        } else {
            Log.e(TAG, "getApp Exception: application object is null");
        }
    }

    return app;
}

它至少不会崩溃,我可以检查 getApp() == null

【问题讨论】:

  • 您好,您找到解决方案了吗?
  • @user5599807 很遗憾没有
  • 这种崩溃有多常见?总是有特定于供应商/ROM的奇怪的罕见崩溃。
  • 我在 Android 8.0 和 8.1 上也看到了问题。

标签: android android-7.0-nougat android-application-class


【解决方案1】:

转换失败,因为 getApplication() 返回 Application 而不是所需的子类。

我在发现错误并要求用户重新启动设备或重新安装应用程序方面取得了一些成功。

很遗憾,这种罕见的崩溃并没有真正的解决方法。谷歌不会修复与生命周期相关的问题,但表示它在 Android 7.1+ 中有所减少。来源:https://issuetracker.google.com/issues/37137009

【讨论】:

【解决方案2】:

我认为您应该改为将 getApplicationContext() 转换为 App。

【讨论】:

  • 您能解释一下为什么它会有所帮助吗?
  • 这是另一种选择,有时在为 android 编程时,我体验到像这样的微小更改可以摆脱异常。
  • 问题是在某些情况下它可能不会返回应用程序对象(即android的供应商实现)stackoverflow.com/questions/5018545/…
【解决方案3】:

您应该像这样在应用程序类中覆盖 attachBaseContext:

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    MultiDex.install(this);
}

查看此链接了解更多信息:https://developer.android.com/reference/android/support/multidex/MultiDexApplication.html

【讨论】:

  • 我不必这样做,因为它已经在 MultiDexApplication 中完成了。在您分享的链接中,它说您可以扩展 MultiDexApplication 或覆盖 attachBaseContext
  • @vandzi 你能在创建时发布你的应用类吗
  • 只有 super.onCreate(); 没有什么有用的。分析初始化。我认为问题出在其他地方
  • 我重新创建了你的实现,它在我的 android 7.0 上运行,它认为它在其他地方
  • 它并不总是崩溃。它仅针对某些设备/用户崩溃,并且可能是随机崩溃的。
【解决方案4】:

这可能会有所帮助

public class App extends MultiDexApplication { 

        public static App app = null;

        public static App getInstance() {
            return app;
        }

        @Override
        public void onCreate() {
            super.onCreate();
            app = this;
        }
}

您不需要强制转换 getApplication(),原因是您已经在 Application 类中,因此只需使用此关键字即可获取应用程序实例。希望对你有用

【讨论】:

  • getApp 处于活动状态,所以我必须投射它
  • 虽然你不需要在你的活动中使用 getApplicationContext()
  • developer.android.com/reference/android/content/Context.htmlgetApplicationContext() 返回当前进程的单个全局应用程序对象的上下文。
  • 我不想获取上下文。我想获取 App 实例。
  • 我已经回答过了。您需要阅读上述声明。全局 Application 对象(即 App 实例)
【解决方案5】:

虽然我不能说这个解决方案是否有效。

我认为静态应用程序实例应该可以解决问题。

class MyApp extends Application {
  private static final sInstance;

  public void onCreate() {
    sInstance = this;
  }

  public static MyApp getInstance() {
    return sInstance;
  }
}

如果你调用MyApp.getInstance(),而不是调用getActivity(),你不应该需要转换。所以不应该有任何ClassCastException 了。

【讨论】:

    猜你喜欢
    • 2015-05-25
    • 1970-01-01
    • 1970-01-01
    • 2018-11-10
    • 2018-07-31
    • 2011-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多