-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added sample for multiple flutters for android
- Loading branch information
Showing
38 changed files
with
1,083 additions
and
0 deletions.
There are no files selected for viewing
15 changes: 15 additions & 0 deletions
15
add_to_app/multiple_flutters/multiple_flutters_android/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
*.iml | ||
.gradle | ||
/local.properties | ||
/.idea/caches | ||
/.idea/libraries | ||
/.idea/modules.xml | ||
/.idea/workspace.xml | ||
/.idea/navEditor.xml | ||
/.idea/assetWizardSettings.xml | ||
.DS_Store | ||
/build | ||
/captures | ||
.externalNativeBuild | ||
.cxx | ||
local.properties |
17 changes: 17 additions & 0 deletions
17
add_to_app/multiple_flutters/multiple_flutters_android/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# multiple_flutters_android | ||
|
||
This is an add-to-app sample that uses the Flutter engine group API to host | ||
multiple instances of Flutter in the app. | ||
|
||
## Getting Started | ||
|
||
```sh | ||
cd ../multiple_flutters_module | ||
flutter pub get | ||
cd - | ||
open -a "Android Studio" multiple_flutters_android/ # macOS command | ||
# (build and run) | ||
``` | ||
|
||
For more information see | ||
[multiple_flutters_module](../multiple_flutters_module/README.md). |
1 change: 1 addition & 0 deletions
1
add_to_app/multiple_flutters/multiple_flutters_android/app/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
50 changes: 50 additions & 0 deletions
50
add_to_app/multiple_flutters/multiple_flutters_android/app/build.gradle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
plugins { | ||
id 'com.android.application' | ||
id 'kotlin-android' | ||
} | ||
|
||
android { | ||
signingConfigs { | ||
self { | ||
} | ||
} | ||
compileSdkVersion 30 | ||
|
||
defaultConfig { | ||
applicationId "dev.flutter.multipleflutters" | ||
minSdkVersion 24 | ||
targetSdkVersion 30 | ||
versionCode 1 | ||
versionName "1.0" | ||
|
||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||
} | ||
|
||
buildTypes { | ||
release { | ||
minifyEnabled false | ||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||
signingConfig debug.signingConfig | ||
} | ||
} | ||
compileOptions { | ||
sourceCompatibility JavaVersion.VERSION_1_8 | ||
targetCompatibility JavaVersion.VERSION_1_8 | ||
} | ||
kotlinOptions { | ||
jvmTarget = '1.8' | ||
} | ||
} | ||
|
||
dependencies { | ||
|
||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" | ||
implementation 'androidx.core:core-ktx:1.2.0' | ||
implementation 'androidx.appcompat:appcompat:1.1.0' | ||
implementation 'com.google.android.material:material:1.1.0' | ||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' | ||
testImplementation 'junit:junit:4.+' | ||
androidTestImplementation 'androidx.test.ext:junit:1.1.1' | ||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' | ||
implementation project(':flutter') | ||
} |
21 changes: 21 additions & 0 deletions
21
add_to_app/multiple_flutters/multiple_flutters_android/app/proguard-rules.pro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Add project specific ProGuard rules here. | ||
# You can control the set of applied configuration files using the | ||
# proguardFiles setting in build.gradle. | ||
# | ||
# For more details, see | ||
# http://developer.android.com/guide/developing/tools/proguard.html | ||
|
||
# If your project uses WebView with JS, uncomment the following | ||
# and specify the fully qualified class name to the JavaScript interface | ||
# class: | ||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
# public *; | ||
#} | ||
|
||
# Uncomment this to preserve the line number information for | ||
# debugging stack traces. | ||
#-keepattributes SourceFile,LineNumberTable | ||
|
||
# If you keep the line number information, uncomment this to | ||
# hide the original source file name. | ||
#-renamesourcefileattribute SourceFile |
34 changes: 34 additions & 0 deletions
34
add_to_app/multiple_flutters/multiple_flutters_android/app/src/main/AndroidManifest.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
package="dev.flutter.multipleflutters"> | ||
|
||
<application | ||
android:name=".App" | ||
android:allowBackup="true" | ||
android:icon="@mipmap/ic_launcher" | ||
android:label="@string/app_name" | ||
android:roundIcon="@mipmap/ic_launcher_round" | ||
android:supportsRtl="true" | ||
android:theme="@style/Theme.MultipleFlutters"> | ||
<activity android:name=".MainActivity"> | ||
<intent-filter> | ||
<action android:name="android.intent.action.MAIN" /> | ||
|
||
<category android:name="android.intent.category.LAUNCHER" /> | ||
</intent-filter> | ||
</activity> | ||
<activity | ||
android:name=".SingleFlutterActivity" | ||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" | ||
android:hardwareAccelerated="true" | ||
android:windowSoftInputMode="adjustResize" | ||
/> | ||
<activity | ||
android:name=".DoubleFlutterActivity" | ||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" | ||
android:hardwareAccelerated="true" | ||
android:windowSoftInputMode="adjustResize" | ||
/> | ||
</application> | ||
|
||
</manifest> |
18 changes: 18 additions & 0 deletions
18
..._flutters/multiple_flutters_android/app/src/main/java/dev/flutter/multipleflutters/App.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package dev.flutter.multipleflutters | ||
|
||
import android.app.Application | ||
import io.flutter.embedding.engine.FlutterEngineGroup | ||
|
||
/** | ||
* Application class for this app. | ||
* | ||
* This holds onto our engine group. | ||
*/ | ||
class App : Application() { | ||
lateinit var engines: FlutterEngineGroup | ||
|
||
override fun onCreate() { | ||
super.onCreate() | ||
engines = FlutterEngineGroup(this) | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
...ers/multiple_flutters_android/app/src/main/java/dev/flutter/multipleflutters/DataModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package dev.flutter.multipleflutters | ||
|
||
import java.lang.ref.WeakReference | ||
|
||
/** | ||
* Interface for getting notifications when the DataModel is updated. | ||
*/ | ||
interface DataModelObserver { | ||
fun onCountUpdate(newCount: Int) | ||
} | ||
|
||
/** | ||
* A singleton/observable data model for the data shared between Flutter and the host platform. | ||
* | ||
* This is the definitive source of truth for all data. | ||
*/ | ||
class DataModel { | ||
companion object { | ||
val instance = DataModel() | ||
} | ||
|
||
private val observers = mutableListOf<WeakReference<DataModelObserver>>() | ||
|
||
public var counter = 0 | ||
set(value) { | ||
field = value | ||
for (observer in observers) { | ||
observer.get()?.onCountUpdate(value) | ||
} | ||
} | ||
|
||
fun addObserver(observer: DataModelObserver) { | ||
observers.add(WeakReference(observer)) | ||
} | ||
|
||
fun removeObserver(observer: DataModelObserver) { | ||
observers.removeIf { | ||
if (it.get() != null) it.get() == observer else true | ||
} | ||
} | ||
} |
81 changes: 81 additions & 0 deletions
81
..._flutters_android/app/src/main/java/dev/flutter/multipleflutters/DoubleFlutterActivity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package dev.flutter.multipleflutters | ||
|
||
import android.content.Intent | ||
import android.os.Bundle | ||
import android.widget.FrameLayout | ||
import android.widget.LinearLayout | ||
import androidx.fragment.app.FragmentActivity | ||
import androidx.fragment.app.FragmentManager | ||
import io.flutter.embedding.android.FlutterFragment | ||
import io.flutter.embedding.engine.FlutterEngineCache | ||
|
||
/** | ||
* An activity that displays 2 FlutterFragments vertically. | ||
*/ | ||
class DoubleFlutterActivity : FragmentActivity(), EngineBindingsDelegate { | ||
private val topBindings: EngineBindings by lazy { | ||
EngineBindings(activity = this, delegate = this, entrypoint = "topMain") | ||
} | ||
private val bottomBindings: EngineBindings by lazy { | ||
EngineBindings(activity = this, delegate = this, entrypoint = "bottomMain") | ||
} | ||
private val numberOfFlutters = 2 | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
val root = LinearLayout(this) | ||
root.layoutParams = LinearLayout.LayoutParams( | ||
LinearLayout.LayoutParams.MATCH_PARENT, | ||
LinearLayout.LayoutParams.MATCH_PARENT | ||
) | ||
root.orientation = LinearLayout.VERTICAL | ||
root.weightSum = numberOfFlutters.toFloat() | ||
|
||
val fragmentManager: FragmentManager = supportFragmentManager | ||
|
||
setContentView(root) | ||
|
||
val app = applicationContext as App | ||
|
||
for (i in 0 until numberOfFlutters) { | ||
val flutterContainer = FrameLayout(this) | ||
root.addView(flutterContainer) | ||
flutterContainer.id = 12345 + i | ||
flutterContainer.layoutParams = LinearLayout.LayoutParams( | ||
FrameLayout.LayoutParams.MATCH_PARENT, | ||
FrameLayout.LayoutParams.MATCH_PARENT, | ||
1.0f | ||
) | ||
val engine = if (i == 0) topBindings.engine else bottomBindings.engine | ||
FlutterEngineCache.getInstance().put(i.toString(), engine) | ||
val flutterFragment = | ||
FlutterFragment.withCachedEngine(i.toString()).build<FlutterFragment>() | ||
fragmentManager | ||
.beginTransaction() | ||
.add( | ||
12345 + i, | ||
flutterFragment | ||
) | ||
.commit() | ||
} | ||
|
||
topBindings.attach() | ||
bottomBindings.attach() | ||
} | ||
|
||
override fun onDestroy() { | ||
topBindings.detach() | ||
topBindings.detach() | ||
|
||
for (i in 0 until numberOfFlutters) { | ||
FlutterEngineCache.getInstance().remove(i.toString()) | ||
} | ||
|
||
super.onDestroy() | ||
} | ||
|
||
override fun onNext() { | ||
val flutterIntent = Intent(this, MainActivity::class.java) | ||
startActivity(flutterIntent) | ||
} | ||
} |
84 changes: 84 additions & 0 deletions
84
...ultiple_flutters_android/app/src/main/java/dev/flutter/multipleflutters/EngineBindings.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package dev.flutter.multipleflutters | ||
|
||
import android.app.Activity | ||
import io.flutter.FlutterInjector | ||
import io.flutter.embedding.engine.FlutterEngine | ||
import io.flutter.embedding.engine.dart.DartExecutor | ||
import io.flutter.plugin.common.MethodChannel | ||
|
||
/** | ||
* This interface represents the notifications an EngineBindings may be receiving from the Flutter | ||
* instance. | ||
* | ||
* What methods this interface has depends on the messages that are sent over the EngineBinding's | ||
* channel in `main.dart`. Messages that interact with the DataModel are handled automatically | ||
* by the EngineBindings. | ||
* | ||
* @see main.dart for what messages are getting sent from Flutter. | ||
*/ | ||
interface EngineBindingsDelegate { | ||
fun onNext() | ||
} | ||
|
||
/** | ||
* This binds a FlutterEngine instance with the DataModel and a channel for communicating with that | ||
* engine. | ||
* | ||
* Messages involving the DataModel are handled by the EngineBindings, other messages are forwarded | ||
* to the EngineBindingsDelegate. | ||
* | ||
* @see main.dart for what messages are getting sent from Flutter. | ||
*/ | ||
class EngineBindings(activity: Activity, delegate: EngineBindingsDelegate, entrypoint: String) : | ||
DataModelObserver { | ||
val channel: MethodChannel | ||
val engine: FlutterEngine | ||
val delegate: EngineBindingsDelegate | ||
|
||
init { | ||
val app = activity.applicationContext as App | ||
// This has to be lazy to avoid creation before the FlutterEngineGroup. | ||
val dartEntrypoint = | ||
DartExecutor.DartEntrypoint( | ||
FlutterInjector.instance().flutterLoader().findAppBundlePath(), entrypoint | ||
) | ||
engine = app.engines.createAndRunEngine(activity, dartEntrypoint) | ||
this.delegate = delegate | ||
channel = MethodChannel(engine.dartExecutor.binaryMessenger, "multiple-flutters") | ||
} | ||
|
||
/** | ||
* This setups the messaging connections on the platform channel and the DataModel. | ||
*/ | ||
fun attach() { | ||
DataModel.instance.addObserver(this) | ||
channel.invokeMethod("setCount", DataModel.instance.counter) | ||
channel.setMethodCallHandler { call, result -> | ||
when (call.method) { | ||
"incrementCount" -> { | ||
DataModel.instance.counter = DataModel.instance.counter + 1 | ||
result.success(null) | ||
} | ||
"next" -> { | ||
this.delegate.onNext() | ||
result.success(null) | ||
} | ||
else -> { | ||
result.notImplemented() | ||
} | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* This tears down the messaging connections on the platform channel and the DataModel. | ||
*/ | ||
fun detach() { | ||
DataModel.instance.removeObserver(this) | ||
channel.setMethodCallHandler(null) | ||
} | ||
|
||
override fun onCountUpdate(newCount: Int) { | ||
channel.invokeMethod("setCount", newCount) | ||
} | ||
} |
Oops, something went wrong.