flutter和Android通信三种方式

238 阅读2分钟

第一种:MethodChannel

MethodChannel:Android原生和flutter直接相互传值。

flutter下的android项目中,activity继承FlutterActivity重写configureFlutterEngine方法

class MainActivity : FlutterActivity(){

    companion object{
        private const val MethodChannel = "MethodChannel/test"
    }

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger,
            MethodChannel).setMethodCallHandler { call, result ->
            if (call.method == "startNativeActivity") {
                val data = "Android ${android.os.Build.VERSION.RELEASE}"
                Log.d(TAG,"data:$data")
                result.success(data)
            } else {
                result.notImplemented()
            }
        }
    }
}

flutter侧代码如下:

/// async:标记为异步函数,可以使用await关键字来等待其他异步操作完成,不会阻塞主线程
Future<void> _startNativeActivity() async{
  const platform = MethodChannel("MethodChannel/test");
  try {
    final result = await platform.invokeMethod("startNativeActivity");
    print("=test====result:$result");
  }on PlatformException catch (e) {
    print("=test====error:${e.message}");
  }
}
运行结果:
data:Android 14
=test====result:Android 14

flutter侧通过MethodChannel("MethodChannel/test") 和invokeMethod("startNativeActivity") 去原生Android中匹配调用。

第二种EventChannel

android端代码:flutter端通过MethodChannel调用startCounting,在原生侧开始初始化EventChannel,原生侧开始发送EventChannel消息。

private var eventSkin: EventChannel.EventSink? = null
private var eventHandler: Handler? = null
/**
 * 计数器
 */
private var count: Int = 0

private val runnable = object : Runnable {
    override fun run() {
        if (count >= 50) {
            eventSkin?.endOfStream()
        } else {
            count++
            Log.d(TAG, "count:$count")
            eventSkin?.success(count)
        }
        eventHandler?.postDelayed(this, 200)
    }

}

companion object {
    private const val MethodChannel = "MethodChannel/test"
    private const val EventChannel = "EventChannel/test"
}

override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    MethodChannel(
        flutterEngine.dartExecutor.binaryMessenger,
        MethodChannel
    ).setMethodCallHandler { call, result ->
        Log.d(TAG,"method:${call.method}")
        when (call.method) {
            "startCounting" -> {// 收到startCounting消息后开始初始化EventChannel时间,
                // 通过EventChannel每隔200ms向flutter发送一个消息,
                Log.d(TAG, "startCounting")
                EventChannel(
                    flutterEngine.dartExecutor.binaryMessenger,
                    EventChannel
                ).setStreamHandler(object : EventChannel.StreamHandler {
                    override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
                        eventSkin = events
                        count = 0
                        eventHandler = Handler()
                        runnable.run()
                        Log.d(TAG, "onListen")
                    }

                    override fun onCancel(arguments: Any?) {
                        eventHandler?.removeCallbacks(runnable)
                        eventSkin = null
                        Log.d(TAG, "onCancel")
                    }

                })
                result.success(true)
            }
            else -> {
                result.notImplemented()
            }
        }
    }
}

flutter端:

/**
 * 调用Android端的startCounting方法去初始化eventChannel,并监听原生侧发送过来的eventChannel事件
 */
Future<void> _startCounting() async {
  const platform = MethodChannel("MethodChannel/test");
  try {
    final result = await platform.invokeMethod("startCounting");
    _streamSubscription = _eventChannel.receiveBroadcastStream().listen((
      event,
    ) {
      print("=test=startCounting===event:$event");
    });
    print("=test====result:$result");
  } on PlatformException catch (e) {
    print("=test====error:${e.message}");
  }
}
输出:
method:startCounting
startCounting
=test====result:true
count:1
onListen
=test=startCounting===event:1
count:2
=test=startCounting===event:2
count:3
=test=startCounting===event:3
....
count:50
=test=startCounting===event:50
onCancel

第三种 platFormView

/**
 * 自定义View,用于接收flutter传过来的参数
 */
class MyTextView(context: Context, params: String?) : TextView(context), PlatformView {
    init {
        params?.also {
            text = "$params"
        }
    }

    override fun getView(): View? {
        return this
    }

    override fun dispose() {
        Log.d(TAG, "dispose")
    }
}

/**
 * 用于创建原生视图
 */
class NativeTextViewFactory() : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
    override fun create(context: Context?, viewId: Int, args: Any?): PlatformView {
        val message = args as Map<*, *>
        Log.d(TAG, "flutter创建默认值:$message")
        return MyTextView(context!!, message["text"].toString())
    }

}

class MainActivity : FlutterActivity() {
    companion object {
        private const val MethodChannel = "MethodChannel/test"
        private const val NativeChannel = "NativeChannel/test"
    }

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        Log.d(TAG, "configureFlutterEngine")
        MethodChannel(
            flutterEngine.dartExecutor.binaryMessenger,
            MethodChannel
        ).setMethodCallHandler { call, result ->
            Log.d(TAG, "method:${call.method}")
            when (call.method) {
                "sendMessage" -> {// 收到startCounting消息后开始初始化EventChannel时间,
                    // 通过EventChannel每隔200ms向flutter发送一个消息,
                    Log.d(TAG, "startCounting")
                    val message = call.arguments as Map<*, *>
                    val viewId = message["viewId"].toString().toInt()
                    val platformView =
                        flutterEngine.platformViewsController.getPlatformViewById(viewId)
                    val myView = platformView as? MyTextView
                    val msg = message["messge"].toString()
                    myView?.text = msg
                    Log.d(TAG, "message:${msg}")
                    result.success(true)
                }

                else -> {
                    result.notImplemented()
                }
            }
        }
        // 访问Flutter引擎的平台视图注册表
        flutterEngine.platformViewsController.registry.registerViewFactory(
            NativeChannel,
            NativeTextViewFactory()
        )
    }
}
/**
 * 通过MethodChannel通知原生更新AndroidView绑定的view的内容
 */
Future<void> _sendMessageToNative(String message) async {
  const platform = MethodChannel("MethodChannel/test");
  try {
    final result = await platform.invokeMethod("sendMessage",{'messge':message,'viewId':viewId});
    print("=test====result:$result");
  } on PlatformException catch (e) {
    print("=test====error:${e.message}");
  }
}

/// 通过AndroidView与原生view绑定
SizedBox(
  height: 200,
  width: 300,
  child: AndroidView(
    viewType: "NativeChannel/test",
    creationParamsCodec: StandardMessageCodec(),
    creationParams: {"text": "flutter默认值"},
    onPlatformViewCreated: (int id){
      setState(() {
        viewId = id;
      });
    },
  ),
),

通过AndroidView实现原生view贴到flutter的widget上,并进行视图更新。