Flutter 調用 Android Native 的方法,是通過MethodChannel的方式來實現(xiàn)的。
Android端:
實現(xiàn)方式一:
- 創(chuàng)建一個Class,實現(xiàn)FlutterPlugin 和 MethodCallHandler 接口
- 重寫onAttachedToEngine(),onDetachedFromEngine(),onMethodCall() 這3個方法
- onMethodCall方法中,通過自定義的METHOD_NAME,來響應Flutter中,invokeMethod對Native的通信
- 在io.flutter.plugins包下的GeneratedPluginRegistrant添加代碼 flutterEngine.getPlugins().add(SpeechPlugin1.Companion.getINSTANCE());
代碼如下:
/**
* todo Flutter 調用 Android Native 的方法 2
* 1、創(chuàng)建一個Class,實現(xiàn)FlutterPlugin和MethodCallHandler接口
* 2、重寫onAttachedToEngine(),onDetachedFromEngine(),onMethodCall()
* 3、onMethodCall中,通過自定義的METHOD_NAME,來響應Flutter中,invokeMethod對Native的通信,
* 4、在io.flutter.plugins包下的GeneratedPluginRegistrant添加代碼 flutterEngine.getPlugins().add(SpeechPlugin1.Companion.getINSTANCE());
*/
class SpeechPlugin1:MethodChannel.MethodCallHandler,FlutterPlugin {
private var methodChannel: MethodChannel? = null
private var context:Context ?= null
companion object{
private const val CHANNEL_NAME = "speech_plugin"
val INSTANCE : SpeechPlugin1 by lazy (mode = LazyThreadSafetyMode.SYNCHRONIZED){
SpeechPlugin1()
}
}
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
methodChannel = MethodChannel(binding.binaryMessenger,CHANNEL_NAME)
context= binding.applicationContext
methodChannel?.setMethodCallHandler(this)
}
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
methodChannel?.setMethodCallHandler(null)
methodChannel = null
}
@SuppressLint("SimpleDateFormat")
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when(call.method){
"android_time" -> result.success(SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(System.currentTimeMillis()))
"toast" -> {
if (call.hasArgument("msg") && !TextUtils.isEmpty(call.argument<String>("msg"))) {
Toast.makeText(context, call.argument<String>("msg"), Toast.LENGTH_LONG).show()
} else {
Toast.makeText(context, "msg 不能為空", Toast.LENGTH_SHORT).show()
}
}
else ->result.notImplemented()
}
}

image.png
實現(xiàn)方式二:
在繼承了FlutterActivity的MainActivity類中重寫configureFlutterEngine方法
class MainActivity: FlutterActivity() {
private lateinit var speechPlugin: SpeechPlugin2
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
speechPlugin = SpeechPlugin2(this)
//通過MethodChannel與原生通信
val methodChannel = MethodChannel(flutterEngine.dartExecutor, "speech_plugin")
methodChannel.setMethodCallHandler(speechPlugin)
}
class SpeechPlugin2(private val context: Context) : MethodChannel.MethodCallHandler {
@SuppressLint("SimpleDateFormat")
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when(call.method){
"android_time" -> result.success(SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(System.currentTimeMillis()))
"toast" -> {
if (call.hasArgument("msg") && !TextUtils.isEmpty(call.argument<String>("msg"))) {
Toast.makeText(context, call.argument<String>("msg"), Toast.LENGTH_LONG).show()
} else {
Toast.makeText(context, "msg 不能為空", Toast.LENGTH_SHORT).show()
}
}
else ->result.notImplemented()
}
}
}
Flutter端:
- 根據(jù)Native中定義的METHOD_NAME來創(chuàng)建MethodChannel
- 通過MethodChannel.invokeMethod(METHOD_NAME,params),參數(shù)METHOD_NAME為Native中定義的METHOD_NAME,params為傳遞的參數(shù),就可以和Native進行通信了,在Native的onMethodCall方法中,通過call.method == METHOD_NAME來確定,F(xiàn)lutter是否調用的是Native中定義的METHOD_NAME的方法,
class SpeechPlugin {
//一定要和android native端一致
static const String METHOD_NAME = "speech_plugin";
//定義與Native進行交互的MethodChannel,Android與Ios通用
static const MethodChannel _methodChannel = MethodChannel(METHOD_NAME);
//通過安卓獲取當前時間
static Future<String> getAndroidTime() async {
//通過MethodChannel對象的invokeMethod()方法調用原生方法
var time = await _methodChannel.invokeMethod("android_time");
return Future.value(time);
}
//顯示安卓土司
static showAndroidToast(String message) async {
try{
await _methodChannel.invokeMethod("toast",{"msg":message});
} on PlatformException catch(e){ //使用 catch on 捕獲不同類型的錯誤
// handle PlatformException
print(e.toString());
}
}
}
//獲取到android端的系統(tǒng)時間后,再傳遞給android端。用android端的吐司顯示出來
void _showAndridToast(SearchViewModel model) {
SpeechPlugin.getAndroidTime().then((message) {
SpeechPlugin.showAndroidToast(message);
});
}