Android 7.0 and 7.1 getApplication() ClassCastException

我们两清 提交于 2019-11-29 01:50:40

问题


In Developer Console I see a lot of crashes with stacktrace like this

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)

getApp method of BaseActivity is

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

App class is

public class App extends MultiDexApplication { ...

and in manifest application tag contains reference to this class

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

98% of crashes is for android 7.0, rest is 7.1. No other android versions are affected.

EDIT: I use proguard so it can be somehow related but keeping class

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

Note: It may not be related but in same android versions it looks like App's onCreate method is sometimes not called. I observed it because some objects which are created in onCreate were null when they were accessed from Service (started by AlarmManager) or BroadcastReceiver

Does anyone has idea what can cause it, how to fix it or work around it? Thanks

EDIT 2: I ended up with something like this:

   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;
}

It at least doesn't crash and I can check getApp() == null


回答1:


Casting fails because getApplication() returns an Application and NOT the desired sub-class.

I've had some success where I caught the error and asked the user to reboot their device or reinstall the app.

Unfortunately, there's no real fix to this rare crash. Google won't fix the lifecycle-related issue, but said it reduced in Android 7.1+. Source: https://issuetracker.google.com/issues/37137009




回答2:


I think you should cast getApplicationContext() into App instead.




回答3:


You should override attachBaseContext in your application class like this:

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

Check this link for more information: https://developer.android.com/reference/android/support/multidex/MultiDexApplication.html




回答4:


This might help

public class App extends MultiDexApplication { 

        public static App app = null;

        public static App getInstance() {
            return app;
        }

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

you doesn't need to cast getApplication(), reason is you are already in Application class so simply just use this keyword to get application instance. Hope you find useful




回答5:


While I cannot say if this solution works.

I think that static Application instance should solve the problem.

class MyApp extends Application {
  private static final sInstance;

  public void onCreate() {
    sInstance = this;
  }

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

Instead of calling getActivity() if you call MyApp.getInstance() you should not need to cast. So there should not be any ClassCastException anymore.



来源:https://stackoverflow.com/questions/44840768/android-7-0-and-7-1-getapplication-classcastexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!