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.

2 Answers 2

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!

Sign up to request clarification or add additional context in comments.

Comments

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"**
        >

1 Comment

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!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.