Is it possible to get application's context in an Android Library Project?

30,963

Solution 1

Is it possible?

Yes.

If yes, how?

Pass it in as a parameter.

I don't want my user to pass context in parameter to my library project because it is possible that my library project will be called through JNI and I have no idea how I can get context in JNI and pass it to Java layer.

Then figure out "how [you] can get context in JNI and pass it to Java layer". I would imagine that you would pass it like any other object. As @Blundell noted, you do not really have any other option.

Solution 2

There is one more way, add application class in your library project:

/**
 * Base class for those who need to maintain global application state.
 */
public class LibApp extends Application {

  /** Instance of the current application. */
  private static LibApp instance;

  /**
   * Constructor.
   */
  public LibApp() {
    instance = this;
  }

  /**
   * Gets the application context.
   * 
   * @return the application context
   */
  public static Context getContext() {
    return instance;
  }

}

Then in your regular project make the real application class extend LibApp:

/**
 * Base class for those who need to maintain global application state.
 */
public class App extends LibApp {

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

}

Make sure that you have "Name" defined in AndroidManifest:

<application android:name="App" ...>

and that your App class is in the base package.

You can then use LibApp.getContext() your library project to get the application context of the application that is using the library.

This may not be good solution but it works for me. I am sharing it because it might be useful to somebody else.

Solution 3

There's another way to get context in jni, neither passing a parameter nor saving context by yourself, but by using android api. I found that there's a class named:

  • android.app.AppGlobals

in the source code. And the static function

  • getInitialApplication

    can return an Application object. But it must be called in main thread, and the class is hidden. Anyway you can use it by reflecting in java. And you can just use FindClass() and FindStaticObjectMethod() to find out the method, and use it. Hope that helps.

Solution 4

I would pass it as a parameter or pass it a singleton in that library.

Having the main app application extend the library's application class is a bad idea coz in java you can only extend once from a class. If your application requires to pass to another library you will be in trouble.

Solution 5

According to this post you can let the library auto-initialize itself with the application context by the aid of a ContentProvider.

Be careful anyway, as described in the post comments, there may be drawbacks concerning loading time and instant run, as well as crashes on multi-process apps.

HTH

Share:
30,963
Haris Hasan
Author by

Haris Hasan

https://www.linkedin.com/pub/haris-hasan/10/98a/391

Updated on July 18, 2020

Comments

  • Haris Hasan
    Haris Hasan almost 4 years

    I would like to get the context of application which has reference/hosted my library at run-time inside one class of my library project. Is it possible? If yes, how?

    Thanks

    Update I don't want my user to pass context in parameter to my library project because it is possible that my library project will be called through JNI and I have no idea how I can get context in JNI and pass it to Java layer.

    • WarrenFaith
      WarrenFaith almost 13 years
      getApplicationContext()?
    • Aracem
      Aracem almost 13 years
      If u use your library inside other project the context of your library will be the context of the project. What do you want to do with the context?
    • Haris Hasan
      Haris Hasan almost 13 years
      @WarrenFaith: no such method is available inside my android library project
    • Haris Hasan
      Haris Hasan almost 13 years
      @Aracem: I need Context inside library project to perform certain operations but I don't want to ask user to pass context explicitly in some parameter. How can I independently get the current application's context inside my library?
    • Aracem
      Aracem almost 13 years
      the current? with getApplicationContext, even with "this" (if you are in a class extends Activity) The context is allways independent of your libraries.
    • Haris Hasan
      Haris Hasan almost 13 years
      No my class don't extend activity it is a simple plain class
    • ingsaurabh
      ingsaurabh almost 13 years
    • Blundell
      Blundell almost 13 years
      @Haris if you class is a plain class, you NEED to explicitly pass the context in.
  • Haris Hasan
    Haris Hasan almost 13 years
    :) so in short it is not possible to get application context independently in an android library project
  • Blundell
    Blundell almost 13 years
    Yes it is possible, for a class extending application or activity. No not possible independently for any plain Java class including those in a normal Android project or a library project. you would have to pass it as a parameter, as we keep saying
  • Dani bISHOP
    Dani bISHOP over 12 years
    Hi! Sorry, but I think this answer goes to a different point. What @Haris-Hasan wants is to have access to a class outside a library from inside the library. Maybe a method in the library wants access to the resources of a inherited class or something like that. Anyway, your answer is a good answer for singleton :P
  • peceps
    peceps over 12 years
    He said: "I would like to get the context of application which has reference/hosted my library at run-time inside one class of my library project. Is it possible? If yes, how?" This code does exactly that, gives access to the context of the application that is using the library.
  • Dani bISHOP
    Dani bISHOP over 12 years
    It's a matter of interpretation, I suppose. I have the same code that you have posted in my own library, and it solves the question... if you can define your classes from your library. I think Haris-Hasan wants to access 'anything' from inside the library. Anyway, the easiest way (if accesible) is your answer, @peceps. A generic answer would imply reflection, maybe?
  • Maxrunner
    Maxrunner almost 12 years
    Sorry to bump this, but does the app class need to be in the base package?
  • Maxrunner
    Maxrunner almost 12 years
    Are you sure? my app equivalent is in another package and it seems to be working. Also how would you call the App instance from a fragment for example? i'm trying to avoid using the getActivity().getApplicationContext(), since it seems to give potential leaks.
  • Dr.jacky
    Dr.jacky about 9 years
    @peceps Can i write something like this: public static LibApp getInstance() { return instance; }
  • Dr.jacky
    Dr.jacky about 9 years
    @peceps I'm doing some stuff in OnCreate() in LibApp. but OnCreate() doesn't fired. I extends my App from LibApp and added App in Manifest.
  • Luten
    Luten almost 6 years
    Forcing users of library to inherit Application from your class is a bad practice - it creates problems of multiple inheritance, and requires creation of additional class for library integration. The best way here is to have some kind of init method that will have Context param
  • Dmitry
    Dmitry almost 6 years
    Is it required to add a circular dependency on the app module in the library for that?
  • Gabo Alvarez
    Gabo Alvarez over 5 years
    Mate, you are my personal hero now. Thanks you a lot. I'm making an Android library for persistence tasks that should be totally reusable without any dependency FROM the project TO the library , so I couldn't really just make an Application class inside my library and hardcode it to my manifest, that would totally break the reusability and cause uncompatibilty issues when I wanted to port the library to other projects. Also I'm planning to release as Open Source as soon as I can, so that means it can't force other people to use the library Application class. Thank you
  • CommonsWare
    CommonsWare about 5 years
    Accessing hidden classes is being blocked on Android 9.0+.
  • Bibin Baby
    Bibin Baby about 3 years
    This solution will not works if we have multiple libraries and everyone required appcontext.