android - BroadcastReceiver 中的 ApplicationContext

标签 android broadcastreceiver android-context

我有一个这样的应用程序类:

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/

相关文章:

android - flutter 中一个屏幕上有两个 TabBar

android - BroadcastReceiver 所需的帮助

Android:将变量从 Activity 传递到 BroadcastReceiver

android - 在 Presenter 类中访问 Actvity 的上下文是一种好习惯吗?如果没有,那么还有其他更好的方法吗?

java - 将“设置” Activity 连接到“Activity 2”后,我的应用程序崩溃了

android - Cordova NFC 插件 : nfc has no method 'connect' 出现问题

Android更新应用跨应用重启使用DownloadManager(避免多次下载)

android - 从资源 id 整数获取颜色给出错误

java - 可以在具有相同sharedUserId的应用程序之间共享strings.xml吗?

java - 如何为 android 3D 游戏框架创建更新方法?