2

I'm using the usual technique of extending Application in order to store global constants.

So within my activities, I can simply do (in oncreate()):

W = (WcmApplication) getApplicationContext();

However, this doesn't work for broadcast receivers:

The method getApplicationContext() is undefined for the type MyReceiver

So, thinking I was being clever, I tried to do:

 W = (WcmApplication) context;

... but that throws an error at runtime saying my broadcast receiver is not allowed to access that context

Not giving up, I try this:

W = (WcmApplication) Context.getApplicationContext();

... no dice

So I ended up having to do:

W = (WcmApplication)context.getApplicationContext() ;

... and that works nicely, however I have no idea why.

Can someone explain why one works and not the others?

Thank you!

Stephan Tual
  • 2,617
  • 3
  • 27
  • 49

3 Answers3

2

Activity inherits Context, hence you have direct access to the getApplicationContext() method defined on Context. BroadcastReceiver on the other hand does not inherit from Context, which is why it has to receive the context from outside, when invoked to process a broadcast.

In general, the direct Context you have access to from any component (Activity, Service, ContentProvider, or BroadcastReceiver) is a specific for that particular component and defines the context of execution of that component (hence the name :-)). The application context on the other hand defines a more generic context of execution for the whole application. So, the application context is a broader than the component context.

Keep also in mind that it is possible to have more than these two contexts (application and component) chained up at any point in time. You could walk the chain of contexts partially by attempting to cast each node (starting from the component context) to ContextWrapper and if successful use getBaseContext. However, this is a rare advanced scenario, and most times there are only two contexts in the chain that you care - the immediate component one, and the overarching application one.

Franci Penov
  • 74,861
  • 18
  • 132
  • 169
0

I think I have a comprehensive solution (finally thanks to @Franci Penov's post)

This is a static method on my custom Application subclass.

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;
    }
}
Adam
  • 25,966
  • 23
  • 76
  • 87
-1

This is not application context:

(WcmApplication) context;

but rather context of an action. This is why you need to call:

(WcmApplication)context.getApplicationContext() ;
Marko Kotar
  • 449
  • 4
  • 5