Flutter 和Android 的交互之 MethodChannel

Flutter 和 Android 的交互网上的博文非常多,包括Flutter中文网上面关于MethodChannel 的内容,都已经过时了。比如Fluter 中文网上面写道的Android客户端集成如下:


import io.flutter.app.FlutterActivity;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

public class MainActivity extends FlutterActivity {
    private static final String CHANNEL = "samples.flutter.io/battery";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
          new MethodCallHandler() {
             @Override
             public void onMethodCall(MethodCall call, Result result) {
                 // TODO
             }
          });
    }
}

上面集成的是 io.flutter.app.FlutterActivity,通过 getFlutterView() 和 字符串来 构造 MethodChannel ,然后设置来自于 Flutter 调用的监听。

现在我们集成新的 Flutter SDK ,继承的Activity是 io.flutter.embedding.android.FlutterActivity,此FlutterActivity已经不存在 getFlutterView() 方法了,所以Android 和 Flutter的交互也要改变。

集成的流程如下:

1.Android 客户端的代码如下:
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.Nullable;

import io.flutter.embedding.android.FlutterActivity;
import io.flutter.plugin.common.MethodChannel;

public class FlutterAppActivity extends FlutterActivity {

    private final static String CHANNEL_NATIVE = "com.zhujiangtao.flutter";
    private MethodChannel mMethodChannel;

    public static void enter(Context context) {
        Intent intent = new NewEngineIntentBuilder(FlutterAppActivity.class)
                    .initialRoute("zhujiangtao?msg=test&id=10010")
                    .build(context);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 初始化 MethodChannel
        mMethodChannel = new MethodChannel(getFlutterEngine().getDartExecutor().getBinaryMessenger(), CHANNEL_NATIVE);
        // Flutter 调用 android 的方法会执行到此回调
        mMethodChannel.setMethodCallHandler((call, result) -> {
            Log.e("xxxxx", "method = " + call.method);
            switch (call.method) {
                case "callNative":
                    Toast.makeText(FlutterAppActivity.this, call.argument("arg1"), Toast.LENGTH_LONG).show();
                    callFlutter();
                    // 将结果回调给 Flutter 
                    result.success("我是来自Native的回调");
                    break;
            }
        });

    }

    private void callFlutter() {
        // Android 端调用 Flutter 的方法
        mMethodChannel.invokeMethod("callFlutter", "name=zhujiangtao", new MethodChannel.Result() {
            @Override
            public void success(@Nullable Object result) { // Flutter 回调过来的结果
                if (result != null) {
                    Toast.makeText(FlutterAppActivity.this, result.toString(), Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) {

            }

            @Override
            public void notImplemented() {

            }
        });
    }
}

里面清晰的注释了,Android 是如何调用 Flutter 和 Flutter 是怎么调用Android的。

2. AndroidManifest.xml 中注册且处理跳转到Flutter页面黑屏问题

<!--就是之前写的Activity-->
 <activity android:name=".ui.FlutterAppActivity"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">

            <meta-data
                android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
                android:value="true" />
            <!--解决android进入Flutter的黑屏问题-->
            <meta-data
                android:name="io.flutter.embedding.android.SplashScreenDrawable"
                android:resource="@drawable/flutter_splash_bg" />

        </activity>

3. Flutter 端的代码调用原生方法和原生调用Flutter的回调

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:my_flutter/pages/list_view.dart';

class MyMethodChannel extends StatefulWidget{

  @override
  State<StatefulWidget> createState() {
    return MyMethodState();
  }

}

class MyMethodState extends State<MyMethodChannel>{
  String _content;
  // 这里面的 “com.zhujiangtao.flutter”要和 Java 代码中 初始化 MethodChannel的值保持一致
  static MethodChannel _methodChannel = MethodChannel('com.zhujiangtao.flutter');
  
  @override
  void initState() {
    _methodChannel.setMethodCallHandler(_methodChannelHandler);
    super.initState();
  }
  
  @override
  Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(title: Text("TestMethodChannel"),),
     body: Center(
       child: Column(
         children: <Widget>[
           Text('$_content'),
           RaisedButton(
             onPressed: callNative,
             child: Text("callNative"),
           ),
           
           RaisedButton(
             onPressed: (){
             Navigator.push(context, MaterialPageRoute(builder: (context) => TestListView()));
           },
             child: Text('ListView'),
           ),
         ],
       ),
     ),
   );
  }

  /// Flutter 调用原生
  Future<void> callNative() async {
    print("----------------callNative--------------------");
   var res = await _methodChannel.invokeMethod("callNative", {"arg1": "I am from Flutter"});
    //Android收到调用之后返回的数据
    setState(() {
      _content = res;
    });
  }

  /// 原生 调用 Flutter的结果回调
  Future<String> _methodChannelHandler(MethodCall call) async{
    String result = "";
    print("---------------_methodChannelHandler------------------------ method = ${call.method}");
    switch(call.method){
      case "callFlutter":
        setState(() {
          _content = call.arguments.toString();
        });
        result = "Flutter 收到 Android发来的消息";
        break;
    }
    return result;
  }
  
}

里面也是 初始化 MethodChannel ,然后逻辑和原生的差不多;

invokeMethod :原生和Flutter都是调用此方法来和对方通信;

setMethodCallHandler:都是结果的回调。

以上就是 Flutter 和 原生 的交互过程。

以后文章会同步到个人公众号,欢迎关注交流

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值