HttpUtils 从 v2.3.0 之后便重命名了,因为它已不单单是几个工具类,而是一套具有丰富功能的轻量网络开发包。更像是 OkHttp 的加强版,所以它的名字是 OkHttps。
项目地址 Gitee: gitee.com/ejlchina-zh…
GitHub: github.com/ejlchina/ok…
<dependency> <groupId>com.ejlchina</groupId> <artifactId>okhttps</artifactId> <version>1.0.4</version> </dependency> 复制代码
implementation 'com.ejlchina:okhttps:1.0.4' 复制代码
安卓中使用需要把 JDK 版本调成 1.8,在 app 模块的 build.gradle 中加入以下配置即可:
android { // 省略其它配置.. compileOptions { sourceCompatibility = 1.8 targetCompatibility = 1.8 } } 复制代码
在正式开始之前,我们依然假设,下文中出现 http
均是在构建时设置了 BaseUrl
的 HTTP
实例(详细请看前文):
HTTP http = HTTP.builder() .baseUrl("http://api.demo.com") .build(); 复制代码
OK,一切就绪,我们接着上篇文章继续讲。
在 Android 开发中,经常会把某些代码放到特点的线程去执行,比如网络请求响应后的页面更新在主线程(UI线程)执行,而保存文件则在IO线程操作。OkHttps 为这类问题提供了良好的方案。
在 默认 情况下, 所有回调 函数都会 在 IO 线程 执行。为什么会设计如此呢?这是因为 OkHttps 只是纯粹的 Java 领域 Http工具包,本身对 Android 不会有任何依赖,因此也不知 Android 的 UI 线程为何物。这么设计也让它在 Android 之外有更多的可能性。
但是在 Android 里使用 OkHttps 的话,UI线程的问题能否优雅的解决呢?当然可以!简单粗暴的方法就是配置一个 回调执行器:
HTTP http = HTTP.builder() .callbackExecutor((Runnable run) -> { // 实际编码中可以吧 Handler 提出来,不需要每次执行回调都重新创建 new Handler(Looper.getMainLooper()).post(run); // 在主线程执行 }) .build(); 复制代码
上述代码便实现了让 所有 的 回调函数 都在 主线程(UI线程) 执行的目的,如:
http.async("/users") .addBodyParam("name", "Jack") .setOnProcess((Process process) -> { // 在主线程执行 }) .setOnResponse((HttpResult result) -> { // 在主线程执行 }) .setOnException((Exception e) -> { // 在主线程执行 }) .setOnComplete((State state) -> { // 在主线程执行 }) .post(); 复制代码
但是,如果同时还想让某些回调放在IO线程,实现 自由切换 ,怎么办呢?OkHttps 给出了非常灵活的方法,如下:
http.async("/users") .addBodyParam("name", "Jack") .setOnProcess((Process process) -> { // 在主线程执行 }) .nextOnIO() // 指定下一个回调在 IO 线程执行 .setOnResponse((HttpResult result) -> { // 在 IO 线程执行 }) .setOnException((Exception e) -> { // 在主线程执行(没有指明 nextOnIO 则在回调执行器里执行) }) .nextOnIO() // 指定下一个回调在 IO 线程执行 .setOnComplete((State state) -> { // 在 IO 线程执行 }) .post(); 复制代码
无论是哪一个回调,都可以使用 nextOnIO()
方法自由切换。同样,对于文件下载也是一样:
http.sync("/download/test.zip") .get() .getBody() .setOnProcess((Process process) -> { // 在主线程执行 }) .toFolder("D:/download/") .nextOnIO() // 指定下一个回调在 IO 线程执行 .setOnSuccess((File file) -> { // 在 IO 线程执行 }) .setOnFailure((Failure failure) -> { // 在主线程执行 }) .start(); 复制代码
怎么样,是不是很简单呢?
如果觉得可以,就到这里点个小星星吧:
Gitee: gitee.com/ejlchina-zh…
GitHub: github.com/ejlchina/ok…
前篇文章: OkHttp 优雅封装 HttpUtils 之 上传下载解密
下篇文章:OkHttp 优雅封装 OkHttps 之 现生命周期绑定,敬请期待!