当前位置:网站首页>Flutter与原生通信(上)

Flutter与原生通信(上)

2022-06-26 09:37:00 可可鸭~

一 、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");

Flutter端

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

setMethodCallHandler 方法注解

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

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() {
    
                }
            })

Flutter端

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

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);
 }
}
 //API2.0之后
     @Override
     public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
    
     super.configureFlutterEngine(flutterEngine);
  }

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;
    }
}

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;
    });
  }
}

在这里插入图片描述

原网站

版权声明
本文为[可可鸭~]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_43547255/article/details/125413021