PlatformChannel功能简介
PlatformChannel分为BasicMessageChannel、MethodChannel以及EventChannel三种。其各自的主要用途如下:
- BasicMessageChannel: 用于传递数据。Flutter与原生项目的资源是不共享的,可以通过BasicMessageChannel来获取Native项目的图标等资源。
- MethodChannel: 传递方法调用。Flutter主动调用Native的方法,并获取相应的返回值。比如获取系统电量,发起Toast等调用系统API,可以通过这个来完成。
- EventChannel: 传递事件。这里是Native将事件通知到Flutter。比如Flutter需要监听网络情况,这时候MethodChannel就无法胜任这个需求了。EventChannel可以将Flutter的一个监听交给Native,Native去做网络广播的监听,当收到广播后借助EventChannel调用Flutter注册的监听,完成对Flutter的事件通知。
其实可以看到,无论传方法还是传事件,其本质上都是数据的传递,不过上层包的一些逻辑不同而已。
flutter
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; class ChannelPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new _ChannelPageState();
}
} class _ChannelPageState extends State<ChannelPage> { //获取到插件与原生的交互通道
static const jumpPlugin = const MethodChannel('com.example.jump/plugin');
static const counterPlugin = const EventChannel('com.example.counter/plugin');
var _count;
StreamSubscription _counterSub;
@override
void initState() {
super.initState();
_startCounterPlugin();
} @override
void dispose() {
super.dispose();
_endCounterPlugin();
}
void _startCounterPlugin(){
if(_counterSub == null){
_counterSub = counterPlugin.receiveBroadcastStream().listen(_onCounterEvent,onError: _onCounterError);
}
} void _endCounterPlugin(){
if(_counterSub != null){
_counterSub.cancel();
}
}
void _onCounterError(Object error) {
setState(() {
_count = "计时器异常";
print(error);
});
} void _onCounterEvent(Object event) {
setState(() {
_count = event;
});
} Future<Null> _jumpToNative() async {
String result = await jumpPlugin.invokeMethod('oneAct'); print(result);
} Future<Null> _jumpToNativeWithValue() async { Map<String, String> map = { "flutter": "这是一条来自flutter的参数" }; String result = await jumpPlugin.invokeMethod('twoAct', map); print(result);
} @override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Channel"),
centerTitle: true,
),
body: new Center(
child: new ListView(
children: <Widget>[
new Padding(
padding: const EdgeInsets.only(left: 10.0, top: 10.0, right: 10.0),
child: new RaisedButton(
textColor: Colors.black,
child: new Text('跳转到原生界面'),
onPressed: () {
_jumpToNative();
}),
),
new Padding(
padding: const EdgeInsets.only(
left: 10.0, top: 10.0, right: 10.0),
child: new RaisedButton(
textColor: Colors.black,
child: new Text('跳转到原生界面(带参数)'),
onPressed: () {
_jumpToNativeWithValue();
}),
), new Padding(
padding: const EdgeInsets.only(
left: 10.0, top: 10.0, right: 10.0),
child: new Text('这是一个从原生发射过来的数据:$_count'),
), ],
)
),
);
}
}
android
package com.example.flutter_app.plugins; import android.app.Activity;
import android.util.Log; import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.PluginRegistry; public class FlutterPluginCounter implements EventChannel.StreamHandler { public static String CHANNEL = "com.example.counter/plugin"; static EventChannel channel; private Activity activity; private FlutterPluginCounter(Activity activity) {
this.activity = activity;
} public static void registerWith(PluginRegistry.Registrar registrar) {
channel = new EventChannel(registrar.messenger(), CHANNEL);
FlutterPluginCounter instance = new FlutterPluginCounter(registrar.activity());
channel.setStreamHandler(instance);
// basicMessageChannel = new BasicMessageChannel<String> ("foo", StringCodec.INSTANCE);
} @Override
public void onListen(Object o, final EventChannel.EventSink eventSink) {
eventSink.success(123456);
} @Override
public void onCancel(Object o) {
Log.i("FlutterPluginCounter", "FlutterPluginCounter:onCancel");
} }
package com.example.flutter_app.plugins; import android.app.Activity;
import android.content.Intent; import com.example.flutter_app.OneActivity;
import com.example.flutter_app.TwoActivity; import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.PluginRegistry; public class FlutterPluginJumpToAct implements MethodCallHandler { public static String CHANNEL = "com.example.jump/plugin"; static MethodChannel channel; private Activity activity; private FlutterPluginJumpToAct(Activity activity) {
this.activity = activity;
} public static void registerWith(PluginRegistry.Registrar registrar) {
channel = new MethodChannel(registrar.messenger(), CHANNEL);
FlutterPluginJumpToAct instance = new FlutterPluginJumpToAct(registrar.activity());
//setMethodCallHandler在此通道上接收方法调用的回调
channel.setMethodCallHandler(instance);
} @Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) { //通过MethodCall可以获取参数和方法名,然后再寻找对应的平台业务,本案例做了2个跳转的业务 //接收来自flutter的指令oneAct
if (call.method.equals("oneAct")) { //跳转到指定Activity
Intent intent = new Intent(activity, OneActivity.class);
activity.startActivity(intent); //返回给flutter的参数
result.success("success");
}
//接收来自flutter的指令twoAct
else if (call.method.equals("twoAct")) { //解析参数
String text = call.argument("flutter"); //带参数跳转到指定Activity
Intent intent = new Intent(activity, TwoActivity.class);
intent.putExtra(TwoActivity.VALUE, text);
activity.startActivity(intent); //返回给flutter的参数
result.success("success");
}
else {
result.notImplemented();
}
} }
package com.example.flutter_app; import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button; public class OneActivity extends Activity implements View.OnClickListener { private Button mGoFlutterBtn; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_one); mGoFlutterBtn = findViewById(R.id.go_flutter); mGoFlutterBtn.setOnClickListener(this); } @Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.go_flutter:
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
break;
}
} }
package com.example.flutter_app; import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView; public class TwoActivity extends Activity{ private TextView mTextView; public static final String VALUE = "value"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_two); mTextView = findViewById(R.id.text); String text = getIntent().getStringExtra(VALUE); mTextView.setText(text); } }
package com.example.flutter_app; import android.os.Bundle; import com.example.flutter_app.plugins.FlutterPluginCounter;
import com.example.flutter_app.plugins.FlutterPluginJumpToAct; import io.flutter.app.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant; public class MainActivity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
FlutterPluginJumpToAct.registerWith(this.registrarFor(FlutterPluginJumpToAct.CHANNEL));//注册
FlutterPluginCounter.registerWith(this.registrarFor(FlutterPluginCounter.CHANNEL));//注册 }
}
效果: