十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
为什么我们要选择flutter语言呢?它有哪些优点呢?
为襄汾等地区用户提供了全套网页设计制作服务,及襄汾网站建设行业解决方案。主营业务为网站制作、网站设计、襄汾网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
*1.flutter将会帮你更容易,更快速的开发出界面美观的移动应用。
*2.是谷歌的亲儿子
*3.支持热重载 :android原生开发会遇到编译-打包-安装三个步骤。开发效率迟迟得不到提升。热重载技术在flutter内完美体现。
*4.支持垮平台:flutter基于图像回执引擎进行渲染,在不同平台下绘制效果绝对是一致的,能做到真正的跨平台,一处写,处处运行。
*5.性能优异性:不同于H5通过DOM渲染和RN映射组件,flutter直接基于native进行绘制。性能上完全超过原生。
*1.Dart语法编译:Dart是一种强类型、跨平台的客户端开发语言。具有专门为客户端优化、高生产力、快速高效、可移植易学的风格。Dart主要由谷歌负责开发和维护。
*2.Flutter插件:Flutter使用的Dart语言无法直接调用iOS系统提供的OC或swift接口,这时就需要使用插件来实现中转。Flutter官方提供了丰富的原生接口封装
Flutter分为三大部分
*1.由Dart语言负责的Framwork层。
*2.Dart语法执行器。
*3.Skia图像处理引擎。05年就被研发成功了(谷歌的全家桶都是由谷歌的Skia图像处理引擎绘制的,iOS目前的图像处理引擎是JPEG,其中Skia是对JPEG的二次封装。)
*1.2005年Skia图像处理引擎成立,用来展示Chrome,火狐和其他谷歌自己的产品使用。
*2.2007年第一个安卓系统问世,于是谷歌开发者将Skia移植到安卓平台。
*3.Skia作为一个2D的图像系统,包含绘制,渲染,显示图片都是Skia完成。安卓中的3D部分是由OpenGLES来实现的,其中OpenGL ES是OpenGL的嵌入式版本。
BinaryMessenger是Platform端与Flutter端通信的工具,其通信使用的消息格式为二进制格式数据。当我们初始化一个Channel,并向该Channel注册处理消息的Handler时,实际上会生成一个与之对应的BinaryMessageHandler,并以channel name为key,注册到BinaryMessenger中。当Flutter端发送消息到BinaryMessenger时,BinaryMessenger会根据其入参channel找到对应的BinaryMessageHandler,并交由其处理。
Binarymessenger在Android端是一个接口,其具体实现为FlutterNativeView。而其在iOS端是一个协议,名称为FlutterBinaryMessenger,FlutterViewController遵循了它。
参考闲鱼技术出品
深入理解Flutter Platform Channel
在Native侧,创建一个methodChannel通道,用于调用flutter侧方法,或者flutter侧调用Native侧方法,并提供callback。
iOS侧:
关键词:
channelName:channel唯一标识,Native侧和flutter侧保持名称一致。
binaryMessenger:channel Context。
handle: typedef void (^FlutterMethodCallHandler)(FlutterMethodCall* call, FlutterResult result);
FlutterMethodCall:包含 method (方法名)和 arguments (参数)的对象,管理方法对象
FlutterResult: typedef void (^FlutterResult)(id _Nullable result);
Android侧:
关键词:
binaryMessenger:传入flutter Context,及FlutterNativeView。
flutter侧:
关键词:
Future、async:异步操作套装
Future-官方文档
setState:触发重绘当前节点,以更新UI。
一、接入方式:
具体可参考: 官方文档
二、使用 官方文档 :
Dart:
注意点:
在很多场景下,Flutter 页面跳转Flutter 页面,这个时候可以不需要再打开容器。不打开容器,能节省内存开销。 在FlutterBoost3.0上,打开容器和不打开容器的区别表现在用户接口上仅仅是withContainer参数是否为true就好
如项目中跳转预约检测时,若withContainer:false
注意:如果打开的Flutter页面不带容器(例如,通过原生的Navigator.push,或者withContainer=false),那么pop时,result可以是任何类型;如果打开的页面是一个带容器的Flutter页面(即,withContainer=true)或一个Native页面,那么result需要是MapString, dynamic类型。
三、iOS:
1.开启新页面:
2.原生参数回传flutter
四、坑点:
flutter在与原生交互时,容易出现flutter页面被释放的情况,这时,需要重新将flutter页面加到栈中
项目中出现的地方:
弹出系统弹框时;
由flutter页面的tab切换到原生页面tab时;
Flutter Dio源码分析(一)--Dio介绍
Flutter Dio源码分析(二)--HttpClient、Http、Dio对比
Flutter Dio源码分析(三)--深度剖析
Flutter Dio源码分析(四)--封装
Flutter Dio源码分析(一)--Dio介绍视频教程
Flutter Dio源码分析(二)--HttpClient、Http、Dio对比视频教程
Flutter Dio源码分析(三)--深度剖析视频教程
Flutter Dio源码分析(四)--封装视频教程
github仓库地址
本文会手把手教你该怎么去封装一个类库,平时在我们的工作中都是拿着别人的造好的轮子在使用,这篇文章将带你怎么去自己造轮子,以后再碰到别的类库需要对其进行封装的时候提供一个的思路和方法。
在前面的文章中,我们对 Dio 的基本使用、请求库对比、源码分析,我们知道 Dio 的使用非常的简单,那为什么还需要进行封装呢?有两点如下:
当组件库方法发生重要改变需要迁移的时候如果有多处地方用到,那么需要对使用到的每个文件都进行修改,非常的繁琐而且很容易出问题。
当不需要 Dio 库的时候,我们可以随时方便切换到别的网络请求库,当然 Dio 目前内置支持使用第三方库的适配器。
因为一个应用程序基本都是统一的配置方式,所以我们可以针对 拦截器 、 转换器 、 缓存 、 统一处理错误 、 代理配置 、 证书校验 等多个配置进行统一管理。
因为我们的应用程序在每个页面中都会用到网络请求,那么如果我们每次请求的时候都去实例化一个 Dio ,无非是增加了系统不必要的开销,而使用单例模式对象一旦创建每次访问都是同一个对象,不需要再次实例化该类的对象。
这是通过静态变量的私有构造器来创建的单例模式
我们对 超时时间 、 响应时间 、 BaseUrl 进行统一设置
因为不管是 get() 还是 post() 请求, Dio 内部最终都会调用 request 方法,只是传入的 method 不一样,所以我们这里定义一个枚举类型在一个方法中进行处理
我们已经把 Restful API 风格简化成了一个方法,通过 DioMethod 来标明不同的请求方式。在我们平时开发的过程中,需要在请求前、响应前、错误时对某一些接口做特殊的处理,那我们就需要用到拦截器。 Dio 为我们提供了自定义拦截器功能,很容易轻松的实现对请求、响应、错误时进行拦截
我们发现虽然 Dio 框架已经封装了一个 DioError 类库,但如果需要对返回的错误进行统一弹窗处理或者路由跳转等就只能自定义了
在我们发送请求的时候会碰到几种情况,比如需要对非open开头的接口自动加上一些特定的参数,获取需要在请求头增加统一的 token
在我们请求接口前可以对响应数据进行一些基础的处理,比如对响应的结果进行自定义封装,还可以针对单独的 url 做特殊处理等。
我们看了转换器的介绍,发现和拦截器的功能差不多,那为什么还要存在转换器,有两点:
执行流程: 请求拦截器 请求转换器 发起请求 响应转换器 响应拦截器 最终结果 。
只会被用于 'PUT'、 'POST'、 'PATCH'方法,因为只有这些方法才可以携带请求体(request body)
会被用于所有请求方法的返回数据。
在开发过程中,客户端和服务器打交道的时候,往往会用一个 token 来做校验,因为每个公司处理刷新token的逻辑都不一样,我这里举一个简单的例子
为什么我们需要有取消请求的功能,如果当我们的页面在发送请求时,用户主动退出当前界面或者app应用程序退出的时候数据还没有响应,那我们就需要取消该网络请求,防止不必要的错误。
由 服务器生成 的 一小段文本信息 ,发送给浏览器,浏览器把 cookie 以kv形式保存到本地 某个目录下的文本文件内,下一次请求同一网站时会把该 cookie 发送给服务器。
cookie 的使用需要用到两个第三方组件 dio_cookie_manager 和 cookie_jar
因为在我们平时的开发过程中,会碰到一种情况,在进行网络请求时,我们希望能正常访问到上次的数据,对于用户的体验比较好,而不是展示一个空白的页面,该缓存主要是 《Flutter实战》网络接口缓存 提供参考。
我们在程序退出后内存缓存将会消失,所以我们用 shared_preferences 进行磁盘缓存数据。
在我们用flutter进行抓包的时候需要配置 Dio 代理。由 DefaultHttpClientAdapter 提供了一个 onHttpClientCreate 回调来设置底层 HttpClient 的代理。
用于验证正在访问的网站是否真实。提供安全性,因为证书和域名绑定,并且由根证书机构签名确认。
日志打印主要是帮助我们开发时进行辅助排错
flutter与原生通信主要有三种方式:MethodChannel、EventChannel、BasicMessageChannel,这三种方式均各有适用的场景:MethodChannel用于native与flutter的方法调用,EventChannel用于native单向的向flutter发送广播消息,BasicMessageChannel用于native与flutter之间的消息互发。
MethodChannel用于双方之间的方法互调,使用步骤是:
1.创建一个MethodChannel对象,传入MethodChannel名称。
2.使用setMethodHandle对对方调用自己的方法进行监听,通过回调中的MethodCall对象方法名判断、获取方法参数,并且返回调用结果。
3.使用invokeMethod来调用对方的方法,可传入方法名,方法参数,以及监听对方的回调结果。
以下是示例:
需要注意的是,MethodChannel的名称需要双方保持一致,否则就不是同一个MethodChannel了。另外这里的方法调用并不是像Java里面反射那样去先找到class示例对象再解析到相应的方法,而是将双方互发的消息包装成了MethodCall对象,拿到这个对象后通过MethodCall里面的方法名去判断要做什么操作,并不是直接就调用了自身(native或flutter)相对应的方法。具体要做什么操作、调用什么方法还是得自己去调用和实现。
EventChannel适用于native向flutter发送广播消息,只是单向的消息发送,native发,flutter收,返过来flutter并不能向native发送消息。例如native可将定位数据不断的报给flutter,或者录像数据等等,所有基于原生能力产生的数据都可以通过EventChannel进行发送。
步骤:
1.创建一个EventChannel对象,传入EventChannel名称。
2.flutter端调用receiveBroadcastStream进行广播消息注册,传入arguments参数即为广播名称,此参数是告诉native端你要接受的广播类型,判别是什么广播发送的数据。
2.native调用setStreamHandler方法进行广播消息监听,onListen回调里会有一个arguments参数,这里及为flutter注册的广播类型,若flutter端没有注册,则native端不会收到这个回调,也就无法进行消息发送。收到flutter端的广播注册后,根据arguments可判断广播类型,然后根据EventChannel.EventSink来进行消息发送,EventSink.success()即可将消息发送给flutter端。
3.flutter进行广播注册会返回一个streamSubscription类型的对象,该对象可以进行消息的停止,native可在onCancel回调里面收到。
示例如下:
BasicMessageChannel就是比较常用的消息互发,使用步骤如下:
1.创建BasicMessageChannel对象,传入BasicMessageChannel名称。还需传入编解码方式(可以自己实现),系统提供了一些列的编解码方式,后续会介绍到。
2.使用setMessageHandler方法进行消息监听,也可进行回复。
3.使用send方法进行消息发送。
无论哪种方式的消息传递,最终都是将自定义数据转化为二进制数据进行传递,flutter提供的编解码方式分为MethodCodec和MessageCodec两种,EventChannel和MethodChannel使用的就是MethodCodec,BasicMessageChannel使用的是MessageCodec。MethodCodec其实就是在MessageCodec的基础上将数据包装了一下,使其转化为MethodCall对象方便使用。
MethodCodec源码:
MethodCodec提供了两种方式:JSONMethodCodec和StandardMethodCodec,前一种就是JSON和MethodCall对象之间的互转,后一种则是根据传入的数据基本类型(String,Integer等)来进行互转。
MessageCodec则提供了四种方式,如下图,具体就不详细讲述了,看看名字就知道是怎么回事,可以直接去看源码。最常用和默认的就是StandardMessageCodec方式。
从上面的使用方式可以看出,每一种Channel在创建的时候都需要传递一个BinaryMessenger,这个接口可以在FlutterEngine里面拿到,因此需要在FlutterActivity里面实现configFlutterEngine方法里面重写这个方法。FlutterActivity在attach FlutterEngine之后就会调用这个configFlutterEngine方法,通过flutterEngine.getPlugins().add(FlutterPlugin)方法可以FlutterPlugin的回调方法里进行数据的初始化和销毁工作。如下图
这个回调方法里的FlutterPluginBinding提供了一些我们可能会用到的对象,如下: