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>

    效果:

  • 相关阅读:
    【leetcode】Binary Search Tree Iterator
    【leetcode】Palindrome Partitioning II
    【leetcode】Best Time to Buy and Sell Stock III
    【leetcode】Best Time to Buy and Sell Stock II
    【leetcode】Longest Consecutive Sequence
    【leetcode】Factorial Trailing Zeroes
    【leetcode】Simplify Path
    【leetcode】Generate Parentheses
    【leetcode】Combination Sum II
    【leetcode】Combination Sum
  • 原文地址:https://www.cnblogs.com/loaderman/p/11353174.html
Copyright © 2011-2022 走看看