zoukankan      html  css  js  c++  java
  • Flutter和原生交互学习

     

    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);
        FlutterPluginJumpToAct.registerWith(this.registrarFor(FlutterPluginJumpToAct.CHANNEL));//注册
        FlutterPluginCounter.registerWith(this.registrarFor(FlutterPluginCounter.CHANNEL));//注册
    
      }
    }

    activity_one.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <Button
            android:id="@+id/go_flutter"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="去Flutter界面"></Button>
    </LinearLayout>

    activity_two.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </LinearLayout>

    效果:

  • 相关阅读:
    [转]JAVA程序执行顺序,你了解了吗:JAVA中执行顺序,JAVA中赋值顺序
    [转]浅谈Java中的equals和==
    [原创]java WEB学习笔记102:Spring学习---Spring Bean配置:bean配置方式(工厂方法(静态工厂方法 & 实例工厂方法)、FactoryBean) 全类名
    [原创]java WEB学习笔记101:Spring学习---Spring Bean配置:IOC容器中bean的声明周期,Bean 后置处理器
    C# 数组之List<T>
    C# 数组之ArrayList
    C# 数组之int[]
    reverse-XNUCA-babyfuscator
    reverse-daily(1)-audio_visual_receiver_code
    Python多线程和多进程谁更快?
  • 原文地址:https://www.cnblogs.com/loaderman/p/11353174.html
Copyright © 2011-2022 走看看