如何从广播接收器引用应用程序上下文

时间:2012-04-07 10:15:16

标签: android

我正在使用扩展Application的常用技术来存储全局常量。

所以在我的活动中,我可以简单地做(在​​oncreate()中):

W = (WcmApplication) getApplicationContext();

但是,这对广播接收器不起作用:

The method getApplicationContext() is undefined for the type MyReceiver

所以,我以为我很聪明,我试着这样做:

 W = (WcmApplication) context;

...但是在运行时抛出错误,说我的广播接收器不允许访问该上下文

不要放弃,我试试这个:

W = (WcmApplication) Context.getApplicationContext();

...没有骰子

所以我最终不得不这样做:

W = (WcmApplication)context.getApplicationContext() ;

......这很好用,但我不明白为什么。

有人可以解释为什么有人工作而不是其他工作?

谢谢!

3 个答案:

答案 0 :(得分:2)

Activity继承Context,因此您可以直接访问getApplicationContext()上定义的Context方法。另一方面,BroadcastReceiver不会从Context继承,这就是为什么它在调用处理广播时必须从外部接收context

通常,您可以从任何组件(ContextActivityServiceContentProvider)访问的直接BroadcastReceiver是该特定组件并定义该组件执行的 context (因此名称:-))。另一方面,应用程序上下文为整个应用程序定义了更通用的上下文。因此,应用程序 context 比组件 context 更广泛。

请记住,在任何时间点都可以链接超过这两个上下文(应用程序和组件)。您可以通过尝试将每个节点(从组件 context 开始)转换为ContextWrapper并且如果成功使用getBaseContext来部分地遍历上下文链。但是,这是一种罕见的高级方案,并且大多数情况下,您关注的链中只有两个上下文 - 即时组件1和总体应用程序。

答案 1 :(得分:0)

我认为我有一个全面的解决方案(最终感谢@Franci Penov'帖子

这是我的自定义Application子类的静态方法。

public static MyApp get( @NonNull final Context context )
{
    if( s_instance != null )
    {
        return s_instance;
    }
    else
    {
        if( context instanceof Activity )
        {
            final Activity activity = (Activity) context;
            s_instance = (MyApp) activity.getApplication();
        }
        else if( context instanceof Service )
        {
            final Service service = (Service) context;
            s_instance = (MyApp) service.getApplication();
        }
        else if( context instanceof ContextWrapper )
        {
            final ContextWrapper contextWrapper = (ContextWrapper) context;
            s_instance = (MyApp) contextWrapper.getBaseContext().getApplicationContext();
        }
        else
        {
            s_instance = (MyApp) context.getApplicationContext();
        }

        return s_instance;
    }
}

答案 2 :(得分:-1)

这不是应用程序上下文:

(WcmApplication) context;

而是行动的背景。这就是你需要打电话的原因:

(WcmApplication)context.getApplicationContext() ;