How to add Flutter to Android App
Tags: productivity, flutter, programming, android
Published: 2022-05-19 08:39:18

*In case it helped :)*
<a href="https://www.buymeacoffee.com/aseemwangoo" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Pass Me A Coffee!!" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>

<!-- wp:paragraph -->
<p>We will cover briefly:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>Adding flutter to the existing android app</li><li>Adding flutter to the new android app (Compose)</li></ol>
<!-- /wp:list -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Note: This article assumes the reader knows about android</p></blockquote>
<!-- /wp:quote -->

{% youtube 7gCILw0HLw4 %}

<!-- wp:heading {"level":4} -->
<h4>Add to&nbsp;App</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>It’s sometimes not practical to rewrite your entire application in Flutter. For those situations, Flutter can be integrated into your existing application piecemeal, as a library or module. That module can then be imported into your Android or iOS app to render a part of your app’s UI in Flutter.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The <code>add-to-app</code> feature supports integrating multiple instances of any screen size. Having multiple Flutter instances allows each instance to maintain an independent application and UI state while using minimal memory resources. See more on the <a href="https://docs.flutter.dev/development/add-to-app/multiple-flutters" rel="noreferrer noopener" target="_blank">multiple Flutters</a> page.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>Adding flutter to the existing android&nbsp;app</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Flutter 3 was announced on 11th May 2022. There was a talk called <a href="https://youtu.be/w_ezWG1yKQQ?t=874" rel="noreferrer noopener" target="_blank">What’s New In Flutter</a> in which the speaker showed an application called <a href="https://github.com/flutter/put-flutter-to-work" rel="noreferrer noopener" target="_blank">Put Flutter to Work</a>.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center"} -->
<div class="wp-block-image"><figure class="aligncenter"><img src="https://cdn-images-1.medium.com/max/1600/0*QzTLD5GxRRIlbby2.gif" alt="Put Flutter to Work"/><figcaption>Put Flutter to&nbsp;Work</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>We will be adding the <a href="https://github.com/flutter/put-flutter-to-work/tree/main/flutter_nps" target="_blank" rel="noreferrer noopener">flutter feedback screen</a> to the <a href="https://github.com/flutter/put-flutter-to-work/tree/main/newsfeed_android" target="_blank" rel="noreferrer noopener">android app</a></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>Begin</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Let’s open the app’s <code><a href="https://github.com/flutter/put-flutter-to-work/blob/main/newsfeed_android/app/build.gradle" target="_blank" rel="noreferrer noopener">build.gradle</a></code> and see the section under <code>repositories</code>&nbsp;</p>
<!-- /wp:paragraph -->

```groovy
repositories {
    google()
    mavenCentral()
    String storageUrl = "https://storage.googleapis.com"
    maven {
        url '../../flutter_nps/build/host/outputs/repo'
    }
    maven {
        url "$storageUrl/download.flutter.io"
    }
}
```

<!-- wp:list -->
<ul><li>We see the project depends upon a local path inside the <strong>flutter_nps</strong></li><li>The same is observed if we open the project’s <code><a href="https://github.com/flutter/put-flutter-to-work/blob/main/newsfeed_android/build.gradle" rel="noreferrer noopener" target="_blank">build.gradle</a></code>&nbsp;</li><li>The project also depends upon the following flutter specific dependencies</li></ul>
<!-- /wp:list -->

```groovy
debugImplementation 'com.example.flutter_nps:flutter_debug:1.0'
profileImplementation 'com.example.flutter_nps:flutter_profile:1.0'
releaseImplementation'com.example.flutter_nps:flutter_release:1.0'
```

<!-- wp:paragraph -->
<p>As of now, the path <code>flutter_nps/build/host/outputs/repo</code> doesn’t exist in our machine, let’s investigate the <strong>flutter_nps</strong> project now</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4><strong>Add the Flutter module as a dependency</strong></h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>There are two ways to add the Flutter module as a dependency on your existing app. We will be going with the <strong>AAR (Android Archive)</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The AAR mechanism creates generic Android AARs as intermediaries that package your Flutter module.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>This packages your Flutter library as a generic local Maven repository composed of AARs and POMs artifacts.</li><li>We have the following folder structure for the <strong>flutter_nps</strong> app</li></ul>
<!-- /wp:list -->

