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));//注册 }
}

效果:

Flutter和原生交互学习的更多相关文章

  1. Flutter的需要与原生交互的一些常用库

    [说明]由于这些库一直在更新,请自己选择合适的稳定版本下载. 另外如果发现有问题或者你有更好的库,欢迎留言告诉我. 谷歌官方的针对Dart语言的一些实用性的功能以及扩展的库 -- Quiver Qui ...

  2. h5 做app时和原生交互的小常识。

    距离上次随笔或许有半年了吧,最近在用hybrid模式开发移动app,所以就简单的说说用h5技术开发app时候,做原生交互的几个小常识: 一.拨打电话或者发送短信: <a href="t ...

  3. Flutter 即学即用系列博客——08 MethodChannel 实现 Flutter 与原生通信

    背景 前面我们讲了很多 Flutter 相关的知识点,但是我们并没有介绍怎样实现 Flutter 与原生的通信. 比如我在 Flutter UI 上面点击了一个按钮,我希望原生做一些处理,那么原生怎么 ...

  4. Lua和C++交互 学习记录之九:在Lua中以面向对象的方式使用C++注册的类

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 在 ...

  5. Lua和C++交互 学习记录之八:C++类注册为Lua模块

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

  6. Lua和C++交互 学习记录之七:C++全局函数注册为Lua模块

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

  7. Lua和C++交互 学习记录之六:全局函数交互

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

  8. Lua和C++交互 学习记录之五:全局数组交互

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

  9. Lua和C++交互 学习记录之四:全局table交互

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

随机推荐

  1. Web前端面试图

    文章:记一次腾讯微信面试 先是看简历上写的项目经验,问一上些项目上的问题,比如如何编写 js-sdk, 如何去修改 weui 库,遇到最大的难题是什么及如何去解决的. 数组去重的方法有哪些? 如何判断 ...

  2. virtual box 6.0 扩容原有磁盘空间 ubuntu18.04

    virtual box 6.0 扩容原有磁盘空间 ubuntu18.04 1虚拟介质管理 1.1点击菜单 1.2 修改磁罗容量大小(需要关闭虚拟机),点击应用 2使用ubuntu安装镜像将新加容量添加 ...

  3. lomback插件在日志管理方面的应用

    由于现在使用日志可以省去在解决bug时候的很多麻烦, lomback为我们提供了很方便的打印日志的管理 @RunWith(SpringRunner.class) @SpringBootTest @Sl ...

  4. 后台将数据传回前台的三种绑定的方式(Model,Map.ModelAndView)

    //方式1:通过model 将数据绑定 @RequestMapping(value = "findByIdModel", method = RequestMethod.GET) p ...

  5. java设计模式解析(1) Observer观察者模式

      设计模式系列文章 java设计模式解析(1) Observer观察者模式 java设计模式解析(2) Proxy代理模式 java设计模式解析(3) Factory工厂模式 java设计模式解析( ...

  6. 0.Pycharm安装

    以windows版本举例: 1.首先去Pycharm官网,或者直接输入网址:http://www.jetbrains.com/pycharm/download/#section=windows,下载P ...

  7. 4:ELK分析tomcat日志

    五.ELK分析tomcat日志 1.配置FIlebeat搜集tomcat日志 2.配置Logstash从filebeat输入tomcat日志 3.查看索引 4.创建索引

  8. Deepgreen & Greenplum DBA小白普及课之三

    Deepgreen & Greenplum DBA小白普及课之三(备份问题解答) 不积跬步无以至千里,要想成为一名合格的数据库管理员,首先应该具备扎实的基础知识及问题处理能力.本文参考Pivo ...

  9. learning java Cloneable

    class Address{ String Detail; public Address(String detail){ this.Detail = detail; } } class User im ...

  10. mysql group by order by havaing where 顺序

    结论: select xx from xx where xx group by xx order by xxx; select xx from xx group by xx having xx ord ...