Flutter接入Android原生现有工程的两种方式
将Flutter嵌入到原生项目有两种方式,第一种是Flutter官方的的方式:原生去依Flutter的Module,这样,在原生中就可以获取到Flutter的Module的源码,还有一种方式是咸鱼探索出来的,将Flutter的Module编译产物,作为SDK,给原生项目去使用。
在我看来,两种方式各有特点,Flutter官方的方式,方便在与原生可以直接拿到FlutterModule中的东西,这样开发过程的调试会很方便。而将FLutter的产物作为sdk 添加到原生中的话,这样对于大公司来说,比较规范,因为大公司,有专门的人去开发原生,有专门的人去做FLutter,这样,大家互相不影响,做原生的,不需要FLutter的环境,只需要等Flutter调试完后,sdk 依赖进来,就可以了。
下面分别说一下,两种将FLutter 添加到 原生现有工程的操作步骤:
①FLutter官方推荐的方式:
官方的Wiki介绍地址:Add Flutter to existing apps
Android
Create a Flutter module
Let’s assume you have an existing Android app at some/path/MyApp, and that you want your Flutter project as a sibling:
$ cd some/path/
$ flutter create -t module my_flutter
This creates a some/path/my_flutter/ Flutter module project with some Dart code to get you started and a .android/ hidden subfolder that wraps up the module project in an Android library.
(While not required in what follows, if you so desire, you can build that library using Gradle:
$ cd .android/
$ ./gradlew flutter:assembleDebug
This results in a flutter-debug.aar archive file in .android/Flutter/build/outputs/aar/.)
Make the host app depend on the Flutter module
Include the Flutter module as a sub-project in the host app’s settings.gradle:
// MyApp/settings.gradle
// MyApp/settings.gradle
include ':app' // assumed existing content
setBinding(new Binding([gradle: this])) // new
evaluate(new File( // new
settingsDir.parentFile, // new
'my_flutter/.android/include_flutter.groovy' // new
))
The binding and script evaluation allows the Flutter module to include itself (as :flutter) and any Flutter plugins used by the module (as :package_info, :video_player, etc) in the evaluation context of your settings.gradle.
Introduce an implementation dependency on the Flutter module from your app:
// MyApp/app/build.gradle
:
dependencies {
implementation project(':flutter')
:
}
Use the Flutter module from your Java code
Use the Flutter module’s Java API to add Flutter views to your host app. This can be done by directly using Flutter.createView:
// MyApp/app/src/main/java/some/package/MainActivity.java
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
View flutterView = Flutter.createView(
MainActivity.this,
getLifecycle(),
"route1"
);
FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(600, 800);
layout.leftMargin = 100;
layout.topMargin = 200;
addContentView(flutterView, layout);
}
});
It is also possible to create a FlutterFragment that takes care of lifecycle by itself:
// MyApp/app/src/main/java/some/package/SomeActivity.java
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
tx.replace(R.id.someContainer, Flutter.createFragment("route1"));
tx.commit();
}
});
Above we use the string “route1” to tell the Dart code which widget to display in the Flutter view. The lib/main.dart file of the Flutter module project template should switch on (or otherwise interpret) the provided route string, available as window.defaultRouteName, to determine which widget to create and pass to runApp. Schematically,
import 'dart:ui';
import 'package:flutter/material.dart';
void main() => runApp(_widgetForRoute(window.defaultRouteName));
Widget _widgetForRoute(String route) {
switch (route) {
case 'route1':
return SomeWidget(...);
case 'route2':
return SomeOtherWidget(...);
default:
return Center(
child: Text('Unknown route: $route', textDirection: TextDirection.ltr),
);
}
}
It is entirely up to you which route strings you want and how to interpret them.
Building and running your app
You build and run MyApp in exactly the same way that you did before you added the Flutter module dependency, typically using Android Studio. The same goes for editing, debugging, and profiling your Android code.
Hot restart/reload and debugging Dart code
Full IDE integration to support working with the Flutter/Dart code of your hybrid app is work in progress. But the fundamentals are already present via the Flutter command line tools and the Dart Observatory web user interface.
Connect a device or launch an emulator. Then make Flutter CLI tooling listen for your app to come up:
$ cd some/path/my_flutter
$ flutter attach
Waiting for a connection from Flutter on Nexus 5X…
Launch MyApp in debug mode from Android Studio (or whichever way you usually do it). Navigate to an area of the app that uses Flutter. Then turn back to the terminal, and you should see output similar to the following:
Done. Syncing files to device Nexus 5X… 5.1s
? To hot reload changes while running, press “r”. To hot restart (and rebuild state), press “R”. An Observatory debugger and profiler on Nexus 5X is available at: http://127.0.0.1:59556/ For a more detailed help message, press “h”. To quit, press “q”.
You can now edit the Dart code in my_flutter, and the changes can be hot reloaded by pressing r in the terminal. You can also paste the URL above into your browser to use the Dart Observatory for setting breakpoints, analyzing memory retention and other debugging tasks.
②以FLutter产物的方式:
打包aar文件
这一步,就是将FLutter Module 的业务代码 以及 FLutter需要的sdk,打包成一个aar文件。
首先 在Flutter的Module根目录下执行命令
flutter build apk
这样会打包生成apk文件,接下来 将apk 解压,复制assets 下面的 xx-share 文件夹到 Flutter的app 下面。


接下来是生成aar 文件,需要先把项目改成library模式,一共要修改两个地方,
1.

2.
Mainifest 文件注释掉application节点。
然后再次执行上面的命令,这时候 生成的 aar 文件,

就包括了 Flutter Module 中的 dart 业务代码 以及 flutter.jar 这个 Flutter 依赖的 sdk。以及一些其他的运行FLutter相关的产物。可以自行解压aar文件查看一下编译产物。
接下来就是去依赖产物了。
原生去依赖生成的aar产物
这一步可以直接将aar文件 添加到 原生中,然后 去 compile(xxx.aar),或者说,将aar文件托管到jcenter上, 然后 通过compile(com.xx.xx)的方式 将aar产物down到本地,供原生项目去调用。
注意几个问题:
- 编译生产的release 产物 的 so是 v7a
.
- gradle.properties 增加一个 enableD8

这里有我学习Flutter过程中的一个Demo,会持续更新Demo的内容,对Flutter 有兴趣的朋友可以一起学习。
https://github.com/CodingForAndroid/flutter_new
更多推荐

所有评论(0)