其他
Flutter系列之混合开发Android篇
Flutter混合开发模式
Flutter Module的创建方式
添加Flutter的几种方式
添加单个Flutter页面
添加FlutterFragment
Flutter与Android互相跳转
Flutter混合开发模式
直接将原生项目作为 Flutter 项目的子项目,Flutter 默认会创建 android 和 ios 的工程目录;
创建 Flutter Module 作为依赖添加到现有的原生项目中。
Flutter Module的创建方式
使用命令创建 Flutter Module
使用 As 创建 Flutter Module
添加Flutter的几种方式
以 aar 的方式集成的 Android 现有项目中:
cd flutter_module
flutter build aar
maven {
url 'G:/xxx/flutter_module_one/build/host/outputs/repo'
}
maven {
url 'https://storage.googleapis.com/download.flutter.io'
}
}
buildTypes {
profile {
initWith debug
}
}
dependencies {
debugImplementation 'com.manu.flutter.flutter_module_one:flutter_debug:1.0'
profileImplementation 'com.manu.flutter.flutter_module_one:flutter_profile:1.0'
releaseImplementation 'com.manu.flutter.flutter_module_one:flutter_release:1.0'
}
以 Flutet module 的方式集成到现有 Android 项目中:
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir,
'flutter_module_two/.android/include_flutter.groovy'
))
implementation project(':flutter')
}
添加单个Flutter页面
android:name=".AgentActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
</activity>
myButton.setOnClickListener {
startActivity(
FlutterActivity.createDefaultIntent(this)
)
}
// 自定义路由
myButton.setOnClickListener {
startActivity(
FlutterActivity
.withNewEngine()
.initialRoute("/my_route")
.build(this)
)
}
Log.v(TAG, "Setting up FlutterEngine.");
// 1. 检查预缓存的FlutterEngine
String cachedEngineId = host.getCachedEngineId();
if (cachedEngineId != null) {
flutterEngine = FlutterEngineCache.getInstance().get(cachedEngineId);
isFlutterEngineFromHost = true;
if (flutterEngine == null) {
throw new IllegalStateException(
"The requested cached FlutterEngine did not exist in the FlutterEngineCache: '"
+ cachedEngineId
+ "'");
}
return;
}
// 2. 是否有自定义的FlutterEngine
// Second, defer to subclasses for a custom FlutterEngine.
flutterEngine = host.provideFlutterEngine(host.getContext());
if (flutterEngine != null) {
isFlutterEngineFromHost = true;
return;
}
Log.v(
TAG,
"No preferred FlutterEngine was provided. Creating a new FlutterEngine for"
+ " this FlutterFragment.");
// 3. 创建新的FlutterEngine
flutterEngine =
new FlutterEngine(
host.getContext(),
host.getFlutterShellArgs().toArray(),
/*automaticallyRegisterPlugins=*/ false);
isFlutterEngineFromHost = false;
}
添加FlutterFragment
private val flutterFragmentTag = "flutter_fragment_tag"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_agent2)
val fragmentManager = supportFragmentManager
var flutterFragment = fragmentManager.findFragmentByTag(flutterFragmentTag)
if (flutterFragment == null){
// flutterFragment = FlutterFragment.createDefault()
flutterFragment = MFlutterFragment
.withNewEngine()
?.build()
if (flutterFragment != null) {
fragmentManager.beginTransaction()
.add(R.id.ff_container,flutterFragment,flutterFragmentTag)
.commit()
}
}
}
}
val intent = Intent(this@LaunchActivity,AgentActivity2::class.java)
startActivity(intent)
Flutter与Android互相跳转
class AgentActivity : FlutterActivity() {
private val tag = AgentActivity::class.java.simpleName;
private val channel = "com.manu.startMainActivity"
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
Log.d(tag,"configureFlutterEngine")
// 注册MethodChannel,用来监听Flutter页面的方法调用
MethodChannel(flutterEngine.dartExecutor, channel)
.setMethodCallHandler { methodCall: MethodCall, result: MethodChannel.Result ->
if ("startMainActivity" == methodCall.method) {
MainActivity.startMainActivity(this)
result.success("success")
} else {
result.notImplemented()
}
}
}
companion object{
/**
* 重新创建NewEngineIntentBuilder才能保证生效
*/
fun withNewEngine(): MNewEngineIntentBuilder? {
return MNewEngineIntentBuilder(AgentActivity::class.java)
}
}
/**
* 自定义NewEngineIntentBuilder
*/
class MNewEngineIntentBuilder(activityClass: Class<out FlutterActivity?>?) :
NewEngineIntentBuilder(activityClass!!)
}
// 同理FlutterFragment也一样
// 省略 ...
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Flutter Page"),
centerTitle: true,
),
body: PageWidget()
),
routes: <String,WidgetBuilder>{
},
);
}
}
/// Stateful Widget
class PageWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _PageState();
}
}
/// State
class _PageState extends State<PageWidget> {
MethodChannel platform;
@override
void initState() {
super.initState();
platform = new MethodChannel('com.manu.startMainActivity');
}
@override
Widget build(BuildContext context) {
return RaisedButton(
onPressed: () {
_startMainActivity();
},
child: Text("Flutter to Android"),
);
}
/// 跳转到原生Activity
void _startMainActivity(){
platform.invokeMethod('startMainActivity').then((value) {
print("value:startMainActivity");
}).catchError((e) {
print(e.message);
});
}
}