flutter和Android原生通信共计有三种类型,分别是:
- MethodChannel:flutter和Android之间互相调用,调用一次,执行一次,如Flutter调用Native拍照
- EventChannel:用于数据流(event streams)的通信,持续通信,收到消息后无法回复此次消息,通常用于Native向Dart的通信,如:手机电量变化,网络连接变化,陀螺仪,传感器等;
- BasicMessageChannel:用于传递字符串和半结构化的信息,持续通信,收到消息后可以回复此次消息,如:Native将遍历到的文件信息陆续传递到Dart,在比如:Flutter将从服务端陆陆续获取到信息交个Native加工,Native处理完返回等
这三种类型的类型的Channel都是通信,即A <=> B,Flutter可以主动发送消息给platform端,并且platform接收到消息后可以做出回应,同样,platform端可以主动发送消息给Flutter端,Flutter端接收数后返回给platform端。 这一篇主要记录一下BasicMessageChannel的使用方法
Flutter代码通过BasicMessageChannel调用Android代码
1、flutter代码
class _MyHomePageState extends State<MyHomePage> {
String content = "";
BasicMessageChannel _messageChannel =
BasicMessageChannel("messageChannel", StandardMessageCodec());
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"$content",
),
TextField(
onChanged: _onChange,
)
],
),
),
);
}
Future<String> _sendMessage(value) async {
String reply = await _messageChannel.send(value);
print(reply);
return reply;
}
void _onChange(String value) {
print(value);
_sendMessage(value);
}
}
2、Android代码
package com.example.nativeapp;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.BasicMessageChannel;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.common.StringCodec;
public class MyFlutterActivity extends FlutterActivity {
public final static String INIT_PARAMS = "initParams";
private BasicMessageChannel basicMessageChannel;
private String initParams;
public static void start(Context context, String initParams) {
Intent intent = new Intent(context, MyFlutterActivity.class);
intent.putExtra(INIT_PARAMS, initParams);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initParams = getIntent().getStringExtra(INIT_PARAMS);
//BinaryMessenger messenger - 消息信使,是消息的发送与接收的工具;
//String name - Channel的名字,也是其唯一标识符;
//MethodCodec codec - 用作EventChannel的编解码器;
basicMessageChannel = new BasicMessageChannel(getFlutterEngine().getDartExecutor().getBinaryMessenger(), "messageChannel", StandardMessageCodec.INSTANCE);
basicMessageChannel.setMessageHandler((message, reply) -> {
Log.i("MessageHandler", message.toString());
//返回值
reply.reply("Android 已收到");
});
}
//使用在MyApplication预先初始化好的Flutter引擎以提升Flutter页面打开速度,
// 注意:在这种模式下回导致getInitialRoute 不被调用所以无法设置初始化参数
@Override
public String getCachedEngineId() {
return MyApplication.CACHED_ENGINE_ID;
}
/**
* 重载该方法来传递初始化参数
*
* @return
*/
@NonNull
@Override
public String getInitialRoute() {
return initParams == null ? super.getInitialRoute() : initParams;
}
}
Android向Flutter发送数据只需要将上面的流程反过来,在Flutter中注册basicMessageChannel.setMessageHandler(),
然后在Android代码中调用_messageChannel.send(value)即可。
要注意的一点是BasicMessageChannel创建的时候,flutter和android两边的通道名字一定要相同,否则会抛出异常