2016-12-09 8 views
2

でのApplicationContext:それはマニフェストに登録されている私はこのようなアプリケーションのクラスを持っているBroadcastReceiver

public class MyApplication extends Application { 
} 

<application 
     android:name=".MyApplication" 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 
    ... 

    </application> 

私はダガーコンポーネントなどを維持するために、このApplicationクラスを使用

今私はBroadcastReceiverを持っています:

public class MyBroadcastReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(final Context context, final Intent intent){ 

     MyApplication myApplication = (MyApplication) context.getApplicationContext();   
    } 
} 

は、それはInstallReferrerReceiverとしてマニフェストに登録されています

<receiver 
     android:name="my.package.MyReceiver" 
     android:exported="true"> 
     <intent-filter> 
      <action android:name="com.android.vending.INSTALL_REFERRER"/> 
     </intent-filter> 
    </receiver> 

あなたは、私は通常、ここにも活動などで正常に動作し、私のアプリケーションクラスにアプリケーション・コンテキストをキャスト見ることができるように。

経由Crashlytics私は例外を受け取るのに:

Unable to start receiver my.package.BroadcastReceiver: java.lang.ClassCastException: android.app.Application cannot be cast to my.package.MyApplication 

私の質問のビーイング:私ははBroadcastReceiverのアプリケーションコンテキストとしての私のApplicationオブジェクトを受け取るために保証されませんのですか?

+0

正常に動作するはずです。このクラッシュを報告しているデバイス間に共通点はありますか?また、 ' '要素(例えば、あなたは' android:process'を使用しています)やブロードキャストの送信方法については珍しいことがありますか? – CommonsWare

+1

私は、あなたの 'BroadcastReceiver'(私はソースを探しています)であなたのアプリケーションにアクセスすることが保証されていないと思います。 'if(context.getApplicationContext()instanceof MyApplication)'をチェックできますか? –

+0

@CommonsWare申し訳ありませんが、それはおそらく追加することが重要だった、私は受信者のマニフェストエントリを追加しました。 – FWeigl

答えて

1

ActivityThread.handleReceiverの実装を見ると、ContextImpl.getReceiverRestrictedContext()を渡すことでBroadcastReceiver.onReceivedが呼び出されることがわかります。この呼び出しによって返されたコンテキストは実際にgetApplicationContextをラップしないため、ContextImplでtiが呼び出されます。あなたはContextImpl.getApplicationContext()を見れば、あなたは三項演算子の最後の枝を見れば今、あなたはあなたがそれだ返されることがActivityThread.getApplication()にコールバックすることがわかります。この

@Override 
public Context getApplicationContext() { 
    return (mPackageInfo != null) ? mPackageInfo.getApplication() : 
     mMainThread.getApplication(); 
} 

のようなものが表示されますmInitialApplicationメンバー。 mInitialApplicationは、LoadedApk.makeApplication()を呼び出すことによって初期化され、ブール値パラメータ:forceDefaultAppClassを持ちます。 trueに設定されている場合、android.app.Applicationはマニフェストで定義されたアプリケーションをインスタンス化します。

AOSPソースに基づいて、これは例えばのためにとどうなる:

アプリはフルバックアップのために立ち上げや復元、基本アプリケーションクラスに制限された環境での それを持ち出すされている場合。

関連する問題