70

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.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Haris Hasan
  • 29,856
  • 10
  • 92
  • 122
  • getApplicationContext()? – WarrenFaith Aug 23 '11 at 07:20
  • 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? – Aracem Aug 23 '11 at 07:21
  • @WarrenFaith: no such method is available inside my android library project – Haris Hasan Aug 23 '11 at 07:21
  • 1
    @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? – Haris Hasan Aug 23 '11 at 07:23
  • the current? with getApplicationContext, even with "this" (if you are in a class extends Activity) The context is allways independent of your libraries. – Aracem Aug 23 '11 at 07:25
  • 1
    No my class don't extend activity it is a simple plain class – Haris Hasan Aug 23 '11 at 07:27
  • possible duplicate of [How should I go about getting Context in this case?](http://stackoverflow.com/questions/7146778/how-should-i-go-about-getting-context-in-this-case) – ingsaurabh Aug 23 '11 at 07:54
  • 1
    @Haris if you class is a plain class, you NEED to explicitly pass the context in. – Blundell Aug 23 '11 at 08:23

5 Answers5

57

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.

peceps
  • 17,370
  • 11
  • 72
  • 79
  • 3
    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 – Dani bISHOP Nov 10 '11 at 03:51
  • 8
    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. – peceps Nov 15 '11 at 10:31
  • 1
    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? – Dani bISHOP Nov 17 '11 at 22:40
  • Sorry to bump this, but does the app class need to be in the base package? – Maxrunner Aug 23 '12 at 17:06
  • 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. – Maxrunner Sep 14 '12 at 14:22
  • @peceps Can i write something like this: public static LibApp getInstance() { return instance; } – Dr.jacky May 14 '15 at 03:42
  • @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. – Dr.jacky May 14 '15 at 06:52
  • 1
    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 – Luten Aug 16 '18 at 05:23
  • Is it required to add a circular dependency on the app module in the library for that? – Dmitry Aug 19 '18 at 02:12
  • This solution will not works if we have multiple libraries and everyone required appcontext. – Bibin Baby Jun 17 '21 at 06:30
14

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.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 3
    :) so in short it is not possible to get application context independently in an android library project – Haris Hasan Aug 23 '11 at 10:41
  • 2
    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 – Blundell Aug 23 '11 at 10:57
13

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.

naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
Lam
  • 179
  • 1
  • 3
  • 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 – Gabo Alvarez Feb 22 '19 at 04:55
  • Accessing hidden classes is [being blocked on Android 9.0+](https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces). – CommonsWare May 14 '19 at 18:37
3

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

1

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.

Sayooj Valsan
  • 536
  • 5
  • 16