4

In the library module's manifest, I need to use an Application class. Is it possible to do this in Android?

Manifest:

<application
    android:name="com.compnay.app.App"
    android:allowBackup="true"
    android:label="@string/app_name"
    >
</application>

Module library Manifest:

<application
    android:name="com.example.mymodule.App"
    android:allowBackup="true"
    android:label="@string/app_name"
    >
</application>

Ryan M
  • 18,333
  • 31
  • 67
  • 74
user3742866
  • 136
  • 6
  • Did you tried any errors did you got any errors? I think it's possible not tried personally... Check this also https://stackoverflow.com/q/39506352/9365212 – AgentP Jun 07 '20 at 17:25
  • in com.example.mymodule.The app I have some for dagger initialization app module and com.compnay.app.App also more code for dagger initialization for the library . so I need to use two Application classes. – user3742866 Jun 07 '20 at 17:47
  • Merging Errors: Error: Attribute application@name value=(com.compnay.app.App.AppController) from AndroidManifest.xml:12:9-52 is also present at AndroidManifest.xml:43:14-77 – user3742866 Jun 07 '20 at 18:01
  • 1
    Did you checked @RyanM answer ... you can ask doubt to him if you have... in comments – AgentP Jun 07 '20 at 18:04

2 Answers2

4

There is a trick that you can use. We imagine your main application class is Application1 and your library application class is Application2. Now extend your Application1 from Application2. Just remember to call onCreate of Application2 in Application1's onCreate

public class Application1 extend Application2{
@Override
    public void onCreate() {
        super.onCreate();

        //your codes


}
behrad
  • 1,228
  • 14
  • 21
1

Unfortunately, it's not possible to have multiple Application classes, but there are workarounds, depending on what you're trying to do.

An Android application can only have a single Application subclass that's used as the application context.

This is because every Context in the app has a reference to it that can be retrieved by getApplicationContext(). There's no provision for multiple application contexts, and no way to specify whether you want the "library application context" or the "main application context."

Assuming that what you want to do is initialize your library on app startup, you can simply create an empty ContentProvider that's android:exported="false" and do your initialization in its onCreate method. This will be called before the app's Application.onCreate.

<provider
    android:name="com.my.library.MyLibraryInitializer"
    android:authorities="${applicationId}.mylibrary-initializer"
    android:exported="false"/>
public class MyLibraryInitializer extends ContentProvider {
    @Override
    public boolean onCreate() {
        // perform your initialization here
        return true;
    }

    // Everything below here is just boilerplate to implement the abstract methods
    // in ContentProvider, no need to change it

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        return 0;
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }
}

This is, for example, what WorkManager does to initialize itself: it declares a provider in its manifest and performs its initialization within the onCreate method of that ContentProvider.

Ryan M
  • 18,333
  • 31
  • 67
  • 74
  • 1
    Thanks, fo you suggest. Can I use ContentProvider to library startup run code at the Application's startup? Can you share any example ? – user3742866 Jun 07 '20 at 18:17
  • 1
    Yes, that's exactly what my answer describes how to do. I added a skeleton example and also linked to a real-world example. – Ryan M Jun 07 '20 at 18:29
  • @Override public boolean onCreate() { // perform your initialization here AppController appController = new AppController(getContext()); appController.onCreate(); return true; } Thanks a lot, it is working. But it is possible to get any memory error. ContentProvider when destroying in the application ? This is no ContentProvider lifecycle available on the internet. Can tell us details about the ContentProvider lifecycle and when destroy it . – user3742866 Jun 07 '20 at 18:56
  • As far as memory issues, it's exactly the same as an `Application` object - it lives for the entire life of the process, so make sure not to hold references to anything you don't want kept around indefinitely. There's no need to explicitly handle destroying it, it'll be removed when the process dies (note the lack of any cleanup/destroy code in WorkManager's `ContentProvider`). – Ryan M Jun 07 '20 at 23:29
  • @user3742866 You note that this is working - are there any additional issues preventing you from accepting this answer to mark it as correct? – Ryan M Jun 09 '20 at 08:16
  • I got an another way. https://developer.android.com/topic/libraries/app-startup – user3742866 Jun 11 '20 at 05:45
  • 1
    Yep, that just came out today, in fact :-) I'd recommend using that - I was actually going to update my answer with that information once it came out, as it provides a better experience. – Ryan M Jun 11 '20 at 05:48