<!-- wp:image {"align":"center"} -->
<div class="wp-block-image"><figure class="aligncenter"><img src="https://cdn-images-1.medium.com/max/1600/1*tW6twLv4gG021SBlA4Vteg.png" alt="Flutter_nps project"/><figcaption>Flutter_nps project</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:list -->
<ul><li>We use the following command for generating the AAR</li></ul>
<!-- /wp:list -->

```yaml
flutter build aar
```

<!-- wp:paragraph -->
<p>which also shows us the on-screen instructions to integrate</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center"} -->
<div class="wp-block-image"><figure class="aligncenter"><img src="https://cdn-images-1.medium.com/max/1600/1*Wqp8TvQksLIBOXWjkDFedQ.png" alt="Flutter AAR integration steps"/><figcaption>Flutter AAR integration steps</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>and now if we run our android app, it should work…🎉🎉🎉🎉</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p><strong>Note</strong>: The android app which was used in the above section doesn’t use the Compose. In the next section, we will integrate Flutter in a Compose app</p></blockquote>
<!-- /wp:quote -->

<!-- wp:heading {"level":4} -->
<h4>Adding flutter to the new android app (Compose)</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In this section, we will create a <a href="https://github.com/AseemWangoo/AddFlutter" rel="noreferrer noopener" target="_blank">new android app</a> but with Compose Activity.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>Begin</h4>
<!-- /wp:heading -->

<!-- wp:list -->
<ul><li>Create <code>New Project</code> and Select <code>EmptyComposeActivity</code> and this will create a Compose project</li><li>We create a <a href="https://github.com/AseemWangoo/AddFlutter/blob/master/app/src/main/java/com/example/addflutter/components/SimpleButtonComponent.kt" rel="noreferrer noopener" target="_blank">button component</a> on the main screen</li></ul>
<!-- /wp:list -->

<!-- wp:image {"align":"center"} -->
<div class="wp-block-image"><figure class="aligncenter"><img src="https://cdn-images-1.medium.com/max/1600/1*LB6TUuioXrqRenaYktoOQQ.png" alt="Compose Button"/><figcaption>Compose Button</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:list -->
<ul><li>Let’s open the app’s <code><a href="https://github.com/AseemWangoo/AddFlutter/blob/master/app/build.gradle" rel="noreferrer noopener" target="_blank">build.gradle</a></code> and under <code>repositories</code> add the following</li></ul>
<!-- /wp:list -->

```groovy
repositories {
    google()
    mavenCentral()
    String storageUrl = "https://storage.googleapis.com"
    maven {
        url '../../flutter_nps/build/host/outputs/repo'
    }
    maven {
        url "$storageUrl/download.flutter.io"
    }
}
```

<!-- wp:paragraph -->
<p>and also add the above to the project’s <code><a href="https://github.com/AseemWangoo/AddFlutter/blob/master/build.gradle" rel="noreferrer noopener" target="_blank">build.gradle</a></code>&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>Inside the <code>dependencies</code> of app <code><a href="https://github.com/AseemWangoo/AddFlutter/blob/master/app/build.gradle" target="_blank" rel="noreferrer noopener">build.gradle</a></code> add the following</li></ul>
<!-- /wp:list -->

```groovy
debugImplementation 'com.example.flutter_nps:flutter_debug:1.0'
profileImplementation 'com.example.flutter_nps:flutter_profile:1.0'
releaseImplementation'com.example.flutter_nps:flutter_release:1.0'
```

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Note: Try removing the <code>profileImplementation</code> in case the gradle gives any errors</p></blockquote>
<!-- /wp:quote -->

<!-- wp:list -->
<ul><li>The above steps implies that our new project requires the AAR from the <a href="https://github.com/flutter/put-flutter-to-work/tree/main/flutter_nps" rel="noreferrer noopener" target="_blank">flutter_nps</a> (since we are reusing the same flutter project).</li><li>The steps for building the AAR remain the same as we saw in the above section.</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Next, we create the <a href="https://github.com/AseemWangoo/AddFlutter/blob/master/app/src/main/java/com/example/addflutter/Application.kt" target="_blank" rel="noreferrer noopener">Application class</a> which extends the <code>Application</code> Also, register this inside our <a href="https://github.com/AseemWangoo/AddFlutter/blob/master/app/src/main/AndroidManifest.xml" target="_blank" rel="noreferrer noopener">Manifest.xml</a> under <code>android:name="&lt;YOUR APPLICATION CLASS&gt;"</code></p>
<!-- /wp:paragraph -->

