Flutter系列之混合开发Android篇
躬行之
共 15801字,需浏览 32分钟
· 2020-08-12
Flutter混合开发模式
Flutter Module的创建方式
添加Flutter的几种方式
添加单个Flutter页面
添加FlutterFragment
Flutter与Android互相跳转
Flutter混合开发模式
直接将原生项目作为 Flutter 项目的子项目,Flutter 默认会创建 android 和 ios 的工程目录;
创建 Flutter Module 作为依赖添加到现有的原生项目中。
Flutter Module的创建方式
使用命令创建 Flutter Module
flutter create -t module --org com.manu.flutter flutter_module_one
使用 As 创建 Flutter Module
添加Flutter的几种方式
以 aar 的方式集成的 Android 现有项目中:
// cd到Flutter Module根目录
cd flutter_module
flutter build aar
repositories {
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 项目中:
include ':app'
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir,
'flutter_module_two/.android/include_flutter.groovy'
))
dependencies {
implementation project(':flutter')
}
添加单个Flutter页面
<activity
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)
)
}
/* package */ void setupFlutterEngine() {
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
class AgentActivity2 : FragmentActivity() {
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()
}
}
}
}
// 跳转添加Fragment的Activyt
val intent = Intent(this@LaunchActivity,AgentActivity2::class.java)
startActivity(intent)
Flutter与Android互相跳转
// FlutterActivity
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也一样
// 省略 ...
void main() => runApp(MyApp());
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
StatecreateState() {
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);
});
}
}
评论
Go 1.22 的新增功能系列之二:reflect.TypeFor
Go 1.22 的第一个候选版本已经发布,这意味着最终版本即将发布,现在是我在博客中介绍我在这个周期中所做工作的时候了。像往常一样,我的贡献很小,但它们是我的,所以我将从幕后的角度来谈谈它们。首先是reflect.TypeFor。这是整个函数:// TypeFor returns the [Type
GoCN
0
为什么我们公司还在用 Python 开发项目?
作者:哇哒嘻哇https://www.zhihu.com/question/278798145/answer/3416549119最近几年里,经常看到某些曾重度使用 Python 的大公司迁移成其它语言技术栈,但是,那些小公司/小团队的情况如何呢?一直很想了解那些仍在坚持使用 Python,且支撑业
机器学习算法与Python实战
0
Go 1.22 的新增功能系列之一:cmp.Or
截至撰写本文时,Go 1.22 已经发布几个月了。早就该结束我为 1.22 所做的工作的系列了。抱歉耽搁了这么久,我最近忙于生活事务。如果您错过了我关于reflect.TypeFor(https://blog.carlana.net/post/2024/golang-reflect-type-for
GoCN
1
全新 SOTA backbone | 2024年了,再见ViT系列Backbone,实数难得,不知道效果如何?
点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达在构建用于精确匹配的深度固定长度表示时,确定指纹上的密集特征点,特别是在像素 Level 上,具有重大意义。为了探索指纹匹配的可解释性,作者提出了一种多阶段可解释的指纹匹配网络,名为通过视觉 Transformer 进行指纹匹配的
小白学视觉
10
嵌入式开发的尽头是什么?
知乎问题,摘选了一个回答大家也可以评论说自己的看法首先转管理岗当然是可以的。。这个几乎是废话,啥行业做到最后,都可以选择当部门经理。。如果是技术岗位。。那就是全栈工程师。。其实,嵌入式软件开发最大的缺点就是,接触不到供应链。。没法单干。。我给你讲一个故事。。我在2020年的时候,在一家嵌入式开发公司
嵌入式Linux
10
嵌入式开发的一个骚操作!
关注、星标公众号,直达精彩内容来源 | 网络目录1 映射表在串口数据解析中的应用1.1 数据结构1.2 指令、函数映射表1.3 串口解析函数实现2 映射表在UI设计中的应用2.1 数据结构2.2 函数映射表2.3 定义两个变量保存当前场景和上一个场景2.4 按下Up按键
李肖遥
0
带你玩转Linux系统之lscpu命令
链接:https://bbs.huaweicloud.com/blogs/422603一、lscpu命令介绍lscpu 是一个 Linux 命令,用于显示CPU架构的详细信息。它可以用来查看 CPU 的型号、主频、架构、虚拟化支持等。二、lscpu命令的使用帮助2.1 命令格式lscpu [选项]2
良许Linux
0
C语言基础之动态内存操作汇总
来源:机器之心1、堆区空间申请#include <stdlib.h> //头文件void *malloc(size_t size);//函数size表示申请的空间字节数函数的返回值:成功:返回值空间起始地址失败:NULL特点:分配指定大小的内存空间;分配的内存空间是连续的;需要手动释放
良许Linux
0