基於Flutter Version:1.22.3, Dart Version:2.10.3
FlutterPlugin提供了Android和ios的底層封裝,在Flutter層提供組件功能,使得Flutter可以比較方便得調用Native得模塊,對於Flutter實現比較複雜或者基於平臺不能完成得部分,都可以封裝成Plugin。
本文都是android得樣例。
Flutter調用android原生實現,封裝成Plugin
基本流程
- Flutter端聲明MethodChannel,並通過invokeMethod函數調用native的函數
- Android聲明Plugin,創建與Flutter端對應的MethodChannel,對Flutter端聲明的函數進行監聽,並進行相應的處理
- 在Plugin機制中綁定兩者的關係。
此處以調用Android原生的日誌爲例進行講解
1.Flutter端聲明一個log_util.dart文件
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
class LogUtils {
///聲明的通道名稱
static const String _channelName = 'flutter.io/system/log';
///判斷是否是debug環境
static bool get _isDebug => !bool.fromEnvironment("dart.vm.product");
///創建渠道對象
static const _channel = const MethodChannel(_channelName);
///通過命名函數來實現類似java中重載機制
static void v({@required String message, String tag}) {
if (_isDebug) {
///調用函數來執行,
///invokeMethod參數
///[String method]:指定方法名,Android端需要監聽並做處理的
///[dynamic arguments]:需要傳遞給Android端的參數
_channel.invokeMethod('logV', {'tag': tag ?? '', 'message': message ?? ''});
}
}
static void d({@required String message, String tag}) {
if (_isDebug) {
_channel.invokeMethod('logD', {'tag': tag ?? '', 'message': message ?? ''});
}
}
static void i({@required String message, String tag}) {
if (_isDebug) {
_channel.invokeMethod('logI', {'tag': tag ?? '', 'message': message ?? ''});
}
}
static void w({@required String message, String tag}) {
if (_isDebug) {
_channel.invokeMethod('logW', {'tag': tag ?? '', 'message': message ?? ''});
}
}
static void e({@required String message, String tag}) {
if (_isDebug) {
_channel.invokeMethod('logE', {'tag': tag ?? '', 'message': message ?? ''});
}
}
}
2.Android端plugin的編寫
在android端的項目中有一個目錄如下,
image.png
package io.flutter.plugins;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
/**
* 打印日誌plugin
*/
public class LogPlugin implements FlutterPlugin , MethodChannel.MethodCallHandler{
private static final String mChannelName = "flutter.io/system/log";//與Flutter端對應的通道名稱
private static final String LOG_V = "logV";
private static final String LOG_D = "logD";
private static final String LOG_I = "logI";
private static final String LOG_W = "logW";
private static final String LOG_E = "logE";
private MethodChannel mMethodChannel;
private Context mApplicationContext;
/**
* 當plugin與FlutterEngine相關聯時調用
* @param binding
*/
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
//獲取上下文對象,可以發起跳轉Activity等操作
mApplicationContext = binding.getApplicationContext();
//創建通道對象
mMethodChannel = new MethodChannel(binding.getBinaryMessenger(),mChannelName);
//添加對Flutter端調用函數的監聽
mMethodChannel.setMethodCallHandler(this);
}
/**
* 當plugin與FlutterEngine解除關聯時調用,用來清除資源等。
* @param binding
*/
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
mApplicationContext = null;
mMethodChannel.setMethodCallHandler(null);
mMethodChannel = null;
}
/**
* 對Flutter端調用函數的監聽
* @param call
* @param result
*/
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
//獲取傳遞過來的參數
String tag = call.argument("tag");
String message = call.argument("message");
//獲取Flutter端調用的函數名稱
String method = call.method;
switch (method){
case LOG_V:
Log.v(tag,message);
break;
case LOG_D:
Log.d(tag,message);
break;
case LOG_I:
Log.i(tag,message);
break;
case LOG_W:
Log.w(tag,message);
break;
case LOG_E:
Log.e(tag,message);
break;
}
}
}
3.在FlutterEngine的plugin中添加LogPlugin建立關聯
package com.example.flutter_first;
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.LogPlugin;
public class MainActivity extends FlutterActivity {
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
flutterEngine.getPlugins().add(new LogPlugin());
}
}
調用如下: