3

I'm trying to write a plugin for stetho, following these steps.

It requires some initialization in onCreate method of a custom application.

public class MyApplication extends Application {
  public void onCreate() {
    super.onCreate();
    Stetho.initializeWithDefaults(this);
  }
}

and making an entry for the same application in AndroidManifest.xml.

<manifest
        xmlns:android="http://schemas.android.com/apk/res/android"
        ...>
        <application
                android:name="MyApplication"
                ...>
         </application>
</manifest>      

But I get an error while trying flutter run for the flutter app that depends on this plugin -

D:\Dev\Repo\flutter_test\myapp\android\app\src\main\AndroidManifest.xml:16:9-57 Error:
        Attribute application@name value=(io.flutter.app.FlutterApplication) from AndroidManifest.xml:16:9-57
        is also present at [:stetho] AndroidManifest.xml:7:18-76 value=(com.vilokanlabs.stetho.stetho.MyApplication).
        Suggestion: add 'tools:replace="android:name"' to <application> element at AndroidManifest.xml:15:5-38:19 to override.

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:processDebugManifest'.
> Manifest merger failed : Attribute application@name value=(io.flutter.app.FlutterApplication) from AndroidManifest.xml:16:9-57
        is also present at [:stetho] AndroidManifest.xml:7:18-76 value=(com.vilokanlabs.stetho.stetho.MyApplication).
        Suggestion: add 'tools:replace="android:name"' to <application> element at AndroidManifest.xml:15:5-38:19 to override.
Vilokan Labs
  • 1,975
  • 12
  • 21

2 Answers2

3

It seems that only one application node is allowed in Android. As suggested here and documented here.

tool:replace could also be a solution as suggested by @sagar-chavada, but it's not working. Somehow, app's manifest is considered/parsed later than the plugin's manifest, so tool:replace has effect if used in application's manifest (which is of no use) but has no effect if used in plugin's manifest (& an error is thrown).

So far, the only solution that worked for me is extending the Flutter's application class in the plugin -

public class MyApplication extends FlutterApplication {
    public void onCreate() {
        super.onCreate();
        Stetho.initializeWithDefaults(this);
    }

and updating the app's manifest file to use this new sub-class -

<!-- io.flutter.app.FlutterApplication is an android.app.Application that
         calls FlutterMain.startInitialization(this); in its onCreate method.
         In most cases you can leave this as-is, but you if you want to provide
         additional functionality it is fine to subclass or reimplement
         FlutterApplication and put your custom class here. -->

    <application
        android:name="com.vilokanlabs.stetho.stetho.MyApplication"
        android:label="myapp"
        ...

As it turns out, comment here suggests the same. Maybe not a very good solution for a plugin (will fail once there are two competing plugins) but it works!

Vilokan Labs
  • 1,975
  • 12
  • 21
1

Add this line to your manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    **xmlns:tools="http://schemas.android.com/tools"**
    >

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        **tools:replace="android:icon,android:theme,android:name"**
        >
Sagar Chavada
  • 5,169
  • 7
  • 40
  • 67
  • Thanks for the suggestion, didn't know about tools:replace. But in my case it's not helping. If I use it in the manifest of my plugin, then I get an error (it seems application manifest is parsed after the plugin manifest). And if I use it in the manifest of my application, then it's no use; plugin's application is never initialized. For now I'm directly replacing the application name in my original manifest file. Thanks again! – Vilokan Labs Mar 03 '18 at 12:44