300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > flutter图片点击跳转_Flutter系列之Platform Channel使用详解

flutter图片点击跳转_Flutter系列之Platform Channel使用详解

时间:2023-07-15 08:16:28

相关推荐

flutter图片点击跳转_Flutter系列之Platform Channel使用详解

PS:逐渐体会到关键少数原则的重要性,接下来就是付诸实践了,另外科创50ETF明天开始限额销售,可以适当关注或入手一点。

前面几篇文章介绍了 Navigator 组件、Flex 布局、图片加载、Widget 生命周期、混合开发等 Flutter 开发基础知识,链接如下:

Flutter系列之Navigator使用详解

Flutter系列之Flex布局详解

Flutter系列之图片加载详解

Flutter系列之Widget生命周期

Flutter系列之混合开发Android篇

下面介绍一下 Flutter 混合开发中 Platform Channel 的使用,主要内容如下:

平台通道介绍

平台数据类型对照

BasicMessageChannel

MethodChannel

EventChannel

平台通道介绍

Platform Channel 是一个异步消息通道,消息在发送之前会编码成二进制消息,接收到的二进制消息会解码成 Dart 值,其传递的消息类型只能是对应的解编码器支持的值,所有的解编码器都支持空消息,其 Native 与 Flutter 通信架构如下图所示:

Flutter 中定义了三种不同类型的 PlatformChannel,主要有三种如下:

BasicMessageChannel:用于数据传递;

MethodChannel:用于传递方法调用;

EventChannel:用于传递事件;

其构造方法都需指定一个通道标识、解编码器以及 BinaryMessenger,BinaryMessenger 是一个 Flutter 与平台的通信工具,用来传递二进制数据、设置对应的消息处理器等。

解编码器有两种分别是 MethodCodec 和 MessageCodec,前者对应方法后者对应消息,BasicMessageChannel 使用的是 MessageCodec,MethodChannel 和 EventChannel 使用的是 MethodCodec。

平台数据类型对照

Platform Channel 提供不同的消息解码机制,如 StandardMessageCodec 提供基本数据类型的解编码、JSONMessageCodec 支持 Json 的解编码等,在平台之间通信时都会自动转换,各平台数据类型对照如下:

BasicMessageChannel

BasicMessageChannel 主要用来数据传递,包括二进制数据,借助 BasicMessageChannel 可以实现 MethodChannel 和 EventChannel 的功能,这里用 BasicMessageChannel 实现 Android 项目使用 Flutter 资源文件的案例,关键流程如下:

Flutter 端获得图片资源对应的二进制数据,这里使用 BinaryCodec,则数据格式为 ByteData;

使用 BasicMessageChannel 发送图片对应的数据;

在 Android 端使用 ByteBuffer 接收,并将其转换成 ByteArray,然后解析成 Bitmap 显示出来。

Flutter 端关键代码如下:

1//创建BasicMessageChannel 2_basicMessageChannel=BasicMessageChannel("com.manu.image",BinaryCodec()); 3 4//获取assets中的图片对应的ByteData数据 5rootBundle.load('images/miao.jpg').then((value)=>{6_sendStringMessage(value) 7}); 8 9//发送图片数据10_sendStringMessage(ByteDatabyteData)async{11await_basicMessageChannel.send(byteData);12}

Android 端关键代码如下:

