Flutter与Android 互相通信(Kotlin版)

Android与Flutter之间的通信共有四种实现方式。

1.由于在初始化flutter页面时会传递一个字符串——route,因此我们就可以拿route来做文章,传递自己想要传递的数据。该种方式仅支持单向数据传递且数据类型只能为字符串,无返回值。
2.通过EventChannel来实现,EventChannel仅支持数据单向传递,无返回值。
3.通过MethodChannel来实现,MethodChannel支持数据双向传递,有返回值。
4.通过BasicMessageChannel来实现,BasicMessageChannel支持数据双向传递,有返回值。

本文采用的是MethodChannel方式,如要看其他三种请直接移动到文章底部

Flutter 调用原生

1 首先我们要在Android中定义插件

class FlutterPluginTestNewPlugin(
        private  val activity: Activity) : MethodCallHandler {

    override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
        if (call.method == "download") {
            Log.e("onMethodCall", call.method)
            result.success("Android")
            download()
        } else if(call.method=="play") {
            val intent = Intent(activity, DownloadPlayActivity::class.java)
            intent.putExtra("proxy_url", MainActivity.item.proxyUrl)
            intent.putExtra("origin_url", MainActivity.item.url)
            activity.startActivity(intent)
        }else{
            result.notImplemented()
        }
    }

    companion object {
        private var channel: MethodChannel? = null

        /// 保留旧版本的兼容
        fun registerWith(registry: PluginRegistry) {
            val registrar: PluginRegistry.Registrar = registry.registrarFor("flutter_plugin_test_new")
            channel = MethodChannel(registrar.messenger(), "flutter_plugin_test_new")
            channel!!.setMethodCallHandler(FlutterPluginTestNewPlugin(registrar.activity()))
        }
    }


    private fun download(){
        if (MainActivity.item.isRunningTask) {
            LogUtils.d("jeffmony pause downloading.")
            VideoDownloadManager.getInstance().pauseDownloadTask(MainActivity.item)
        } else if (MainActivity.item.isSlientTask) {
            LogUtils.d("jeffmony start downloading.")
            VideoDownloadManager.getInstance().startDownload(MainActivity.item)
        }
    }

}

我定义了两个flutter调用Android的方法 download ,play

2 Android 插件注册

class MainActivity: FlutterActivity() {
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
         GeneratedPluginRegistrant.registerWith(this@MainActivity)
        FlutterPluginTestNewPlugin.registerWith(this@MainActivity)


    }

3 Flutter 调用原生插件

const platform = const MethodChannel('flutter_plugin_test_new');
      final String result = await platform.invokeMethod('download');

需要注意的是 方法名要一致,(方法支持带参数),要有共同的Channel flutter_plugin_test_new (自己定义代表一个事件的tag)

简单提一下带参数的调用:
Flutter端发起

Map map = {"url": “123456”};
 platform.invokeMethod('download',map);

Android端接收

 val url: String? = call.argument("url")

原生调用 Flutter

1Android 定义插件

class MyFlutterEventPlugin implements EventChannel.StreamHandler {
    public static EventChannel.EventSink eventSink;

    public static MyFlutterEventPlugin registerWith(PluginRegistry registry) {
        String CHANNEL = "event_plugin";
        PluginRegistry.Registrar registrar = registry.registrarFor(CHANNEL);
        EventChannel eventChannel = new EventChannel(registrar.messenger(), CHANNEL);
        MyFlutterEventPlugin myFlutterEventPlugin = new MyFlutterEventPlugin();
        eventChannel.setStreamHandler(myFlutterEventPlugin);
        return myFlutterEventPlugin;
    }

    @Override
    public void onListen(Object o, EventChannel.EventSink eventSink) {
        this.eventSink = eventSink;
    }

    @Override
    public void onCancel(Object o) {
    }
}

2.Android 插件注册 & 调用

public class MainActivity extends FlutterActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GeneratedPluginRegistrant.registerWith(this);
            MyFlutterEventPlugin.registerWith(this)
        MyFlutterEventPlugin eventPlugin = MyFlutterEventPlugin.registerWith(this);
   // 成功的回调
      MyFlutterEventPlugin.eventSink!!.success(“6666”)
      //失败回调
// MyFlutterEventPlugin.eventSink!!.error("计时器异常", "计时器异常", e.message)

    }
}

3.Flutter 注册监听器接收来自原生的消息

const myEventPlugin = const EventChannel('event_plugin');

  @override
  void initState() {
    super.initState();
    //设置监听
    myEventPlugin.receiveBroadcastStream().listen(_onEvent, onError: _onError);
  }
  void _onEvent(Object event) {
  // 这里的event事Object类型  可以接收各种类型的参数
    print("onEvent: $event");
  }
  void _onError(Object error) {
    print("onError: $error");
  }

温馨提示:
本文涉及到Flutter中Android插件的开发以及引用,不熟悉的同学请前往https://www.jianshu.com/p/4a9b6bf43b38学习如何构建插件,再看本文会得心应手。

本文基于Flutter 1.12之前,1.12之后插件写法可以沿用这种(已兼容),也可以进行升级,升级注意事项请前往https://blog.csdn.net/ZuoYueLiang/article/details/103706627

Flutter与原生交互总结
https://www.jianshu.com/p/f35da4195df9

你可能感兴趣的:(Flutter学习)