我有一个这样的应用程序类:
public class MyApplication extends Application {
}
它在 list 中注册:
<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 类来保存 Dagger 组件等。
现在我有一个 BroadcastReceiver:
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent){
MyApplication myApplication = (MyApplication) context.getApplicationContext();
}
}
它在 list 中注册为 InstallReferrerReceiver :
<receiver
android:name="my.package.MyReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER"/>
</intent-filter>
</receiver>
如您所见,我将应用程序上下文转换为我的 Application 类,它在 Activities 等中工作正常,通常也在这里。
虽然我收到异常,但通过 Crashlytics:
Unable to start receiver my.package.BroadcastReceiver: java.lang.ClassCastException: android.app.Application cannot be cast to my.package.MyApplication
我的问题是:我是否不保证接收我的 Application 对象作为 BroadcastReceiver 中的应用程序上下文?
最佳答案
如果查看 ActivityThread.handleReceiver 的实现,您会发现通过将 ContextImpl.getReceiverRestrictedContext() 传递给它来调用 BroadcastReceiver.onReceived。此调用返回的上下文实际上并未包装 getApplicationContext,因此将在 ContextImpl 上调用 ti。现在,如果您查看 ContextImpl.getApplicationContext(),您会看到类似这样的内容
@Override
public Context getApplicationContext() {
return (mPackageInfo != null) ? mPackageInfo.getApplication() :
mMainThread.getApplication();
}
如果您查看三元运算符的最后一个分支,您会发现它将回调到 ActivityThread.getApplication()
,这将返回它的 mInitialApplication
成员。 mInitialApplication
通过调用 LoadedApk.makeApplication()
进行初始化,它有一个 bool 参数:forceDefaultAppClass
。如果设置为 true android.app.Application
将实例化您的 list 中定义的应用程序。
根据 AOSP 来源,这种情况发生在例如:
If the app is being launched for full backup or restore, bring it up in a restricted environment with the base application class.
关于android - BroadcastReceiver 中的 ApplicationContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41061272/