26

This might be a simple question but I just wanted to make sure I am right.

In my android application I have a constructor that uses:

activity.getApplicationContext()

The activity is passed into the constructor as a parameter.

The problem is that I am calling this class from a Service. If I make a second constructor which accepts the Service as a parameter and uses service.getApplicationContext? Will I get the same application context?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
gtdevel
  • 1,513
  • 6
  • 21
  • 38
  • I have a very similar question - I have an app that has more than one process. There is a library that needs a class loader but is not itself an application but used in applications. It may be in more than one process in the application. Is there a way to get the current processes context from a library using some global object accessable in any process from a library so I can call context.getClassLoader()? – peterk Aug 28 '15 at 23:08

6 Answers6

57

The easiest way to get the application context is:

Create a class App that extends android.app.Application

public class App extends Application {
    public static Context context;

    @Override public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
    }
}

Modify your AndroidManifest.xml 's <application> tag to have the attribute android:name="your.package.name.App".

Any time you need the application context, just get it from App.context.

Application is always initialized first whether your process runs, whether it's an activity, a service, or something else. You will always have access to the application context.

Randy Sugianto 'Yuku'
  • 71,383
  • 57
  • 178
  • 228
  • 5
    I saw the exact same approach somewhere and I'm using it to make application context accessible throughout my whole application. But I was not sure, is it the best practice to achieve this? Why accessing the context of application is not supplied as a built-in feature in android SDK? – Alireza Mirian Jul 18 '13 at 11:41
  • @AlirezaMirian it is supported. By getApplicationContext() on Context objects. However we have to pass the Context object everywhere. – Randy Sugianto 'Yuku' Apr 09 '14 at 05:31
  • 1
    getApplicationContext as you said is a method of `Context` class or its sub-classes. But assume you are creating a class that overrides `AsyncTask` to do some stuff in your application. And you wanna manipulate the UI in `onPostExecute` for example. Anyway, I think life would be more easier if `getApplicationContext` were static. – Alireza Mirian Apr 09 '14 at 08:55
  • 1
    I feel like this should be the accepted answer. Clean & elegant! – AlexVPerl Jan 08 '15 at 23:42
  • The reason this probably isn't provided is because it can introduce static initialization order issues. Namely, some static initializer could try to access `App.context`, but it would be null. I suppose the framework designers decided this was bad form. – Colin Basnett Aug 05 '15 at 19:20
  • 10
    Android Studio gives this warning for this code - `Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run) ` . Is this really the best way to implement global context variable? – Neo Dec 20 '16 at 17:43
  • 3
    this is a memory leak – Logan Guo Jan 24 '17 at 06:40
  • This approach is not encouraged because it provides an inconsistent manner to retrieve the context. If you're following an examplelike @AlirezaMirian's, I would suggest to refer the context that calls the `AsyncTask`. If it's called in, let's say, `RandomActivity`, use `RandomActivity.this.getApplicationContext()`. – Gabriel Vasconcelos Mar 02 '17 at 22:54
  • 3
    Application is not initialized first, Content Providers are initialized before it. – BladeCoder Oct 03 '17 at 03:25
12

Will I get the same application context?

Yes. You can check the android documentation, they have provided

 getApplicationContext()

Return the context of the single, global Application object of the current process.

So it should not be changed for the whole application process.

Please also take a note of this:

getApplicationContext() generally should only be used if you need a Context whose lifecycle is separate from the current context, that is tied to the lifetime of the process rather than the current component.

Correct me if I'm wrong.

Thanks

Swati Bhartiya
  • 101
  • 1
  • 8
bHaRaTh
  • 3,464
  • 4
  • 34
  • 32
2

There is only one application context, so you should get the same one. You can have just one constructor that takes a Context, you don't really need two. Or if you wanted to make sure that you are getting the application context, and not, say, an activity one, you can have your constructor take Application as a parameter which is a Context.

Nikolay Elenkov
  • 52,576
  • 10
  • 84
  • 84
1

I have adapted yuku's answer with a non static direct context reference.

Create a class domain.company.pseudo.ApplicationName which extends android.app.Application.

package hypersoft.systems.android;

import android.app.Application;

public class Starbox extends Application {

  public static Starbox instance;

  @Override
  public void onCreate() {
    super.onCreate();
    instance = this;
  }

}

In this sample, my full application package name is hypersoft.systems.android.starbox.

Now, modify your AndroidManifest.xml <application> tag to have the attribute android:name="hypersoft.systems.android.Starbox", and be sure the Starbox.java class file is located in the project component directory: android rather than starbox.

With all this done, you can now import hypersoft.systems.android.Starbox, and in your code you can get the ApplicationContext by calling Starbox.instance.getApplicationContext()

Successfully compiling with build tools 26 and api 26 (Android 8.0) with min sdk version 14 (4.0).

  • Id be interested as to which approach is the better practice here. Because I cant see an upside to reveal the whole application object to the whole project when all one needs and uses is the context. Considering that use-case, is it necessary or better to still provide the whole application object instead just the component or function that is needed/used? – Benjamin Basmaci Aug 11 '21 at 11:43
1

You can go for getApplicationContext() if you wanna get context of whole application. If you want to get context of current class you can use getBaseContext() instead.

Arun
  • 613
  • 1
  • 7
  • 14
Android Killer
  • 18,174
  • 13
  • 67
  • 90
-2

Application Context add Activity Context both are different.Downcasting is risky .Use this code to use context object .

public class App extends Application {
public static Context context;

    @Override public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
    }
} 

In Your Activities and in fragments Class :

Conetext context=App.context;

Tenaciousd93
  • 3,438
  • 4
  • 33
  • 56
Ashish Saini
  • 2,328
  • 25
  • 21