Multiple Application classes in app's and library module's manifest files
Asked Answered
S

2

6

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>

Saidel answered 7/6, 2020 at 17:20 Comment(4)
Did you tried any errors did you got any errors? I think it's possible not tried personally... Check this also https://mcmap.net/q/1779005/-application-class-in-a-module-39-s-manifest/9365212Psychotherapy
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.Saidel
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-77Saidel
Did you checked @RyanM answer ... you can ask doubt to him if you have... in commentsPsychotherapy
C
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


}
Cinchonism answered 20/2, 2022 at 13:24 Comment(1)
that's superb. simple inheritance way,Thermopylae
L
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.

Larrikin answered 7/6, 2020 at 17:46 Comment(7)
Thanks, fo you suggest. Can I use ContentProvider to library startup run code at the Application's startup? Can you share any example ?Saidel
Yes, that's exactly what my answer describes how to do. I added a skeleton example and also linked to a real-world example.Larrikin
@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 .Saidel
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).Larrikin
@Saidel You note that this is working - are there any additional issues preventing you from accepting this answer to mark it as correct?Larrikin
I got an another way. developer.android.com/topic/libraries/app-startupSaidel
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.Larrikin

© 2022 - 2024 — McMap. All rights reserved.