web-dev-qa-db-ja.com

Android 7.0および7.1getApplication()ClassCastException

開発者コンソールでは、このようなスタックトレースで多くのクラッシュが発生します

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です。他のAndroidバージョンは影響を受けません。

編集:私はproguardを使用しているので、何らかの形で関連している可能性がありますが、クラスを維持しています

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

注:関連していない可能性がありますが、同じAndroidバージョンでは、アプリのonCreateメソッドが呼び出されないことがあるようです。onCreateで作成された一部のオブジェクトがからアクセスされたときにnullであったため、観察しました。サービス(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を確認できます

25
vandzi

getApplication()Applicationを返し、目的のサブクラスではないため、キャストは失敗します。

エラーを見つけて、ユーザーにデバイスを再起動するか、アプリを再インストールするように依頼したところ、ある程度の成功を収めました。

残念ながら、このまれなクラッシュに対する実際の修正はありません。 Googleはライフサイクル関連の問題を修正しませんが、Android 7.1+。出典: https://issuetracker.google.com/issues/37137009 ==

12
Jsyntax

代わりにgetApplicationContext()Appにキャストする必要があると思います。

2
Tuby

これは役立つかもしれません

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クラスにいるため、このキーワードを使用してアプリケーションインスタンスを取得するだけです。お役に立てば幸いです

0
Piyush Patel

この解決策が機能するかどうかはわかりませんが。

静的アプリケーションインスタンスで問題が解決するはずだと思います。

_class MyApp extends Application {
  private static final sInstance;

  public void onCreate() {
    sInstance = this;
  }

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

getActivity()を呼び出す場合は、MyApp.getInstance()を呼び出す代わりに、キャストする必要はありません。したがって、ClassCastExceptionはもう存在しないはずです。

0
Ioane Sharvadze

次のように、アプリケーションクラスのattachBaseContextをオーバーライドする必要があります。

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

詳細については、次のリンクを確認してください: https://developer.Android.com/reference/Android/support/multidex/MultiDexApplication.html

0
Vincent