Commit eeebe1d6 authored by justin's avatar justin Committed by GitHub

Merge pull request #710 from nightfallsad/master

fix android platform demo, add custom method channel demo, add integration.md
parents 4eee7d3d 14d8bfa0
1、为何使用flutter_boost?
官方的集成方案有诸多弊病:
- 日志不能输出到原生端;
- 存在内存泄漏的问题,使用boost可以让内存稳定;
- native调用flutter,flutter调用native,通道的封装,使开发更加简便;
- 同时对于页面生命周期的管理,也梳理的比较整齐
2、集成流程IOS
在delegate中做flutter初始化的工作
```
在appDelegate中引入,PlatformRouterImp,用于实现平台侧的页面打开和关闭,不建议直接使用用于页面打开,建议使用FlutterBoostPlugin中的open和close方法来打开或关闭页面;
PlatformRouterImp内部实现打开各种native页面的映射。
self.router = [PlatformRouterImp new];
//初始化FlutterBoost混合栈环境。应在程序使用混合栈之前调用。如在AppDelegate中。本函数默认需要flutter boost来注册所有插件。
[FlutterBoostPlugin.sharedInstance startFlutterWithPlatform:self.router
onStart:^(FlutterEngine *engine) {
}];
```
PlatformRouterImp,内部实现打开native页面的路由代码截图
```
- (void)open:(NSString *)name
urlParams:(NSDictionary *)params
exts:(NSDictionary *)exts
completion:(void (^)(BOOL))completion
{
if ([name isEqualToString:@"page1"]) {//打开页面1
// 打开页面1的vc
return;
}
BOOL animated = [exts[@"animated"] boolValue];
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController pushViewController:vc animated:animated];
if(completion) completion(YES);
}
```
如何打开,关闭flutter页面,直接调用FlutterBoostPlugin的类方法即可。
```
/**
* 关闭页面,混合栈推荐使用的用于操作页面的接口
*
* @param uniqueId 关闭的页面唯一ID符
* @param resultData 页面要返回的结果(给上一个页面),会作为页面返回函数的回调参数
* @param exts 额外参数
* @param completion 关闭页面的即时回调,页面一旦关闭即回调
*/
+ (void)close:(NSString *)uniqueId
result:(NSDictionary *)resultData
exts:(NSDictionary *)exts
completion:(void (^)(BOOL))completion;
/**
* 打开新页面(默认以push方式),混合栈推荐使用的用于操作页面的接口;通过urlParams可以设置为以present方式打开页面:urlParams:@{@"present":@(YES)}
*
* @param url 打开的页面资源定位符
* @param urlParams 传人页面的参数; 若有特殊逻辑,可以通过这个参数设置回调的id
* @param exts 额外参数
* @param resultCallback 当页面结束返回时执行的回调,通过这个回调可以取得页面的返回数据,如close函数传入的resultData
* @param completion 打开页面的即时回调,页面一旦打开即回调
*/
+ (void)open:(NSString *)url
urlParams:(NSDictionary *)urlParams
exts:(NSDictionary *)exts
onPageFinished:(void (^)(NSDictionary *))resultCallback
completion:(void (^)(BOOL))completion;
/**
* Present方式打开新页面,混合栈推荐使用的用于操作页面的接口
*
* @param url 打开的页面资源定位符
* @param urlParams 传人页面的参数; 若有特殊逻辑,可以通过这个参数设置回调的id
* @param exts 额外参数
* @param resultCallback 当页面结束返回时执行的回调,通过这个回调可以取得页面的返回数据,如close函数传入的resultData
* @param completion 打开页面的即时回调,页面一旦打开即回调
*/
+ (void)present:(NSString *)url
urlParams:(NSDictionary *)urlParams
exts:(NSDictionary *)exts
onPageFinished:(void (^)(NSDictionary *))resultCallback
completion:(void (^)(BOOL))completion;
```
IOS如何传递数据给flutter
```
//name是事件的名称,arguments中是一个NSDictionary,OC代码
[FlutterBoostPlugin.sharedInstance sendEvent:@"name" arguments:@{}];
//flutter部分接收数据,dart代码
FlutterBoost.singleton.channel.addEventListener('name',
(name, arguments){
//todo
return;
});
```
flutter如何传递数据给native
```
//flutter代码,ChannelName是通道名称与native部分一致即可,tmp是map类型的参数
Map<String,dynamic> tmp = Map<String,dynamic>();
try{
FlutterBoost.singleton.channel.sendEvent(ChannelName, tmp);
}catch(e){
}
//IOS侧代码
[FlutterBoostPlugin.sharedInstance addEventListener:^(NSString *name, NSDictionary *arguments) {
} forName:@"statistic"];
```
flutter中页面的生命周期管理
```
enum ContainerLifeCycle {
Init,
Appear,//已经出现,很遗憾的是如果在native部分present页面,这里是不会回调的。
WillDisappear,
Disappear,
Destroy,
Background,
Foreground
}
FlutterBoost.singleton.addBoostContainerLifeCycleObserver(//这个类是单例,再每个页面的initState方法中添加即可监听
(ContainerLifeCycle state, BoostContainerSettings settings) {
//setttings是配置,name表示页面的名称,建议一定要等到当前页面Appear状态的时候再做操作,
print(
'FlutterBoost.singleton.addBoostContainerLifeCycleObserver '+state.toString()+' '+settings.name);
},
);
```
关于flutter部分打开新页面的回调的一些坑。
```
FlutterBoost.singleton
.open(CoursePage.routeName, urlParams: {
}).then((Map<dynamic, dynamic> value) {
print(
'call me when page is finished. did recieve second route result $value');
//这个方法会优先于addBoostContainerLifeCycleObserver中的appear方法调用,所以说有些方法在这里调用,如果appear还没有出现的话就会有问题。
});
```
3、集成流程Android(待补充)
\ No newline at end of file
...@@ -5,18 +5,19 @@ ...@@ -5,18 +5,19 @@
<b></b><br> <b></b><br>
<a href="README_CN.md">中文文档</a> <a href="README_CN.md">中文文档</a>
<a href="https://mp.weixin.qq.com/s?__biz=MzU4MDUxOTI5NA==&mid=2247484367&idx=1&sn=fcbc485f068dae5de9f68d52607ea08f&chksm=fd54d7deca235ec86249a9e3714ec18be8b2d6dc580cae19e4e5113533a6c5b44dfa5813c4c3&scene=0&subscene=131&clicktime=1551942425&ascene=7&devicetype=android-28&version=2700033b&nettype=ctnet&abtest_cookie=BAABAAoACwASABMABAAklx4AVpkeAMSZHgDWmR4AAAA%3D&lang=zh_CN&pass_ticket=1qvHqOsbLBHv3wwAcw577EHhNjg6EKXqTfnOiFbbbaw%3D&wx_header=1">中文介绍</a> <a href="https://mp.weixin.qq.com/s?__biz=MzU4MDUxOTI5NA==&mid=2247484367&idx=1&sn=fcbc485f068dae5de9f68d52607ea08f&chksm=fd54d7deca235ec86249a9e3714ec18be8b2d6dc580cae19e4e5113533a6c5b44dfa5813c4c3&scene=0&subscene=131&clicktime=1551942425&ascene=7&devicetype=android-28&version=2700033b&nettype=ctnet&abtest_cookie=BAABAAoACwASABMABAAklx4AVpkeAMSZHgDWmR4AAAA%3D&lang=zh_CN&pass_ticket=1qvHqOsbLBHv3wwAcw577EHhNjg6EKXqTfnOiFbbbaw%3D&wx_header=1">中文介绍</a>
<a href="INTEGRATION.md">集成相关</a>
</p> </p>
# Release Note # Release Note
Please checkout the release note for the latest 0.1.64 to see changes [0.1.64 release note](https://github.com/alibaba/flutter_boost/releases) Please checkout the release note for the latest 1.12.13+1 to see changes [1.12.13+1 release note](https://github.com/alibaba/flutter_boost/releases)
# FlutterBoost # FlutterBoost
A next-generation Flutter-Native hybrid solution. FlutterBoost is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts.The philosophy of FlutterBoost is to use Flutter as easy as using a WebView. Managing Native pages and Flutter pages at the same time is non-trivial in an existing App. FlutterBoost takes care of page resolution for you. The only thing you need to care about is the name of the page(usually could be an URL).  A next-generation Flutter-Native hybrid solution. FlutterBoost is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts.The philosophy of FlutterBoost is to use Flutter as easy as using a WebView. Managing Native pages and Flutter pages at the same time is non-trivial in an existing App. FlutterBoost takes care of page resolution for you. The only thing you need to care about is the name of the page(usually could be an URL). 
<a name="bf647454"></a> <a name="bf647454"></a>
# Prerequisites # Prerequisites
You need to add Flutter to your project before moving on.The version of the flutter SDK requires v1.9.1+hotfixes, or it will compile error. You need to add Flutter to your project before moving on.The version of the flutter SDK requires to match boost's version, or it will compile error.
...@@ -24,13 +25,8 @@ You need to add Flutter to your project before moving on.The version of the flut ...@@ -24,13 +25,8 @@ You need to add Flutter to your project before moving on.The version of the flut
| Flutter Boost Version | Support Flutter SDK Version | Description | Support AndroidX? | | Flutter Boost Version | Support Flutter SDK Version | Description | Support AndroidX? |
| --------------------- | --------------------------- | ------------------------------------------------------------ | ------------------ | | --------------------- | --------------------------- | ------------------------------------------------------------ | ------------------ |
| 0.1.50 | 1.5.4-hotfixes | android if other flutter versions or branches will compile incorrectly. | No |
| 0.1.51-0.1.59 | 1.5.4-hotfixes | bugfix for 0.1.50. | No |
| 0.1.60 | 1.9.1-hotfixes | Android does not support andriodx if other flutter branches will compile incorrectly. | No |
| 0.1.61-0.1.69 | 1.9.1-hotfixes | bugfix for 0.1.60. | No |
| 0.1.63 | 1.9.1-hotfixes | If other branches will compile incorrectly. Synchronize with the 0.1.60 code, and bugfix also merge to this branch. | No |
| 1.9.1+2 | 1.9.1-hotfixes | Rename the version number and start supporting androidx by default | Yes | | 1.9.1+2 | 1.9.1-hotfixes | Rename the version number and start supporting androidx by default | Yes |
| 1.12.13 | 1.12.13-hotfixes | supporting androidx | Yes | | 1.12.13+1 | 1.12.13-hotfixes | supporting androidx | Yes |
...@@ -39,10 +35,7 @@ You need to add Flutter to your project before moving on.The version of the flut ...@@ -39,10 +35,7 @@ You need to add Flutter to your project before moving on.The version of the flut
| Flutter Boost branch | Support Flutter SDK Version | Description | Support AndroidX? | | Flutter Boost branch | Support Flutter SDK Version | Description | Support AndroidX? |
| --------------------- | --------------------------- | ------------------------------------------------------------ | ------------------ | | --------------------- | --------------------------- | ------------------------------------------------------------ | ------------------ |
| v1.9.1-hotfixes | 1.9.1-hotfixes | for androidx | Yes | | v1.9.1-hotfixes | 1.9.1-hotfixes | for androidx | Yes |
| task/task_v1.9.1_support_hotfixes| 1.9.1-hotfixes | for support | NO |
| v1.12.13-hotfixes | 1.12.13-hotfixes | for androidx | Yes | | v1.12.13-hotfixes | 1.12.13-hotfixes | for androidx | Yes |
| task/task_v1.12.13_support_hotfixes| 1.12.13-hotfixes | for support | NO |
# Getting Started # Getting Started
...@@ -56,14 +49,7 @@ androidx branch ...@@ -56,14 +49,7 @@ androidx branch
flutter_boost: flutter_boost:
git: git:
url: 'https://github.com/alibaba/flutter_boost.git' url: 'https://github.com/alibaba/flutter_boost.git'
ref: ' 1.12.13' ref: '1.12.13+1'
```
support branch
```json
flutter_boost:
git:
url: 'https://github.com/alibaba/flutter_boost.git'
ref: 'task/task_v1.12.13_support_hotfixes'
``` ```
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
# Release Note # Release Note
请查看最新版本0.1.64的release note 确认变更,[0.1.64 release note](https://github.com/alibaba/flutter_boost/releases) 请查看最新版本1.12.13+1的release note 确认变更,[1.12.13+1 release note](https://github.com/alibaba/flutter_boost/releases)
# FlutterBoost # FlutterBoost
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
# 前置条件 # 前置条件
在继续之前,您需要将Flutter集成到你现有的项目中。flutter sdk 的版本需要 v1.9.1-hotfixes,否则会编译失败. 在继续之前,您需要将Flutter集成到你现有的项目中。flutter sdk 的版本需要和boost版本适配,否则会编译失败.
# FAQ # FAQ
请阅读这篇文章: 请阅读这篇文章:
...@@ -24,25 +24,17 @@ ...@@ -24,25 +24,17 @@
| Flutter Boost 版本 | 支持的 Flutter SDK 版本 | Description | 是否支持 AndroidX? | | Flutter Boost 版本 | 支持的 Flutter SDK 版本 | Description | 是否支持 AndroidX? |
| ----------------------- | ----------------------- | ------------------------------------------------------------ | ------------------- | | ----------------------- | ----------------------- | ------------------------------------------------------------ | ------------------- |
| 0.1.50 | 1.5.4-hotfixes | android 如果其他 flutter 版本或者分支会编译错误。 | No |
| 0.1.51-0.1.59 | 1.5.4-hotfixes | 0.1.50 的 bugfix。 | No |
| 0.1.60 | 1.9.1-hotfixes | android 如果其他 flutter 分支会编译错误。 | No |
| 0.1.63 | 1.9.1-hotfixes | 和 0.1.60 代码同步, bugfix 也会合入该分支,如果其他分支会编译错误。 | No |
| 0.1.61-0.1.69 | 1.9.1-hotfixes | 0.1.60 的 bugfix。 | No |
| 1.9.1+2 | 1.9.1-hotfixes | 版本号重新命名,开始默认支持androidx | Yes | | 1.9.1+2 | 1.9.1-hotfixes | 版本号重新命名,开始默认支持androidx | Yes |
| 1.12.13 | 1.12.13 -hotfixes | 支持androidx | Yes | | 1.12.13+1 | 1.12.13 -hotfixes | 支持androidx | Yes |
| Flutter Boost 分支 | 支持的 Flutter SDK 版本 | Description | Support AndroidX? | | Flutter Boost 分支 | 支持的 Flutter SDK 版本 | Description | 是否支持 AndroidX? |
| --------------------- | --------------------------- | ------------------------------------------------------------ | ------------------ | | --------------------- | --------------------------- | ------------------------------------------------------------ | ------------------ |
| v1.9.1-hotfixes | 1.9.1-hotfixes | for androidx | Yes | | v1.9.1-hotfixes | 1.9.1-hotfixes | for androidx | Yes |
| task/task_v1.9.1_support_hotfixes| 1.9.1-hotfixes | for support | NO |
| v1.12.13-hotfixes | 1.12.13-hotfixes | for androidx | Yes | | v1.12.13-hotfixes | 1.12.13-hotfixes | for androidx | Yes |
| task/task_v1.12.13_support_hotfixes| 1.12.13-hotfixes | for support | NO |
# 安装 # 安装
...@@ -56,15 +48,7 @@ androidx branch ...@@ -56,15 +48,7 @@ androidx branch
flutter_boost: flutter_boost:
git: git:
url: 'https://github.com/alibaba/flutter_boost.git' url: 'https://github.com/alibaba/flutter_boost.git'
ref: '1.12.13' ref: '1.12.13+1'
```
support branch
```json
flutter_boost:
git:
url: 'https://github.com/alibaba/flutter_boost.git'
ref: 'task/task_v1.12.13_support_hotfixes'
``` ```
......
...@@ -3,9 +3,11 @@ package com.taobao.idlefish.flutterboostexample; ...@@ -3,9 +3,11 @@ package com.taobao.idlefish.flutterboostexample;
import android.app.Application; import android.app.Application;
import android.content.Context; import android.content.Context;
import android.os.Build;
import android.util.Log; import android.util.Log;
import com.idlefish.flutterboost.*; import com.idlefish.flutterboost.*;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.idlefish.flutterboost.interfaces.INativeRouter; import com.idlefish.flutterboost.interfaces.INativeRouter;
...@@ -13,7 +15,7 @@ import io.flutter.embedding.android.FlutterView; ...@@ -13,7 +15,7 @@ import io.flutter.embedding.android.FlutterView;
import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry; import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.GeneratedPluginRegistrant; import io.flutter.plugin.common.StandardMessageCodec;
public class MyApplication extends Application { public class MyApplication extends Application {
...@@ -41,6 +43,26 @@ public class MyApplication extends Application { ...@@ -41,6 +43,26 @@ public class MyApplication extends Application {
@Override @Override
public void onEngineCreated() { public void onEngineCreated() {
// 注册MethodChannel,监听flutter侧的getPlatformVersion调用
MethodChannel methodChannel = new MethodChannel(FlutterBoost.instance().engineProvider().getDartExecutor(), "flutter_native_channel");
methodChannel.setMethodCallHandler((call, result) -> {
if (call.method.equals("getPlatformVersion")) {
result.success(Build.VERSION.RELEASE);
} else {
result.notImplemented();
}
});
// 注册PlatformView viewTypeId要和flutter中的viewType对应
FlutterBoost
.instance()
.engineProvider()
.getPlatformViewsController()
.getRegistry()
.registerViewFactory("plugins.test/view", new TextPlatformViewFactory(StandardMessageCodec.INSTANCE));
} }
@Override @Override
......
package com.taobao.idlefish.flutterboostexample;
import io.flutter.app.FlutterPluginRegistry;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.StandardMessageCodec;
public class TextPlatformViewPlugin {
public static void register(PluginRegistry.Registrar registrar) {
registrar.platformViewRegistry().registerViewFactory("plugins.test/view",
new TextPlatformViewFactory(StandardMessageCodec.INSTANCE));
}
}
...@@ -23,8 +23,22 @@ ...@@ -23,8 +23,22 @@
PlatformRouterImp *router = [PlatformRouterImp new]; PlatformRouterImp *router = [PlatformRouterImp new];
[FlutterBoostPlugin.sharedInstance startFlutterWithPlatform:router [FlutterBoostPlugin.sharedInstance startFlutterWithPlatform:router
onStart:^(FlutterEngine *engine) { onStart:^(FlutterEngine *engine) {
}]; // 注册MethodChannel,监听flutter侧的getPlatformVersion调用
FlutterMethodChannel *flutterMethodChannel = [FlutterMethodChannel methodChannelWithName:@"flutter_native_channel" binaryMessenger:engine.binaryMessenger];
[flutterMethodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
NSString *method = call.method;
if ([method isEqualToString:@"getPlatformVersion"]) {
NSString *sysVersion = [[UIDevice currentDevice] systemVersion];
result(sysVersion);
} else {
result(FlutterMethodNotImplemented);
}
}];
}];
self.window = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds]; self.window = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds];
......
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_boost/flutter_boost.dart'; import 'package:flutter_boost/flutter_boost.dart';
import 'package:flutter_boost_example/platform_view.dart'; import 'package:flutter_boost_example/platform_view.dart';
...@@ -11,6 +12,24 @@ class FirstRouteWidget extends StatefulWidget { ...@@ -11,6 +12,24 @@ class FirstRouteWidget extends StatefulWidget {
class _FirstRouteWidgetState extends State<FirstRouteWidget> { class _FirstRouteWidgetState extends State<FirstRouteWidget> {
_FirstRouteWidgetState(); _FirstRouteWidgetState();
// flutter 侧MethodChannel配置,channel name需要和native侧一致
static const MethodChannel _methodChannel = MethodChannel('flutter_native_channel');
String _systemVersion = '';
Future<dynamic> _getPlatformVersion() async {
try {
final String result = await _methodChannel.invokeMethod('getPlatformVersion');
print('getPlatformVersion:' + result);
setState(() {
_systemVersion = result;
});
} on PlatformException catch (e) {
print(e.message);
}
}
@override @override
void initState() { void initState() {
print('initState'); print('initState');
...@@ -111,6 +130,10 @@ class _FirstRouteWidgetState extends State<FirstRouteWidget> { ...@@ -111,6 +130,10 @@ class _FirstRouteWidgetState extends State<FirstRouteWidget> {
}); });
}, },
), ),
RaisedButton(
child: Text('Get system version by method channel:' + _systemVersion),
onPressed: () => _getPlatformVersion(),
),
], ],
), ),
), ),
...@@ -318,6 +341,25 @@ class FlutterRouteWidget extends StatefulWidget { ...@@ -318,6 +341,25 @@ class FlutterRouteWidget extends StatefulWidget {
} }
class _FlutterRouteWidgetState extends State<FlutterRouteWidget> { class _FlutterRouteWidgetState extends State<FlutterRouteWidget> {
// flutter 侧MethodChannel配置,channel name需要和native侧一致
static const MethodChannel _methodChannel = MethodChannel('flutter_native_channel');
String _systemVersion = '';
Future<dynamic> _getPlatformVersion() async {
try {
final String result = await _methodChannel.invokeMethod('getPlatformVersion');
print('getPlatformVersion:' + result);
setState(() {
_systemVersion = result;
});
} on PlatformException catch (e) {
print(e.message);
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final String message = widget.message; final String message = widget.message;
...@@ -509,6 +551,17 @@ class _FlutterRouteWidgetState extends State<FlutterRouteWidget> { ...@@ -509,6 +551,17 @@ class _FlutterRouteWidgetState extends State<FlutterRouteWidget> {
onTap: () => onTap: () =>
FlutterBoost.singleton.open('sample://flutterFragmentPage'), FlutterBoost.singleton.open('sample://flutterFragmentPage'),
), ),
InkWell(
child: Container(
padding: const EdgeInsets.all(8.0),
margin: const EdgeInsets.all(8.0),
color: Colors.yellow,
child: Text(
'get system version by method channel:' + _systemVersion,
style: TextStyle(fontSize: 22.0, color: Colors.black),
)),
onTap: () => _getPlatformVersion(),
),
], ],
), ),
), ),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment