flutter_plugin与原生的多次通信(BasicMessageChannel)
flutter插件化开发与原生的多次通信(BasicMessageChannel)flutter与原生的通信有三种方式BasicMessageChannel:用于传递字符串和半结构化的信息,双向通信,原生可以多次向flutter发送消息MethodChannel:用于传递方法调用(method invocation),双向通行,EventChannel: 用于数据流(event streams)的
·
flutter插件化开发与原生的多次通信(BasicMessageChannel)
flutter与原生的通信有三种方式
- BasicMessageChannel:用于传递字符串和半结构化的信息,双向通信,原生可以多次向flutter发送消息
- MethodChannel:用于传递方法调用(method invocation),双向通行,
- EventChannel: 用于数据流(event streams)的通信,flutter调用原生一次,原生也只能返回flutter一次消息,然后通信结束
本文介绍使用BasicMessageChannel插件化开发flutter与原生的多次通信
flutter_plugin端代码
class AdhubPlugin {
// adhub_plugin通信名称
static const _channel = const BasicMessageChannel(
'adhub_plugin', StandardMessageCodec());
/// 注意:返回_channel 用于接受多次返回的消息
static Future<BasicMessageChannel> adHubSplash(String applicationID,String spaceID) async {
Map map = {"method":"getAdHubSplash","arguments":{}};
_channel.send(map);
return _channel;
}
}
iOS端代码
#import "AdhubPlugin.h"
@implementation AdhubPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
AdhubPlugin* instance = [[AdhubPlugin alloc] init];
[instance setMessageChannel:registrar];
}
-(void)setMessageChannel:(NSObject<FlutterPluginRegistrar>*)registrar{
messageChannel = [FlutterBasicMessageChannel messageChannelWithName:@"adhub_plugin" binaryMessenger:[registrar messenger]];
// 接收消息监听 callback用于单次通讯,无法多次返回消息
__block AdhubPlugin *blockSelf = self;
[messageChannel setMessageHandler:^(id message, FlutterReply callback) {
NSString *method = message[@"method"];
if ([@"getAdHubSplash" isEqualToString:method]) {
NSDictionary* dic = message[@"arguments"];
[blockSelf createSplash:dic];
} else {
callback(@"");
}
}];
}
/// 第三方开屏
- (void)createSplash:(NSDictionary *)dic{
[AdHubSDKManager configureWithApplicationID:[dic objectForKey:@"applicationID"]];
[AdHubSDKManager openTheAdHubLog];
self.splash = [[AdHubSplash alloc]initWithSpaceID:[dic objectForKey:@"spaceID"] spaceParam:@"" lifeTime:5000];
self.splash.delegate = self;
self.splash.showLaunchImage = NO;
[self.splash ADH_loadAndDisplaySplashAd];// 使用此方法加载开屏
}
#pragma mark adHub广告
/**
开屏展现
[messageChannel sendMessage:@""]用来与flutter端多次通信 类型可以是任意类型 这里是字符串
*/
- (void)ADH_splashDidPresentScreen:(AdHubSplash *)adHubSplash {
[messageChannel sendMessage:@"开屏展现"];
}
/**
开屏点击
*/
- (void)ADH_splashDidClick:(AdHubSplash *)adHubSplash {
[messageChannel sendMessage:@"开屏点击"];
}
/**
开屏即将消失
*/
- (void)ADH_splashWillDismissScreen:(AdHubSplash *)adHubSplash {
}
/**
开屏消失
*/
- (void)ADH_splashDidDismissScreen:(AdHubSplash *)adHubSplash {
[messageChannel sendMessage:@"开屏消失"];
}
/**
开屏请求失败
*/
- (void)ADH_splash:(AdHubSplash *)adHubSplash didFailToLoadAdWithError:(AdHubRequestError *)error {
[messageChannel sendMessage:@"开屏请求失败"];
}
@end
如果通信是多页面的话,可以用通知来实现,在本页面注册通知,在其他页面实现通知
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
//注册通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationFuncion:) name:@"ios.to.flutter" object:nil];
AdhubPlugin* instance = [[AdhubPlugin alloc] init];
[instance setMessageChannel:registrar];
}
- (void)notificationFuncion: (NSNotification *) notification {
// iOS 中其他页面向Flutter 中发送消息通过这里
// 本页中 可以直接使用 [messageChannel sendMessage:dic];
//处理消息
NSLog(@"notificationFuncion ");
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
if (messageChannel!=nil) {
[dic setObject:@" [messageChannel sendMessage:dic]; 向Flutter 发送消息 " forKey:@"message"];
[dic setObject: [NSNumber numberWithInt:401] forKey:@"code"];
//主动向Flutter 中发送消息
[messageChannel sendMessage:dic];
}
}
- (void)dealloc {
//单条移除观察者
//[[NSNotificationCenter defaultCenter] removeObserver:self name:@"ios.to.flutter" object:nil];
//移除所有观察者
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Android端代码(非plugin插件化实例)
在MainActivity中,创建了 BasicMessageChannel 的实例 mMessageChannel,可以在MainActivity 中直接使用 mMessageChannel 实例来向 Flutter 中发送消息
private void channelSendMessage() {
Toast.makeText(mContext, "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);
}
});
}
在其他的 Activity 页面中,我们就使用不到这个实例的,我这里的一个实现 Android 中新建的Activity 页面向 Flutter 中发送消息的方法 是广播机制
在 MainActivity 中注册广播,在广播接收者中通过 BasicMessageChannel 的实例 mMessageChannel 来发送消息。
在 Android 中其他的页面中 发送广播到 MainActivity 中的广播接收者中,这样就实现了Android 中新建的Activity 页面向 Flutter 中发送消息
public class MainActivity extends FlutterActivity {
... ...
Handler mHandler = new Handler(Looper.myLooper());
private MainReceiver mMainReceiver;
@Override
protected void onDestroy() {
super.onDestroy();
//注销广播
unregisterReceiver(mMainReceiver);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
... ...
//注册广播
mMainReceiver = new MainReceiver();
IntentFilter lIntentFilter = new IntentFilter("android.to.flutter");
registerReceiver(mMainReceiver, lIntentFilter);
}
public class MainReceiver extends BroadcastReceiver {
public MainReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "接收到自定义的广播", Toast.LENGTH_SHORT).show();
mHandler.post(new Runnable() {
@Override
public void run() {
Map<String, Object> resultMap2 = new HashMap<>();
resultMap2.put("message", "android 主动调用 flutter test 方法");
resultMap2.put("code", 200);
if (mMessageChannel != null) {
// 向Flutter 发送消息
mMessageChannel.send(resultMap2, new BasicMessageChannel.Reply<Object>() {
@Override
public void reply(Object o) {
System.out.println("android onReply: " + o);
}
});
}
}
});
}
}
}
flutter项目调用
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: InkWell(
child: Text('进入开屏页面'),
onTap: () async {
BasicMessageChannel channel = await AdhubPlugin.adHubSplash('20017','102904');
channel.setMessageHandler((result) async {
//解析 原生发给 Flutter 的参数
print(result);
});
}
)
),
),
);
}
}
更多推荐
已为社区贡献1条内容
所有评论(0)