第一种: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上,并进行视图更新。