flutter源码依赖简单demo(名字为onlyone):
flutter混合开发中,会有flutter module和flutter plugin
1.分别创建Flutter module和Flutter plugin
2.Flutter module的pubspec.yaml中引入flutter plugin依赖
only_one_flutter_plugin:
path: /Users/xufangzhen/FlutterProjects/only_one_flutter_plugin
3.将Flutter Module import进android工程
android工程中修改点如下:
1.settings.gradle文件中创建对flutter module进行评估,并引入
setBinding(new Binding([gradle: this]))
evaluate(new File(settingsDir, './only_one_flutter_module/.android/include_flutter.groovy'))
include ':only_one_flutter_module'
project(':only_one_flutter_module').projectDir = new File('xxx/only_one_flutter_module')
4.在app module中的build.gradle中引入
implementation project(path: ':flutter')
implementation project(path: ':only_one_flutter_plugin')
可能会遇到问题:
- 使用flutter v1.12,需要升级android的target sdk 为28及以上
- 如果你的工程没有使用androidx,那么你需要将flutter mo,dule中的pubspec.yaml文件里androidX: true去掉。
- setting include工程的工程 only_one_flutter_module后,原android工程无法断点调试,只需要将include的名字和路径改成only_one_flutter_module的父目录即可。
引入闲鱼的 flutter_boost
flutter_boost引入主要是解决native跳flutter重复创建flutter engine引题内存等问题,具体可以去闲鱼博客上了解。
到了flutter sdk是1.12.x,flutter engine可以复用了,具体还没看
具体使用如下:
在flutter plugin中pubspec.yarml的,使用引入flutter_boost
查看git上的介绍,不支持android x,flutter sdk是1.12的,使用以下配置
flutter_boost:
git:
url: 'https://github.com/alibaba/flutter_boost.git'
ref: 'task/task_v1.12.13_support_hotfixes'
flutter plugin 的 android工程的app的build.gradle中添加
api project(path: ':flutter_boost')
在flutter module的main()方法中,调用plugin的初始化方法
return MaterialApp(
builder: OnlyOnePlugin.init({
'one': (pageName, params, _) {
return OnePage();
},
'twoPage': (pageName, params, _) {
return TwoPage();
},
}),
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
在flutter plugin的lib下创建的OnlyOnePlugin类,
并增加注册、跳转和关闭方法
class OnlyOnePlugin {
static TransitionBuilder init(Map<String, PageBuilder> builders) {
FlutterBoost.singleton.registerPageBuilders(builders);
return FlutterBoost.init();
}
static Future<Map<dynamic, dynamic>> openPage(String pageName,
{Map<dynamic, dynamic> data, Map<dynamic, dynamic> exts}) async {
return FlutterBoost.singleton
.open(changeToRouterUrl(pageName), urlParams: data, exts: exts);
}
static Future<bool> closePage(BuildContext context,
{Map<String, dynamic> data, bool animate}) async {
if (null == context) return Future.value(false);
String uniqueId = BoostContainer.of(context)?.settings?.uniqueId ?? "";
return FlutterBoost.singleton.close(uniqueId, result: data, exts: null);
}
static const MethodChannel _channel =
const MethodChannel('only_one_flutter_plugin');
static Future<String> get platformVersion async {
final String version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
……
}
在flutter plugin的android工程中,进行初始化、容器、bridge等工作开发
初始化:
在application的create方法中调用初始化方法
public static void initBoost(Application application) {
FlutterBoost.BoostLifecycleListener boostLifecycleListener = new FlutterBoost.BoostLifecycleListener() {
@Override
public void beforeCreateEngine() {
}
@Override
public void onEngineCreated() {
}
@Override
public void onPluginsRegistered() {
}
@Override
public void onEngineDestroy() {
}
};
INativeRouter router = new INativeRouter() {
@Override
public void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) {
openPage(context, url, urlParams, requestCode, exts);
}
};
Platform platform = new FlutterBoost
.ConfigBuilder(application, router)
.isDebug(isDebug)
.whenEngineStart(FlutterBoost.ConfigBuilder.ANY_ACTIVITY_CREATED)
.renderMode(FlutterView.RenderMode.texture)
.lifecycleListener(boostLifecycleListener)
.build();
FlutterBoost.instance().init(platform);
}
遇到问题:
- FlutterBoostPlugin not register yet
如果出现上面的问题,说明flutter module的android工程里,GeneratedPluginRegistrant
无法自动生成。com.idlefish.flutterboost.FlutterBoostPlugin.registerWith(shimPluginRegistry.registrarFor("com.idlefish.flutterboost.FlutterBoostPlugin"));
早期遇到这个问题需要手动注册,现在flutter_boost已经修复
容器:
可以自己写个Flutter容器,加载FlutterBoost里的flutterFragment
再带个启动方法,(用路由的结合下路由,这里略去)
public static void launch(Activity context, String pageName, JSONObject param, int requestCode) {
Intent intent = new Intent(context, OnlyFlutterActivity.class);
intent.putExtra(PAGE_NAME_KEY, pageName);
intent.putExtra(ROUTER_PARAM_KEY, param);
context.startActivityForResult(intent, requestCode);
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.only_flutter_activity);
String pageName = getIntent().getStringExtra(PAGE_NAME_KEY);
HashMap params = (HashMap) getIntent().getSerializableExtra(ROUTER_PARAM_KEY);
mFragment = new FlutterFragment.NewEngineFragmentBuilder().url(pageName).params(params).build();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_stub, mFragment)
.commit();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mFragment.onActivityResult(requestCode, resultCode, data);
}
其中pageName就是在flutter module里注册进去的页面名。
return MaterialApp(
builder: OnlyOneFlutterPlugin.init({
'onePage': (pageName, params, _) {
print("params = " + params.toString());
return OnePage(title: "标题1");
},
'twoPage': (pageName, params, _) {
return TwoPage(title: "标题2");
},
}),
……
上面看到已经看到了native跳flutter
flutter跳flutter或者flutter跳native只需要调用flutter plugin lib下OnlyOneFlutterPlugin的openPage方法即可
//flutter跳flutter
OnlyOneFlutterPlugin.openPage("twoPage", data: params);
//flutter跳native
OnlyOneFlutterPlugin.openPage("MainActivity", data: params);
flutter端不管跳flutter还是native都调用了
FlutterBoost.singleton.open方法,最终会触发下面这个在初始化时的回调。
INativeRouter router = new INativeRouter() {
@Override
public void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) {
openPage(context, url, urlParams, requestCode, exts);
}
};
我们只需要在openPage的方法中写下时跳native页面还是flutter页面即可。
这里简单的示意下,正确的做法还是要在路由器的拦截器方法里写
static void openPage(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) {
if ("onePage".equals(url) || "twoPage".equals(url)) {
……
OnlyFlutterActivity.launch ……
} else {
……
AppRouter.launch ……
}
}
网友评论