Flutter 调用原生系统日志库

这里以 Flutter 调用原生系统日志库,来理解下 Flutter 与 Android 交互

这里创建的时候用到了 Kotlin 、AndroidX

 

Android端

进入 android 目录下的 build.gradle ,点击 Open for Editing in Android Studio ,打开新的 android项目。

App 目录下 build.gradle 引入第三方日志封装库

dependencies {
    implementation 'com.orhanobut:logger:2.2.0'
}

第三方库当然需要初始化等一些操作,这里多数很熟悉,直接上代码

定义 App(Application),继承 FlutterApplication ,注意在 AndroidManifest.xml 中配置

App 中

class App : FlutterApplication() {
    override fun onCreate() {
        super.onCreate()
        mApp = this
        //...
        Logger.addLogAdapter(AndroidLogAdapter(formatStrategy))
    }

    companion object {
        lateinit var mApp: Context
    }
}

orhanobut.logger.Logger 参考它的 GitHub 用法

MainActivity (继承 FlutterActivity) 中复写 configureFlutterEngine 方法,但首先需要确定一个唯一的字符串标识符,来构造一个命名通道,这里以 "com.milanxiaotiejiang.plugins/log" 命名

class MainActivity : FlutterActivity() {
    private val CHANNEL_LOG = "com.milanxiaotiejiang.plugins/log"
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
//        super.configureFlutterEngine(flutterEngine)
        GeneratedPluginRegistrant.registerWith(flutterEngine)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_LOG)
                .setMethodCallHandler { call, result ->
                    val arguments = call.arguments.toString()
                    when (call.method) {
                        "logI" -> Logger.i(arguments)
                        "logD" -> Logger.d(arguments)
                        "logV" -> Logger.v(arguments)
                        "logW" -> Logger.w(arguments)
                        "logE" -> Logger.e(arguments)
                    }
                    result.success(true)
                }
    }

}

这里  super.configureFlutterEngine(flutterEngine)  与   GeneratedPluginRegistrant.registerWith(flutterEngine) 两方法都可以。

setMethodCallHandler :设置方法处理回调,可以取出方法名,进行判断,最后调用相应的原生方法。

而 result 为返回结果,它有三个方法

  public interface Result {
    @UiThread
    void success(@Nullable Object result);

    @UiThread
    void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails);

    @UiThread
    void notImplemented();
  }

Android 端准备完毕

 

Flutter端

定义 log_services.dart 文件,这里 MethodChannel 中 name 就是原生中定义的唯一的字符串标识符,调用 invokeMethod 方法 + 调用原生方法名可实现。

import 'package:flutter/services.dart';

//声明MethodChannel
const _platform = const MethodChannel('com.milanxiaotiejiang.plugins/log');

class Logger {
  Logger._();

  //invokeMethod方法接收的参数,第一个必选参数,设置的是方法的名称;后面的参数为可选的需要传递的参数

  static void i(String msg) async {
    _platform.invokeMethod('logI', {'msg': msg});
  }

  static void d(String msg) async {
    _platform.invokeMethod('logD', {'msg': msg});
  }

  static void v(String msg) async {
    _platform.invokeMethod('logV', {'msg': msg});
  }

  static void w(String msg) async {
    _platform.invokeMethod('logW', {'msg': msg});
  }

  static void e(String msg) async {
    _platform.invokeMethod('logE', {'msg': msg});
  }
}

这样 Flutter 调用 Logger 就可以在 logcat 中显示日志了。

 

ios 本人不是很了解,也没有设备,就不提及 ios 了哈!以一张图看 Dart 与 原生 之间的通信

Flutter 调用原生系统日志库_第1张图片

 

需要注意的是,在使用方法通道进行方法调用时,由于涉及到跨系统数据交互,Flutter 会使用 StandardMessageCodec 对通道中传输的信息进行类似 JSON 的二进制序列化,以标准化数据传输行为。这样在我们发送或者接收数据时,这些数据就会根据各自系统预定的规则自动进行序列化和反序列化。

另外方法通道是非线程安全的。这意味着原生代码与 Flutter 之间所有接口调用必须发生在主线程。Flutter 是单线程模型,因此自然可以确保方法调用请求是发生在主线程(Isolate)的;而原生代码在处理方法调用请求时,如果涉及到异步或非主线程切换,需要确保回调过程是在原生系统的 UI 线程中执行的,否则应用可能会出现奇怪的 Bug,甚至是 Crash。

那么,我们可以将 Android 中网络请求放在原生,调用 Flutter 中创建异步任务调用原生 API 请求后台。这样可以使用更强大的 OkHttp,甚至 Mars。

 

你可能感兴趣的:(flutter知识体系)