參考:https://www.jianshu.com/p/1a131deeee75
參考:https://www.jianshu.com/p/1770ded8f50f
一.混編
1.咸魚模式
Flutter打包成aar嵌入到原生工程
2.Google模式,Flutter頁面嵌入原生
public class MyFlutterActivity extends FragmentActivity {
FlutterFragment flutterFragment;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_flutter);
initFlutterEngine();
attachFlutterFragment();
}
String ENGINE_ID = "a";
private FlutterEngine initFlutterEngine() {
FlutterEngine flutterEngine = FlutterEngineCache.getInstance().get(ENGINE_ID);
if (null == flutterEngine) {
flutterEngine = new FlutterEngine(this);
flutterEngine.getNavigationChannel().setInitialRoute("/");
flutterEngine.getDartExecutor().executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault());
FlutterEngineCache
.getInstance()
.put(ENGINE_ID, flutterEngine);
messageChannelFunction(this,flutterEngine);
}
return flutterEngine;
}
private void attachFlutterFragment() {
if (null == flutterFragment) {
flutterFragment =
FlutterFragment.withCachedEngine(ENGINE_ID)
.shouldAttachEngineToActivity(true)
.build();
}
getSupportFragmentManager()
.beginTransaction()
.add(R.id.container, flutterFragment)
.commit();
}
}
二.通信
1.BasicMessageChannel 方式
跨Native,Flutter發送消息可接收消息
1.1Flutter端給原生發消息
//Flutter 端
//創建 BasicMessageChannel
// flutter_and_native_100 為通信標識
// StandardMessageCodec() 為參數傳遞的 編碼方式
static const messageChannel = const BasicMessageChannel(
'flutter_and_native_100', StandardMessageCodec());
//發送消息
Future<Map> sendMessage(Map arguments) async {
Map reply = await messageChannel.send(arguments);
//解析 原生發給 Flutter 的參數
int code = reply["code"];
String message = reply["message"];
//更新 Flutter 中頁面顯示
setState(() {
_counter = "code:$code message:$message";
});
return reply;
}
//原生端
private BasicMessageChannel<Object> mMessageChannel;
private void messageChannelFunction(Context mContext, FlutterEngine flutterEngine) {
//消息接收監聽
//BasicMessageChannel (主要是傳遞字符串和一些半結構體的數據)
//創建通
mMessageChannel = new BasicMessageChannel<Object>(flutterEngine.getDartExecutor(), "flutter_and_native_100", StandardMessageCodec.INSTANCE);
// 接收消息監聽
mMessageChannel.setMessageHandler(new BasicMessageChannel.MessageHandler<Object>() {
@Override
public void onMessage(Object o, BasicMessageChannel.Reply<Object> reply) {
Map<Object, Object> arguments = (Map<Object, Object>) o;
//方法名標識
String lMethod = (String) arguments.get("method");
//測試 reply.reply()方法 發消息給Flutter
if (lMethod.equals("test")) {
Toast.makeText(mContext, "flutter 調用到了 android test", Toast.LENGTH_SHORT).show();
//回調Flutter
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", "reply.reply 返回給flutter的數據");
resultMap.put("code", 200);
//回調 此方法只能使用一次
reply.reply(resultMap);
} else if (lMethod.equals("test2")) {
//測試 mMessageChannel.send 發消息給Flutter
//Android 可通過這個方法來主動向 Flutter中發送消息
//只有Flutter 中注冊了消息監聽 才能接收到這個方法向 Flutter 中發送的消息
// channelSendMessage();
} else if (lMethod.equals("test3")) {
//測試通過Flutter打開Android Activity
Toast.makeText(mContext, "flutter 調用到了 android test3", Toast.LENGTH_SHORT).show();
Intent lIntent = new Intent(MyFlutterActivity.this, TestBasicMessageActivity.class);
mContext.startActivity(lIntent);
}
}
});
}
1.2 原生給Flutter發消息
//原生端
private void channelSendMessage() {
mMessageChannel = new BasicMessageChannel<Object>(initFlutterEngine().getDartExecutor(), "flutter_and_native_100", StandardMessageCodec.INSTANCE);
Toast.makeText(this, "flutter 調用到了 android test", Toast.LENGTH_SHORT).show();
//構建參數
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", "reply.reply 返回給flutter的數據");
resultMap.put("code", 200);
//向 Flutter 中發送消息
//參數 二可以再次接收到 Flutter 中的回調
//也可以直接使用 mMessageChannel.send(resultMap)
mMessageChannel.send(resultMap, new BasicMessageChannel.Reply<Object>() {
@Override
public void reply(Object o) {
Log.d("mMessageChannel", "mMessageChannel send 回調 " + o); //消息沒有收到???
}
});
}
//Fluttrer 端
void messageChannelFunction(){
messageChannel.setMessageHandler((message) async {
print('message: $message');
return '返回Native端的數據001';//這是native端的響應 ,執行了
});
}
2.MethodChannel 方式
直接跨Native,Flutter調用方法
2.1 Native端 發送 + 監聽接收
/**
* 設置MethodChannel 監聽
*
* @param flutterEngine
*/
private void setMethodChannel(FlutterEngine flutterEngine) {
MethodChannel channel = new MethodChannel(flutterEngine.getDartExecutor(), "study_3/methodChannel");
channel.setMethodCallHandler(new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
switch (methodCall.method) {
// case NATIVE_METHOD_LOGIN:
// login(context, (String) methodCall.argument("phone"), (String) methodCall.argument("code"));
// break;
}
}
});
}
private void invokeMethodChannel(FlutterEngine flutterEngine) {
MethodChannel channel = new MethodChannel(flutterEngine.getDartExecutor(), "cn.withflutter.plugins.flutter");
//在Android端調用Flutter中的getInputParams方法,參數是以Json的格式傳遞。這里是無參方法使用null
channel.invokeMethod("getInputParams", "{'arg1':'來自Native'}", new MethodChannel.Result() {
@Override
public void success(@Nullable Object result) {
}
@Override
public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) {
}
@Override
public void notImplemented() {
}
});
}
2.2 Flutter端 發送+監聽接收
class PluginChannel {
static const _methodChannelName = "study_3/methodChannel";
static const _methodChannel = MethodChannel(_methodChannelName);
static void invokeMethod() {
_methodChannel.invokeMethod("getAge", {"name": "lili"}).then((result) {
print('flutter receive response:$result');
});
}
static void listenMethod() {
_methodChannel.setMethodCallHandler((methodCall) async {
print('flutter listen:$methodCall');
return "男";
});
}
}
3.EventChannel 模式
EventChannel並沒有分別提供發送和收聽消息的方法,它只提供了一個receiveBroadcastStream方法,用於發送消息,同時返回一個流(Stream),用於監聽平台插件成功返回的所有事件信息,這個流可以被監聽
不止一次。因此我們可以用於native端需要持續傳遞數據到flutter的情況,比如監聽電量,調用攝像頭等等
flutter:
class PluginChannel {
static const _eventChannelName = "study_3/eventChannel";
static const _eventChannel = EventChannel(_eventChannelName);
static void event() {
_eventChannel.receiveBroadcastStream("event arg")
.listen((result) {
print('flutter listen:$result');
});
}
}
android:
private void eventChannelDemo(FlutterEngine flutterEngine){
EventChannel channel = new EventChannel(flutterEngine.getDartExecutor(),"study_3/methodChannel");
channel.setStreamHandler(new EventChannel.StreamHandler() {
@Override
public void onListen(Object arguments, EventChannel.EventSink events) {
events.success(1);
events.success(2);
events.success(3);
events.success(4);
events.endOfStream();
}
@Override
public void onCancel(Object arguments) {
}
});
}
