「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」
首先创建一个Android原生项目,然后可以选择直接创建一个Flutter Project (选择Flutter Module),也可以直接创建一个 New Module(选择Flutter Module)。前者是需要自己手动在Android项目中依赖的,后者则是直接依赖在当前Android项目中的。新手建议后者。
参考google官方中文文档如下:
flutter.cn/docs/develo…
一、准备工作:
1.创建一个Android原生项目
2.创建一个Flutter module
二、采用aar方式集成Flutter module到Android原生
1.执行命令 flutter build aar 成功之后打印如下日志
`Consuming the Module`
`1``. Open <host>\app\build.gradle`
`2``. Ensure you have the repositories configured, otherwise add them:`
`String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?: ``"[https://storage.googleapis.com"](https://storage.googleapis.com/)`
`repositories {`
`maven {`
`url ``'E:\anima_demo\build\host\outputs\repo'`
`}`
`maven {`
`url ``"$storageUrl/download.flutter.io"`
`}`
`}`
`3``. Make the host app depend on the Flutter module:`
`dependencies {`
`debugImplementation ``'com.example.anima_demo:flutter_debug:1.0'`
`profileImplementation ``'com.example.anima_demo:flutter_profile:1.0'`
`releaseImplementation ``'com.example.anima_demo:flutter_release:1.0'`
`}`
`4``. Add the `profile` build type:`
`android {`
`buildTypes {`
`profile {`
`initWith debug`
`}`
`}`
`}`
上面的操作是在app下的build.gradle下面配置本地仓库和远程仓库。我试验的结果来看,似乎只有本地仓库会生效。
三、采用源码依赖Flutter Module到Android原生
1.把Android原生项目和Flutter项目放到同一目录下。
2.在Android原生的setting.gradle中做如下设置
// Include the host app project.
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
))
3.在Android中添加如下依赖
dependencies {
implementation project(':flutter')
}
四、总结两种依赖的优缺点
1.采用aar方式依赖。优点是原生不需要配置flutter开发环境。缺点是每次修改打包验证都需要重新打出aar包,如果是本地依赖还需要把结果物体给其他同事。远程依赖可能需要上传到自己的maven仓库。
2.采用源码方式依赖。优点是每次其他同事修改,只需要在module中点击pub get 或者 pub update即可更新。缺点是开发原生同事也需要配置flutter开发环境。
个人看法:Flutter开发,能够统一 两个端界面和逻辑的一致性,一份代码两个平台运行,可以提高整体的开发效率。所以原生开发可以学习下Flutter。最好还是采用源码依赖方式,这样多人合作开发Flutter效率会很高。
-
把flutter页面显示到原生中
一、在首页直接显示Flutter页面,直接把MainActivity继承io.flutter.embedding.android.FlutterActivity,这个包下是最新的FlutterActivity。
package com.example.nativeandflutterdemo
import android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
class MainActivity : FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
二、首页是原生的Activity ,在里面点击按钮在跳转到Flutter界面。
startActivity(Intent(this@MainActivity,FlutterActivity::class.java))
或者startActivity(FlutterActivity.createDefaultIntent(this))
需要注意的是一定要在AndroidManifest里面注册FlutterActivity
<activity android:name="io.flutter.embedding.android.FlutterActivity"/>
package com.example.nativeandflutterdemo
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import io.flutter.embedding.android.FlutterActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var tv = findViewById<TextView>(R.id.tv)
tv.setOnClickListener {
// startActivity(FlutterActivity.createDefaultIntent(this))
startActivity(Intent(this@MainActivity,FlutterActivity::class.java))
}
}
}
三、当有多个flutter页面的时候,需要从原生跳转到特定flutter页面
- 先创建两个flutter界面
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class OnePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Text('这是 One 页面'),
),
);
}
}
import 'package:flutter/cupertino.dart';
class TwoPage extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Container(child: Text("two Page"),);
}
}
- 在main.dart中的MaterialApp中添加routes,注册路由。
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or press Run > Flutter Hot Reload in a Flutter IDE). Notice that the
// counter didn't reset back to zero; the application is not restarted.
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
routes: {
"onePage": (context){
return OnePage();
},
"twoPage":(context){
return TwoPage();
}
},
);
}
}
- MainActivity的跳转也需要修改一下
startActivity(FlutterActivity.withNewEngine()
.initialRoute("twoPage")
.build(this))
到此为止,Native跳转到原生就结束了。不过发现跳转会有黑屏,因为FlutterActivity创建会启动FlutterEngine。所以尽量少创建FlutterActivity。然后可以对FlutterEngine进行缓存。
- 在Android 项目的Application中创建引擎(FlutterEngine)
class MyApplication : Application() {
lateinit var flutterEngine: FlutterEngine
override fun onCreate() {
super.onCreate()
flutterEngine = FlutterEngine(this)
flutterEngine.dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
)
FlutterEngineCache
.getInstance()
.put("engine_id", flutterEngine)
}
}
- 使用的时候通过缓存来获取引擎
startActivity(
FlutterActivity
.withCachedEngine("engine_id")
.build(this)
)