• Flutter与原生通信(上)


    一 、flutter中通信的三种方式

    BasicMessageChannel:用于传递字符串和半结构化的信息
    MethodChannel:用于传递方法调用(method invocation)通常用来调用native中某个方法
    EventChannel: 用于数据流(event streams)的通信。有监听功能,比如电量变化之后直接推送数据给flutter端。


    二 、MethodChannel的使用

    1.搭建流程:
    Flutter ------>Native
    MethodChannel是Flutter和原生交互的基础,通过传入Flutter插件的名字,调用invokeMethod方法,便可以调用原生的方法,有点类似于Java的反射。
    注册渠道:在两端同时创建一个MethodChannel对象,注册相同的字符串值。
    Android端

    MethodChannel a2FChannel = new MethodChannel((FlutterView)flutterView,"A2FChannel");
    
    • 1

    Flutter端

     var channel = MethodChannel("A2FChannel");
     final String result = await channel.invokeMethod(nativeMethod, args);
    
    • 1
    • 2

    setMethodCallHandler 方法注解

    channel.setMethodCallHandler { call, result ->
               //call.method 来获取方法名
               //call.arguments 来获取入参
               //result.success来放回成功处理结果
               //result.error来放回失败后的结果
               //result.notImplemented来放回为实现该方法
         }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    Native ------>Flutter
    在( Flutter ——> Native)代码基础上面
    Native端

    channel.invokeMethod(flutterMethod, args, new MethodChannel.Result () {
    			 //方法重写
            @Override
            public void success(@Nullable Object o) {
            }
           @Override
           public void error(String s, @Nullable String s1, @Nullable Object o) {
    			}
    			@Override
           public void notImplemented() {
                    }
                })
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    Flutter端

    _channel.setMethodCallHandler((MethodCall call) {
          //call.method 来获取方法名
          //call.arguments 来获取参数
        });
    
    • 1
    • 2
    • 3
    • 4

    2.本地方法编写

    在 Flutter 1.12 ,插件 API 升 级到了 2.0 。
    API 2.0 之前。
    开发者通常要在 MainActivity 的 onCreate() 方法中手动调用 GeneratedPluginRegistrant.registerWith() 来执行插件类中的一个静态方法初始化插件。
    API 2.0 之后,出现了 FlutterPlugin 接口。
    开发者只要让创建的插件类实现它,并把初始化代码放到一个重写的方法中就好了。

    //API 2.0 之前。
    public class MainActivity extends FlutterActivity {
    	 @Override
    	 protected void onCreate(Bundle savedInstanceState) {
    	 super.onCreate(savedInstanceState);
    	 GeneratedPluginRegistrant.registerWith(this);
     }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
     //API2.0之后
         @Override
         public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
         super.configureFlutterEngine(flutterEngine);
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    PS知识点

    1. 启动一个 Android 应用,启动的通常是一个 Activity ,如果这个应用是 Flutter 应用,那么这个 Activity 是 FlutterActivity
    2. 在 FlutterActivity 的 onCreate() 方法中,创建了一个 FlutterEngine ,是一个单独的 Flutter 执行环境,通过它,可以让一个 Android 应用运行 Dart 代码。FlutterEngine 提供了,FlutterRenderer 负责渲染视图。DartExecutor 作为 BinaryMessenger 用来和 Flutter 端通信。我们创建 MethodChannel 就要用到这个。

    3.flutter通过原生获取手机电量示例代码如下:


    MainActivity

    package com.example.item_1;
    
    import androidx.annotation.NonNull;
    
    import io.flutter.embedding.android.FlutterActivity;
    
    import io.flutter.embedding.engine.FlutterEngine;
    
    import io.flutter.plugins.GeneratedPluginRegistrant;
    
    import io.flutter.plugin.common.MethodChannel;
    
    import android.content.ContextWrapper;
    
    import android.content.Intent;
    
    import android.content.IntentFilter;
    
    import android.os.BatteryManager;
    
    import android.os.Build.VERSION;
    
    import android.os.Build.VERSION_CODES;
    
    import android.os.Bundle;
    //单独打开android环境下能够查看目录
    public class MainActivity extends FlutterActivity {
        //定义一个私有的静态成员变量
        private static final String CHANNEL = "com.jk/battery";
        //初始化
        @Override
        public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
            super.configureFlutterEngine(flutterEngine);
            //创建MethodChannel对象,添加调用方法
            //写法1:
    //        new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
    //                new MethodChannel.MethodCallHandler() {
    //                    @Override
    //                    public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
    //                        // 通过methodCall可以获取参数和方法名  执行对应的平台业务逻辑即可
    //                        if(methodCall.method.equals("getBatteryLevel")){
    //                            int batteryLevel = getBatteryLevel();
    //                            if(batteryLevel != -1){
    //                                result.success(batteryLevel);
    //                            }else{
    //                                result.error("UNAVAILABLE", "Battery level not available.", null);
    //                            }
    //                        }else{
    //                            result.notImplemented();
    //                        }
    //                    }
    //                }
    //        );
            //写法2:
            //新版的Flutter SDK默认使用的是 import io.flutter.embedding.android.FlutterActivity; 包,
            // 则在MethodChannel方法中的第一个参数填写 getFlutterEngine().getDartExecutor().getBinaryMessenger()
            //如果你使用的Flutter的SDK是旧版本,那么默认的是 import io.flutter.app.FlutterActivity; 包
            // 则MethodChannel方法中的第一个参数填写 getFlutterView()
            MethodChannel methodChannel = new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL);
            methodChannel.setMethodCallHandler(
                    (call, result) -> {
                        //如果等于flutter中传过来的方法名称
                        if (call.method.equals("getBatteryInfo")) {
                            //调用另外一个自定义方法回去电量信息
                            int batteryLevel = getBatteryLevel();
                            if (batteryLevel != -1) {
                                result.success(batteryLevel);
                            } else {
                                result.error("UNAVAILABLE", "Battery level not available.", null);
                            }
                        } else {
                            //如果没有这个方法名称就返回没有这个接口
                            result.notImplemented();
                        }
                    }
            );
        }
        private int getBatteryLevel() {
    
            int batteryLevel = -1;
    
            if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
    
                BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);
    
                batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
    
            } else {
    
                Intent intent = new ContextWrapper(getApplicationContext()).
    
                        registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
    
                batteryLevel = (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) /
    
                        intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
    
            }
            return batteryLevel;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101

    Flutter

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    class PageOne extends StatefulWidget {
      const PageOne({Key key}) : super(key: key);
    
      @override
      State<PageOne> createState() => _Page_oneState();
    }
    class _Page_oneState extends State<PageOne> {
      String value = "电量剩余";
      //建立与原生交互的连接点
      static const channel = const MethodChannel("com.jk/battery");
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("通过原生获取电量"),
          ),
          body: Container(
            child: Column(
              children: [
                Text("$value"),
                FloatingActionButton(onPressed: ()=>getData(),child: Text("电量"),)
              ],
            ),
          ),
        );
      }
      Future getData()async{
        String batteryLevel;
        final int result = await channel.invokeMethod("getBatteryInfo");
        try{
          //从原生种获取当前channel中的方法值
          final int result = await channel.invokeMethod("getBatteryInfo");
          batteryLevel = 'Battery level at $result % .';
        }on PlatformException catch(e){
          batteryLevel = "Failed to get battery level: '${e.message}'.";
        }
        setState(() {
          value = batteryLevel;
        });
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    在这里插入图片描述

  • 相关阅读:
    element-table 行的拖拽更改顺序(无需下载sortableJs
    异步性能不如同步?通过压测讨论应该如何设置线程数
    BF518/BF516/BF514/BF512系列DSP的开发教程四十一:数字信号处理-FFT
    Unity UI Toolkit学习笔记-Runtime UI 案例实践
    GO框架基础 (三)、xorm库
    职场CPU反着用!爽呆了!
    某学生宿舍楼设计
    零等待编程体验:AirCode带您进入无界限编程世界
    [附源码]SSM计算机毕业设计智能超市导购系统JAVA
    记一次生产大对象及GC时长优化经验
  • 原文地址:https://blog.csdn.net/qq_43547255/article/details/125413021