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

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>

我使用这个应用程序类来保存匕首组件等。
现在我有一个广播接收器:
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

我的问题是:我是否不能保证在广播接收器中将应用程序对象作为应用程序上下文接收?

最佳答案

如果查看activitythread.handlereceiver的实现,您将看到broadcastReceiver.onReceived是通过向其传递contextImpl.getReceiverRestrictedContext()来调用的。此调用返回的上下文实际上没有包装getapplicationcontext,因此将在contextimpl上调用ti。现在,如果查看contextimpl.getapplicationcontext(),您将看到如下内容

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

如果您查看三元运算符的最后一个分支,您将看到它将回调到ActivityThread.getApplication(),这将返回它的mInitialApplication成员。mInitialApplication通过调用具有布尔参数的LoadedApk.makeApplication()来初始化。如果设置为true,则将实例化清单中定义的应用程序。
根据AOSP来源,当发生以下情况时会发生这种情况:
如果要启动应用程序进行完全备份或还原,请将其启动
在具有基本应用程序类的受限环境中。

关于android - BroadcastReceiver中的ApplicationContext,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41061272/

10-10 08:21