Flutter与Android通信自定义EventChannel
2020-10-13 本文已影响0人
翟小乙
在Flutter开发中,不可避免使用到android 原生开发,那如何交互呢?,我们今天来举例说明一下,比如我们通过MethodChannel和EventChannel,进行字符串的Base64转码并返回给flutter。
MethodChannel举例获取字符串Base64转码:
flutter 旧版本(sdk<1.2):
flutter 端代码
import 'package:flutter/services.dart';
class ChannelUtils {
static ChannelUtils _channelUtils;
MethodChannel methodChannel;
static const String Channel = "com.methodold.test" ;
static ChannelUtils getInstance() {
if (_channelUtils == null) {
_channelUtils = new ChannelUtils();
}
return _channelUtils;
}
/*
*返回异步方法回调
*/
void encodeFunBase64(String encode, onEvent, {onError}) {
if (methodChannel == null) {
methodChannel = MethodChannel(Channel);
}
methodChannel.invokeMethod('base64', {'data': encode}).then(onEvent,
onError: onError);
}
/*
*可改为同步方法:返回base64 加密后的数据
*/
Future<String> encodeStrBase64(String encode, onEvent, {onError}) async {
if (methodChannel == null) {
methodChannel = MethodChannel(Channel);
}
String base64 =
await methodChannel.invokeMethod('base64', {'data': encode});
return base64;
}
}
android 端代码
import android.util.Base64;
import androidx.annotation.NonNull;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry;
//Flutter sdk 小于1.2 一般来说此方法思想适用于任何情况
public class MethodOld implements MethodChannel.MethodCallHandler {
private final static String CHANNEL = "com.methodold.test";
//在Act界面调用注册方法
public static MethodOld register(PluginRegistry pluginRegistry) {
PluginRegistry.Registrar registrar = pluginRegistry.registrarFor(CHANNEL);
MethodChannel methodChannel = new MethodChannel(registrar.messenger(), CHANNEL);
MethodOld methodOld = new MethodOld();
methodChannel.setMethodCallHandler(methodOld);
return methodOld;
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
//方法名为base64且包含key为data
if (call.method.equals("base64") && call.hasArgument("data")) {
String data = call.argument("data");
byte[] dataByte = data.getBytes();
String encodeStr = Base64.encodeToString(dataByte, Base64.NO_WRAP);
result.success(encodeStr);
}
}
}
flutter 新版本(sdk>=1.2):
flutter 端代码
同flutter 旧版本(sdk<1.2)的flutter代码一样.
只需要修改通道: static const String Channel = "com.methodold.test" ;
为:Channel = "com.methodnew.test" ;
android 端代码
import android.app.Activity;
import android.util.Base64;
import androidx.annotation.NonNull;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry;
public class MethodNew implements FlutterPlugin, MethodChannel.MethodCallHandler, ActivityAware {
private static MethodChannel methodChannel;
private final static String CHANNEL = "com.methodnew.test";//通道
private Activity activity;//获取上下文
@Override //自动注册
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
methodChannel = new MethodChannel(binding.getBinaryMessenger(), CHANNEL);
methodChannel.setMethodCallHandler(new MethodNew());
//若获取上下文为null 则改为以下方法
//methodChannel.setMethodCallHandler(this);
}
//手动注册
public static MethodNew register(PluginRegistry pluginRegistry) {
PluginRegistry.Registrar registrar = pluginRegistry.registrarFor(CHANNEL);
methodChannel = new MethodChannel(registrar.messenger(), CHANNEL);
MethodNew methodNew = new MethodNew();
methodChannel.setMethodCallHandler(methodNew);
return methodNew;
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
if (call.method.equals("base64") && call.hasArgument("data")) {
String data = call.argument("data");
byte[] dataByte = data.getBytes();
String encodeStr = Base64.encodeToString(dataByte, Base64.NO_WRAP);
result.success(encodeStr);
}
}
@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
activity = binding.getActivity();
}
@Override
public void onDetachedFromActivityForConfigChanges() {
}
@Override
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
}
@Override
public void onDetachedFromActivity() {
activity = null;
}
}
EventChannel举例获取字符串Base64转码:
flutter 旧版本(sdk<1.2):
flutter 端代码
Model配置Json数据串
class Base64Model {
int code;//标识码:Android端可判断来源
String data;//需要被加密的数据
Base64Model(this.code, this.data);
//拼接字符串
Map<String, dynamic> toJson() => {"code": code, "data": data};
}
EventChannel接收工具类
import 'package:flutter/services.dart';
import 'package:flutter_home/utils/smutils/ssssss.dart';
class ChannelUtils {
static ChannelUtils _channelUtils;
EventChannel eventChannel;
static const String Channel = "com.eventold.test" ;
static ChannelUtils getInstance() {
if (_channelUtils == null) {
_channelUtils = new ChannelUtils();
}
return _channelUtils;
}
/*
*返回异步方法回调
*/
void encodeFunBase64(String encode, onEvent, {onError}) {
if (eventChannel == null) {
eventChannel = EventChannel(Channel);
}
Base64Model base64model = new Base64Model(101, encode);
eventChannel.receiveBroadcastStream(base64model.toJson()).listen(onEvent, onError: onError);
}
}
android 端代码
引入Gson库:由flutter 端组成的json串在Android端展示为code=101的这种带等号格式,所以需要引入gson第三方库进行解析!
app 的build.gradle配置:
implementation 'com.google.code.gson:gson:2.4'
Model配置Json数据串
public class Base64Model {
int code;//数据来源标识码
String data;//数据
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
EventChannel接收类
注:events.success与events.error区别就是调用success后flutter与Android 的通道没有断开,调用error后flutter与Android的通道断开不可以在发数据。
import android.util.Base64;
import com.google.gson.Gson;
import org.json.JSONException;
import org.json.JSONObject;
import act.Base64Model;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.PluginRegistry;
public class EventOld implements EventChannel.StreamHandler {
private final static String CHANNEL = "com.eventold.test";
public static EventOld register(PluginRegistry pluginRegistry) {
PluginRegistry.Registrar registrar = pluginRegistry.registrarFor(CHANNEL);
EventChannel eventChannel = new EventChannel(registrar.messenger(), CHANNEL);
EventOld eventOld = new EventOld();
eventChannel.setStreamHandler(eventOld);
return eventOld;
}
@Override
public void onListen(Object arguments, EventChannel.EventSink events) {
if (arguments != null && arguments.toString() != null) {
Gson gson = new Gson();
Base64Model base64Model = gson.fromJson(new Gson().toJson(arguments), Base64Model.class);
JSONObject jsonObject = new JSONObject();
if (base64Model.getCode() == 101) {
//字节数组
String base64 = base64Model.getData();
byte[] dataByte = base64.getBytes();
String encodeStr = Base64.encodeToString(dataByte, Base64.NO_WRAP);
try {
jsonObject.put("base64", encodeStr);
} catch (JSONException e) {
}
}
//返回数据一个字符串,在flutter端进行Json解析
events.success(jsonObject.toString());
} else {
events.error("error", "error", "地址为空");
}
}
@Override
public void onCancel(Object arguments) {
}
}
flutter 新版本(sdk>=1.2):
flutter 端代码
同flutter 旧版本(sdk<1.2)的flutter代码一样.
只需要修改通道: static const String Channel = "com.eventold.test" ;
为:Channel = "com.eventnew.test" ;
flutter 端代码
引入Gson库:由flutter 端组成的json串在Android端展示为code=101的这种带等号格式,所以需要引入gson第三方库进行解析!
app 的build.gradle配置:
implementation 'com.google.code.gson:gson:2.4'
Model配置Json数据串
public class Base64Model {
int code;//数据来源标识码
String data;//数据
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
EventChannel接收类
import android.app.Activity;
import android.util.Base64;
import androidx.annotation.NonNull;
import com.google.gson.Gson;
import org.json.JSONException;
import org.json.JSONObject;
import act.Base64Model;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.PluginRegistry;
public class EventNew implements EventChannel.StreamHandler, FlutterPlugin, ActivityAware {
private final static String CHANNEL = "com.eventnew.test";
private static EventChannel eventChannel;
private Activity activity;//上下文
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
eventChannel = new EventChannel(binding.getBinaryMessenger(), CHANNEL);
eventChannel.setStreamHandler(new EventNew());
//若获取上下文为null 则改为以下方法
//eventChannel.setMethodCallHandler(this);
}
public static EventNew register(PluginRegistry pluginRegistry) {
PluginRegistry.Registrar registrar = pluginRegistry.registrarFor(CHANNEL);
eventChannel = new EventChannel(registrar.messenger(), CHANNEL);
EventNew eventNew = new EventNew();
eventChannel.setStreamHandler(eventNew);
return eventNew;
}
@Override
public void onListen(Object arguments, EventChannel.EventSink events) {
if (arguments != null && arguments.toString() != null) {
Gson gson = new Gson();
Base64Model base64Model = gson.fromJson(new Gson().toJson(arguments), Base64Model.class);
JSONObject jsonObject = new JSONObject();
if (base64Model.getCode() == 101) {
//字节数组
String base64 = base64Model.getData();
byte[] dataByte = base64.getBytes();
String encodeStr = Base64.encodeToString(dataByte, Base64.NO_WRAP);
try {
jsonObject.put("base64", encodeStr);
} catch (JSONException e) {
}
}
//返回数据一个字符串,在flutter端进行Json解析
events.success(jsonObject.toString());
} else {
events.error("error", "error", "地址为空");
}
}
@Override
public void onCancel(Object arguments) {
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
}
@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
activity = binding.getActivity();
}
@Override
public void onDetachedFromActivityForConfigChanges() {
}
@Override
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
}
@Override
public void onDetachedFromActivity() {
}
}