Mustafa Berkay Mutlu
Mustafa Berkay Mutlu

Reputation: 2099

How to organize application classes for Instant Apps

I am trying to develop a multi-feature instant app.

I have query and autocomplete feature modules.

They have QueryApplication and AutoCompleteApplication classes in their feature modules for dependency injection.

app module's Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.epictimes.uvindex.app" />

'base' module's Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.epictimes.uvindex">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <meta-data
            android:name="aia-compat-api-min-version"
            android:value="1" />

    </application>

</manifest>

query module's Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.epictimes.uvindex.query">

    <application android:name=".QueryApplication">
        <!--simplified-->
    </application>
</manifest>

autocomplete module's Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.epictimes.uvindex.autocomplete">

    <application android:name=".AutoCompleteApplication">
        <!--simplified-->
    </application>
</manifest>

When I try to build, it gives me the following error:

Error:Execution failed for task ':base:processProductionDebugFeatureManifest'.

Manifest merger failed : Attribute application@name value=(net.epictimes.uvindex.query.QueryApplication) from [:query] AndroidManifest.xml:16:9-68 is also present at [:autocomplete] AndroidManifest.xml:14:9-82 value=(net.epictimes.uvindex.autocomplete.AutoCompleteApplication).
Suggestion: add 'tools:replace="android:name"' to element at AndroidManifest.xml:7:5-18:19 to override.

The Merged Manifest in app module also shows the error message. So when I add tools:replace rule in app module's Manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="net.epictimes.uvindex.app">

    <application
        android:name="net.epictimes.uvindex.query.QueryApplication"
        tools:replace="android:name" />

</manifest>

It gives me a similar error:

Error:Execution failed for task ':base:processProductionDebugFeatureManifest'.

Manifest merger failed : Attribute application@name value=(net.epictimes.uvindex.query.QueryApplication) from [:query] AndroidManifest.xml:16:9-68 is also present at [:autocomplete] AndroidManifest.xml:14:9-82 value=(net.epictimes.uvindex.autocomplete.AutoCompleteApplication).
Suggestion: add 'tools:replace="android:name"' to element at AndroidManifest.xml:7:5-18:19 to override.

But this time app, base, query and autocomplete module's Merged Manifests does not show any error. So I think this error is for instantapp module.

So, how to organize application classes for multi-feature instant apps?

Can we even use separate application classes for each feature module?

Upvotes: 7

Views: 1070

Answers (1)

ManmeetP
ManmeetP

Reputation: 821

In short, no, not for each feature module.
It fails because when the instant app tries to merge its manifest, there are multiple android:name (from query and autocomplete ...). Adding tools:replace in the app module will only work for the installed app, it does not resolve anything for the instant app’s manifest.

  • installed app merges these manifests: app, base, feature+
  • instant app merges these manifests: base, feature+

There can only be one manifest per app: instant and installed. So there can also only be one designated android:name after the manifests are merged. Though, both instant and installed can use different Application classes.

  1. declare only one android:name in only one feature of your choosing (that one will be used for the instant app) and declare one in your app module with tools:replace (now your installed app will run with a different one).
  2. or, if you feel you must include android:name for all of your features (base included), then you must add tools:replace to all of them (but now it will default to the base’s Application class).
  3. or simply use InstantApps.isInstantApp() in one master Application class.

You can also see how to do this at: Separate manifest for instant app

Upvotes: 6

Related Questions