1overridefunconfigureFlutterEngine(flutterEngine:FlutterEngine){2super.configureFlutterEngine(flutterEngine) 3Log.i(tag,"configureFlutterEngine") 4//设置消息处理器 5BasicMessageChannel( 6flutterEngine.dartExecutor,"com.manu.image",BinaryCodec.INSTANCE 7).setMessageHandler{message,reply-> 8Log.i(tag,"configureFlutterEngine>message:$message") 9//数据转换:ByteBuffer->ByteArray10valbyteBuffer=messageasByteBuffer11imageByteArray=ByteArray(byteBuffer.capacity())12byteBuffer.get(imageByteArray)13}1415//用于设置Flutter跳转Android的方法处理器16MethodChannel(flutterEngine.dartExecutor,channel).setMethodCallHandler{call,result->17Log.i(tag,"configureFlutterEngine>method:${call.method}")18if("startBasicMessageChannelActivity"==call.method){19//携带图片数据20BasicMessageChannelActivity.startBasicMessageChannelActivity(this,imageByteArray)21}22}23}2425//显示来自Flutterassets中的图片26valimageByteArray=intent.getByteArrayExtra("key_image")27valbitmap=BitmapFactory.decodeByteArray(imageByteArray,0,imageByteArray.size)28imageView.setImageBitmap(bitmap)

另外,BasicMessageChannel 结合 BinaryCodec 是支持大内存数据块的传递的。

MethodChannel

MethodChannel 主要用来方法的传递,自然可以传递 Native 方法和 Dart 方法,即可以通过 MethodChannel 在 Flutter 中调用 Android 原生方法,在 Android 中调用 Dart 方法,互相调用都是通过 MethodChannel 的 invokeMethod 方法调用的,通信时必须使用相同的通道标识符,具体如下:

Flutter调用Android方法

下面通过 MethodChannel 实现从 Flutter 跳转到 Android 原生界面 MainActivity,Android 端如下:

1/** 2*@descFlutterActivity 3*@authorjzman 4*/ 5valtag=AgentActivity::class.java.simpleName; 6 7classAgentActivity:FlutterActivity(){8valtag=AgentActivity::class.java.simpleName; 9privatevalchannel="com.manu.startMainActivity"10privatevarplatform:MethodChannel?=null;1112overridefunconfigureFlutterEngine(flutterEngine:FlutterEngine){13super.configureFlutterEngine(flutterEngine)14Log.d(tag,"configureFlutterEngine")15platform=MethodChannel(flutterEngine.dartExecutor,channel)16//设置方法处理器17platform!!.setMethodCallHandler(StartMethodCallHandler(this@AgentActivity))18}1920companionobject{21/**22*重新创建NewEngineIntentBuilder才能保证生效23*/24funwithNewEngine():MNewEngineIntentBuilder?{25returnMNewEngineIntentBuilder(AgentActivity::class.java)26}27}2829/**30*自定义NewEngineIntentBuilder31*/32classMNewEngineIntentBuilder(activityClass:Class<outFlutterActivity?>?):33NewEngineIntentBuilder(activityClass!!)3435/**36*实现MethodCallHandler37*/38classStartMethodCallHandler(activity:Activity):MethodChannel.MethodCallHandler{39privatevalcontext:Activity=activity40overridefunonMethodCall(call:MethodCall,result:MethodChannel.Result){41if("startMainActivity"==call.method){42Log.i(tag,"arguments:"+call.arguments)43startMainActivity(context)44//向Flutter回调执行结果45result.success("success")46}else{47result.notImplemented()48}49}50}51}

如上还可以使用 MethodChannel.Result 对象向Flutter回调执行结果,Flutter 端如下:

1///State 2class_PageStateextendsState<PageWidget>{3MethodChannelplatform; 4 5@override 6voidinitState(){7super.initState(); 8platform=newMethodChannel('com.manu.startMainActivity'); 9}1011@override12Widgetbuild(BuildContextcontext){13returnContainer(14width:double.infinity,15margin:EdgeInsets.fromLTRB(8,8,8,0),16child:RaisedButton(17onPressed:(){18_startMainActivity();19},20child:Text("FluttertoAndroid"),21),22);23}2425///跳转到原生Activity26void_startMainActivity(){27platform.invokeMethod('startMainActivity','fluttermessage').then((value){28//接收返回的数据29print("value:$value");30}).catchError((e){31print(e.message);32});33}34}

Android调用Dart方法

下面通过 MethodChannel 调用 Flutter 中的 Dart 方法 getName,Android 端代码如下:

1/** 2*@descMainActivity 3*@authorjzman 4*/ 5classMainActivity:FlutterActivity(){6privatevaltag=MainActivity::class.java.simpleName; 7privatevalchannel="com.manu.startMainActivity" 8privatevarmethodChannel:MethodChannel?=null 9overridefunonCreate(savedInstanceState:Bundle?){10super.onCreate(savedInstanceState)11setContentView(R.layout.activity_main)1213btnGetDart.setOnClickListener{14getDartMethod()15}16}1718overridefunconfigureFlutterEngine(flutterEngine:FlutterEngine){19super.configureFlutterEngine(flutterEngine)20Log.i(tag,"configureFlutterEngine")21methodChannel=MethodChannel(flutterEngine.dartExecutor,channel)22}2324privatefungetDartMethod(){25methodChannel?.invokeMethod("getName",null,object:MethodChannel.Result{26overridefunsuccess(result:Any?){27Log.i(tag,"success:"+result.toString())28Toast.makeText(this@MainActivity,result.toString(),Toast.LENGTH_LONG).show()29}3031overridefunerror(errorCode:String,errorMessage:String?,errorDetails:Any?){32Log.i(tag,"error")33}3435overridefunnotImplemented(){36Log.i(tag,"notImplemented")37}38})39}4041companionobject{42funstartMainActivity(context:Context){43valintent=Intent(context,MainActivity::class.java)44context.startActivity(intent)45}46}47}

Flutter 端如下:

1///State 2class_PageStateextendsState<PageWidget>{3MethodChannelplatform; 4 5@override 6voidinitState(){7super.initState(); 8platform=newMethodChannel('com.manu.startMainActivity'); 910//监听Android调用Flutter方法11platform.setMethodCallHandler(platformCallHandler);12}1314@override15Widgetbuild(BuildContextcontext){16returnContainer();17}18///FLutterMethod19FutureplatformCallHandler(MethodCallcall)async{20switch(call.method){21case"getName":22return"namefromflutter";23break;24}25}26}

EventChannel

EventChannel 主要用于 Flutter 到原生之间的单向调用,其使用方式类似 Android 中的广播,原生界面负责 Event 的发送,Flutter 端注册监听即可,不多说直接看代码,Android 端代码如下:

1///Android 2classMFlutterFragment:FlutterFragment(){3//这里用Fragment,Activity也一样 4overridefunconfigureFlutterEngine(flutterEngine:FlutterEngine){5super.configureFlutterEngine(flutterEngine) 6Log.d(tag,"configureFlutterEngine") 7EventChannel(flutterEngine.dartExecutor,"com.manu.event").setStreamHandler(object: 8EventChannel.StreamHandler{9overridefunonListen(arguments:Any?,events:EventChannel.EventSink?){10Log.i(tag,"configureFlutterEngine>onListen")11//EventSink发送事件通知12events?.success("eventmessage")13}1415overridefunonCancel(arguments:Any?){16Log.i(tag,"configureFlutterEngine>onCancel")17}18})19}companionobject{22funwithNewEngine():NewEngineFragmentBuilder?{23returnMNewEngineIntentBuilder(24MFlutterFragment::class.java25)26}27}2829classMNewEngineIntentBuilder(activityClass:Class<outFlutterFragment?>?):30NewEngineFragmentBuilder(activityClass!!)31}

Flutter 端如下:

1///State 2classEventStateextendsState<EventChannelPage>{3EventChannel_eventChannel; 4String_stringMessage; 5StreamSubscription_streamSubscription; 6 7@override 8voidinitState(){9super.initState();10_eventChannel=EventChannel("com.manu.event");11//监听Event事件12_streamSubscription=13_eventChannel.receiveBroadcastStream().listen((event){14setState((){15_stringMessage=event;16});17},onError:(error){18print("eventerror$error");19});20}2122@override23voiddispose(){24super.dispose();25if(_streamSubscription!=null){26_streamSubscription.cancel();27_streamSubscription=null;28}29}3031@override32Widgetbuild(BuildContextcontext){33returnScaffold(34appBar:AppBar(35title:Text("EventChannel"),36centerTitle:true,37),38body:Center(39child:Text(_stringMessage==null?"default":_stringMessage),40));41}42}

以上就是 Flutter 平台通道的使用,可以在公众号回复关键字【Channel】获取源码。

推荐阅读:HTTPS及加密算法,看这一篇就够了自定义View实现一个日期选择器

Wireshark分析验证TCP协议

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。