```kotlin
class AddFlutterApplication : Application() {
    lateinit var flutterEngine: FlutterEngine
    companion object {
        const val FLUTTER_ENGINE_NAME = "nps_flutter_engine_name"
    }
    override fun onCreate() {
        super.onCreate()
        flutterEngine = FlutterEngine(this)
        
        flutterEngine.dartExecutor.executeDartEntrypoint(
            DartExecutor.DartEntrypoint.createDefault()
        )
      
        FlutterEngineCache
            .getInstance()
            .put(FLUTTER_ENGINE_NAME, flutterEngine)
    }
}
```

<!-- wp:list -->
<ul><li>We initialize the <code><a href="https://api.flutter.dev/javadoc/io/flutter/embedding/engine/FlutterEngine.html" rel="noreferrer noopener" target="_blank">FlutterEngine</a></code> which is the container through which Dart code can be run in an Android application</li><li>To start running Dart and/or Flutter within this <code>FlutterEngine</code>, we get a reference to this engine's <code><a href="https://api.flutter.dev/javadoc/io/flutter/embedding/engine/dart/DartExecutor.html" rel="noreferrer noopener" target="_blank">DartExecutor</a></code> and then use <code><a href="https://api.flutter.dev/javadoc/io/flutter/embedding/engine/dart/DartExecutor.html#executeDartEntrypoint%28io.flutter.embedding.engine.dart.DartExecutor.DartEntrypoint%29" rel="noreferrer noopener" target="_blank">DartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint)</a></code></li><li>Finally, we cache the flutter engine to be used by the FlutterActivity</li><li><code>FlutterEngineCache</code> is useful for storing pre-warmed <code><a href="https://api.flutter.dev/javadoc/io/flutter/embedding/engine/FlutterEngine.html" rel="noreferrer noopener" target="_blank">FlutterEngine</a></code> instances. The ID of a given <code><a href="https://api.flutter.dev/javadoc/io/flutter/embedding/engine/FlutterEngine.html" rel="noreferrer noopener" target="_blank">FlutterEngine</a></code> can be any string</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Since we are going to launch a Flutter activity, we will need to register it as an activity under <a href="https://github.com/AseemWangoo/AddFlutter/blob/master/app/src/main/AndroidManifest.xml" target="_blank" rel="noreferrer noopener">Manifest.xml</a> (otherwise it gives an error…)</p>
<!-- /wp:paragraph -->

```xml
<activity
  android:name="io.flutter.embedding.android.FlutterActivity"
          android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|s creenLayout"
  android:hardwareAccelerated="true"
  android:windowSoftInputMode="adjustResize"
/>
```

<!-- wp:paragraph -->
<p>At last, we need to launch the FlutterActivity.</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>We do so by calling the <code>startActivity</code> from the <code>context</code>&nbsp;</li></ul>
<!-- /wp:list -->

```kotlin
context.startActivity(
  FlutterActivity
       .withCachedEngine(AddFlutterApplication.FLUTTER_ENGINE_NAME)
  .build(context)
)
```

<!-- wp:list -->
<ul><li>This <code>withCachedEngine</code> can be used to configure an Intent to launch a FlutterActivity that internally uses an existing FlutterEngine that is cached and is identified using the cached engine ID (which is the same we used while registering inside the Application).</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>and now if we run our new android app, we see it working…🎉🎉🎉🎉</p>
<!-- /wp:paragraph -->

{% youtube 7gCILw0HLw4 %}

<!-- wp:paragraph -->
<p><a rel="noreferrer noopener" href="https://github.com/AseemWangoo/AddFlutter" target="_blank"><em>Source code.</em></a>

*In case it helped :)*
<a href="https://www.buymeacoffee.com/aseemwangoo" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Pass Me A Coffee!!" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>