Flutter 混编快速开始
1 搭建flutter开发环境
flutter安装配置教程:https://flutter.dev/docs/get-started/install/macos
中国地区特别配置:https://flutter.dev/community/china
1.1 获取Flutter SDK
flutter官网下载其最新可用的安装包,解压安装包到你想安装的目录。
1.2 中国区用户环境变量配置:
export PATH=~/Develop/flutter/bin:$PATH
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
ANDROID_HOME=/Users/meicai/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/platform-tools
1.3 运行flutter doctor
该命令检查您的环境并在终端窗口中显示报告。
1.4 配置Android Studio
安装Flutter和Dart插件(Preferences>Plugins)
Flutter插件: 支持Flutter开发工作流 (运行、调试、热重载等)。
Dart插件: 提供代码分析 (输入代码时进行验证、代码补全等)。
2 flutter 和 native 混合开发
2.1 创建一个 Flutter module
androidstudio 创建 :File -> New -> New Module -> Flutter Module
命令行:$ flutter create -t module flutter_module
2.2 宿主 App 设置
Flutter 目前只支持 armeabi-v7a 和 arm64-v8a
android {
//...
defaultConfig {
ndk {
// Filter for architectures supported by Flutter.
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
}
Java 8 requirement
Flutter Android引擎使用Java 8特性
android {
//...
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
2.3 让 App 依赖 Flutter Module
有两种方案,直接依赖源代码和 aar 产物
2.3.1 依赖生成的 aar
构建aar:
androidstudio : flutter module 工程里 Build -> Flutter -> Build AAR
命令行:$ flutter build aar
配置:
MyApp/app/build.gradle
repositories {
maven {
url 'some/path/my_flutter/build/host/outputs/repo'
// This is relative to the location of the build.gradle file
// if using a relative path.
}
maven {
url 'http://download.flutter.io'
}
}
dependencies {
// ...
debugImplementation 'com.example.flutter_module:flutter_debug:1.0'
profileImplementation 'com.example.flutter_module:flutter_profile:1.0'
releaseImplementation 'com.example.flutter_module:flutter_release:1.0'
}
2.3.2 直接依赖源码
依赖 aar 的方式有点麻烦,还需要到 Module 中编译,所以也可以直接依赖源码编译。
MyApp/settings.gradle:
setBinding(newBinding([gradle: this]))
evaluate(newFile(
settingsDir.parentFile,
'my_flutter/.android/include_flutter.groovy'
))
上面的File()路径是 flutter module 相对 host app 的路径。binding 和 include_flutter.groovy 脚本引入 flutter module 本身和相关的 plugin。
依赖模块:
MyApp/app/build.gradle:
dependencies{
implementationproject(':flutter')
}
2.4 在 Android 项目中使用 Flutter Module
目前有两种方式实现,分别在
- io.flutter.facade.*
- io.flutter.embedding.android.*
2.4.1 io.flutter.facade
以前的方式,已经被deprecated。
通过使用 Flutter.createView:
fab.setOnClickListener(newView.OnClickListener() {
@Override
publicvoidonClick(View view){
View flutterView = Flutter.createView(
MainActivity.this,
getLifecycle(),
"route1"
);
FrameLayout.LayoutParams layout = newFrameLayout.LayoutParams(600, 800);
layout.leftMargin = 100;
layout.topMargin = 200;
addContentView(flutterView, layout);
}
});
通过使用 Flutter.createFragment:
fab.setOnClickListener(newView.OnClickListener() {
@Override
publicvoidonClick(View view){
FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
tx.replace(R.id.someContainer, Flutter.createFragment("route1"));
tx.commit();
}
});
2.4.2 io.flutter.embedding.android.*
FlutterView( 继承自 FrameLayout )
//FlutterEngine
FlutterEngine flutterEngine = newFlutterEngine(this);
// Configure an initial route.
flutterEngine.getNavigationChannel().setInitialRoute("route/example");
// Start executing Dart code to pre-warm the FlutterEngine.
flutterEngine.getDartExecutor().executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
);
FlutterEngineCache
.getInstance()
.put("my_engine_id", flutterEngine);
//添加flutterview的方式
FlutterView flutterView = newFlutterView(this);
FrameLayout frameLayout = findViewById(R.id.contentView);
frameLayout.addView(flutterView);
//创建一个 FlutterView 就可以了,这个时候还不会渲染。
//调用下面代码后才会渲染
flutterView.attachToFlutterEngine(flutterEngine);
FlutterFragment:
//use a newFlutterEngine
FlutterFragment flutterFragment = FlutterFragment.createDefault();
//use a pre-warmed FlutterEngine
FlutterFragment flutterFragment = FlutterFragment.withCachedEngine("my_engine_id").build();
FlutterActivity
在 AndroidManifest.xml 中注册
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard
|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
/>
默认启动方式
startActivity(
FlutterActivity.createDefaultIntent(currentActivity)
);
启动到指定路由
Intent customFlutter = newFlutterActivity.IntentBuilder()
.initialRoute("someOtherRoute")
.build(currentActivity);
startActivity(customFlutter);
也可以继承 FlutterActivity, FlutterFragment ,在Activity ,Fragment 中可以做一些处理