鸿蒙开发实战系列之三:网络请求(原生+ Retrofit)
鸿蒙开发实战系列之一:鸿蒙开发实战系列之一:圆角
鸿蒙开发实战系列之二:鸿蒙开发实战系列之二:事件总线EventBus/RxBus
前言
过了一个漫长的中秋+国庆假期,大家伙的鸿蒙内功修炼的怎么样了?难道像小蒙一样,都在吃吃喝喝中度过么,哎,罪过罪过,对不起那些鸡鸭鱼肉啊,赶紧回来写篇文章收收心,让我们一起看看,在鸿蒙中如何发送网络请求吧。
本文会从Java原生访问入手,进而再使用Retrofit访问网络,可以满足绝大部分开发者对于鸿蒙网络访问方面的代码需求,开始之前需要先做一下基础配置。
鸿蒙系统网络访问基础配置
1、跟Android类似,要访问网络,我们首先要配置网络访问权限,在config.json的"module"节点最后,添加上网络权限代码
"reqPermissions": [{"reason": "","name": "ohos.permission.INTERNET"}]
2、配置网络明文访问白名单
"deviceConfig": {"default": {"network": {"usesCleartext": true,"securityConfig": {"domainSettings": {"cleartextPermitted": true,"domains": [{"subDomains": true,"name": "www.baidu.com"}]}}}}}
其中的name即为可以直接http访问的域名,如果全是https链接则可以做该不配置,切记域名是不带http://的,切记域名是不带http://的,切记域名是不带http://的,重要的事说三遍。
Java原生访问网络
由于鸿蒙系统支持Java开发,所以我们可以直接使用Java原生的Api来进行网络访问
该方式使用了java的url.openConnection() Api来获取网络数据
HttpDemo.java
package com.example.demo.classone;import javax.net.ssl.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;public class HttpDemo {/***访问url,获取内容* @param urlStr* @return*/public static String httpGet(String urlStr){StringBuilder sb = new StringBuilder();try{//添加https信任SSLContext sslcontext = SSLContext.getInstance("SSL");//第一个参数为协议,第二个参数为提供者(可以缺省)TrustManager[] tm = {new HttpX509TrustManager()};sslcontext.init(null, tm, new SecureRandom());HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {public boolean verify(String s, SSLSession sslsession) {System.out.println("WARNING: Hostname is not matched for cert.");return true;}};HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());URL url = new URL(urlStr);HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");connection.setReadTimeout(10000);connection.setConnectTimeout(10000);connection.connect();int code = connection.getResponseCode();if (code == HttpURLConnection.HTTP_OK) {BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));String temp;while ((temp = reader.readLine()) != null) {sb.append(temp);}reader.close();}connection.disconnect();} catch (Exception e) {e.printStackTrace();return e.getMessage();}return sb.toString();}
}
HttpX509TrustManager.java
package com.example.demo.classone;
import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;public class HttpX509TrustManager implements X509TrustManager {@Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}@Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return null;}
}
最后是测试是否能够正确访问的代码,注意网络访问是耗时操作要放线程里面执行
new Thread(new Runnable() {@Overridepublic void run() {String result = HttpDemo.httpGet("http://www.baidu.com");HiLog.warn(new HiLogLabel(HiLog.LOG_APP, 0, "===demo==="), "网页返回结果:"+result);}}).start();
采用Retrofit访问网络
在模块的build.gradle里添加Retrofit库的引用,我这边采用的是retrofit2的2.5.0版本做示例
implementation 'com.squareup.retrofit2:retrofit:2.5.0'implementation 'com.squareup.retrofit2:converter-gson:2.5.0'implementation 'io.reactivex.rxjava3:rxjava:3.0.4'
新建ApiManager类用来管理获取OkHttpClient,SSLSocketClient用来提供https支持,ApiResponseConverterFactory是Retrofit的转换器,将请求结果转成String输出
ApiManager.java
package com.example.demo.classone;import com.example.demo.DemoAbilityPackage;
import ohos.app.Environment;
import okhttp3.*;
import retrofit2.Retrofit;import java.io.File;
import java.util.concurrent.TimeUnit;/*** 提供获取Retrofit对象的方法*/
public class ApiManager {private static final String BUSINESS_BASE_HTTP_URL = "http://www.baidu.com";private static Retrofit instance;private static OkHttpClient mOkHttpClient;private ApiManager(){}public static Retrofit get(){if (instance == null){synchronized (ApiManager.class){if (instance == null){setClient();instance = new Retrofit.Builder().baseUrl(BUSINESS_BASE_HTTP_URL).addConverterFactory(ApiResponseConverterFactory.create()).client(mOkHttpClient).build();}}}return instance;}private static void setClient(){if (mOkHttpClient != null){return;}Cache cache = new Cache(new File(getRootPath(Environment.DIRECTORY_DOCUMENTS),"HttpCache"),1024*1024*100);OkHttpClient.Builder builder = new OkHttpClient.Builder()
// .followRedirects(false)//关闭重定向
// .addInterceptor(new AppendUrlParamIntercepter()).cache(cache).retryOnConnectionFailure(false).sslSocketFactory(SSLSocketClient.getSSLSocketFactory()).hostnameVerifier(SSLSocketClient.getHostnameVerifier()).readTimeout(8,TimeUnit.SECONDS).writeTimeout(8,TimeUnit.SECONDS).connectTimeout(8, TimeUnit.SECONDS);
// .protocols(Collections.singletonList(Protocol.HTTP_1_1));mOkHttpClient = builder.build();mOkHttpClient.dispatcher().setMaxRequests(100);}private static String getRootPath(String dirs) {String path = DemoAbilityPackage.getInstance().getCacheDir() + "/" + dirs;File file = new File(path);if (!file.exists()) {file.mkdirs();}return path;}
}
SSLSocketClient.java
package com.example.demo.classone;
import javax.net.ssl.*;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;public class SSLSocketClient {//获取这个SSLSocketFactorypublic static SSLSocketFactory getSSLSocketFactory() {try {SSLContext sslContext = SSLContext.getInstance("SSL");sslContext.init(null, getTrustManager(), new SecureRandom());return sslContext.getSocketFactory();} catch (Exception e) {throw new RuntimeException(e);}}//获取TrustManagerprivate static TrustManager[] getTrustManager() {TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {@Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) {}@Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[]{};}}};return trustAllCerts;}//获取HostnameVerifierpublic static HostnameVerifier getHostnameVerifier() {HostnameVerifier hostnameVerifier = new HostnameVerifier() {@Overridepublic boolean verify(String s, SSLSession sslSession) {return true;}};return hostnameVerifier;}
}
ApiResponseConverterFactory.java
package com.example.demo.classone;import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;/*** BaseResponse的转换器*/
public class ApiResponseConverterFactory extends Converter.Factory {public static Converter.Factory create(){return new ApiResponseConverterFactory();}@Overridepublic Converter<ResponseBody, String> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {return new StringResponseBodyConverter();}@Overridepublic Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {return null;}class StringResponseBodyConverter implements Converter<ResponseBody, String> {@Overridepublic String convert(ResponseBody value) throws IOException {String s = value.string();return s;}}
}
开始使用Retrofit书写业务逻辑
BusinessApiManager.java
package com.example.demo.classone;/*** 服务端访问接口管理*/
public class BusinessApiManager {private static BusinessApiService instance;public static BusinessApiService get(){if (instance == null){synchronized (BusinessApiManager.class){if (instance == null){instance = ApiManager.get().create(BusinessApiService.class);}}}return instance;}
}
BusinessApiService.java
package com.example.demo.classone;import retrofit2.Call;
import retrofit2.http.*;/*** 服务端访问接口*/
public interface BusinessApiService {/*** 获取网页信息* @param url* @return*/@GET()Call<String> getHtmlContent(@Url String url);
}
测试Retrofit是否能够正常使用
BusinessApiManager.get().getHtmlContent("https://www.baidu.com").enqueue(new Callback<String>() {@Overridepublic void onResponse(Call<String> call, Response<String> response) {if (!response.isSuccessful() || response.body() == null){onFailure(null,null);return;}String result = response.body();HiLog.warn(new HiLogLabel(HiLog.LOG_APP, 0, "===demo==="), "网页返回结果:"+result);}@Overridepublic void onFailure(Call<String> call, Throwable throwable) {HiLog.warn(new HiLogLabel(HiLog.LOG_APP, 0, "===demo==="), "网页访问异常");}
});
总结
鸿蒙是基于Java开发的,所有Java原生api都是可以直接在鸿蒙系统上使用的,另外只要和java相关的库都是可以直接引用的,例如在引用retrofit的时候也带入了RxJava。
更多retrofit的使用方式,可以参考retrofit在android系统中的实现,鸿蒙系统基本兼容。
所有相关代码已上传至github:https://github.com/maolinnan/HarmonyosClass
这是本系列的第三篇,后面还会为大家带来更多的鸿蒙干货,敬请期待…。
如果文章对您有一点启发的话,希望您能点个赞。
鸿蒙开发实战系列之三:网络请求(原生+ Retrofit)相关推荐
- 鸿蒙开发实战系列之五:鸿蒙系统原生数据库
鸿蒙开发实战系列之一:鸿蒙开发实战系列之一:圆角 鸿蒙开发实战系列之二:鸿蒙开发实战系列之二:事件总线EventBus/RxBus 鸿蒙开发实战系列之三:鸿蒙开发实战系列之三:网络请求(原生+ Ret ...
- 鸿蒙开发-使用fetch发起网络请求
场景 鸿蒙基于JS搭建HelloWorld并修改国际化文件: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/118274050 在 ...
- AI应用开发实战系列之三:手写识别应用入门
AI应用开发实战 - 手写识别应用入门 手写体识别的应用已经非常流行了,如输入法,图片中的文字识别等.但对于大多数开发人员来说,如何实现这样的一个应用,还是会感觉无从下手.本文从简单的MNIST训练出 ...
- 鸿蒙系统开发者如何加入,鸿蒙开发实战系列之五:鸿蒙系统原生数据库
前言 上文介绍了ObjectBox,属于神器,但是作为一个合格的码农,上的了厅堂,下得了猪圈,神器好用,菜刀也是要会使的嘛,这篇我们就来介绍下鸿蒙系统的数据库如何使用 鸿蒙的关系型数据库是基于SQLi ...
- 微信小程序|开发实战篇之三
开发实战篇之三 前言 1.使用Promise获取多个异步方法的结果 2.高阶组件-search 2.1 search组件的基本结构 2.1.1 search组件的骨架index.wxml文件 2.1. ...
- springboot 插入返回id_Spring Boot实现分布式微服务开发实战系列(七)
今天已经进入第七讲了,整个微服务架构的搭建工作也基本完成.那到目前为止究竟使用了那些技术及实现了什么功能呢?我们先回顾一下. 使用的技术:SpringBoot.Dubbo.Zookeeper.Redi ...
- [Map 3D开发实战系列] Map Resource Explorer 之四-- Map3D开发中的WPF
目录 [Map 3D开发实战系列] Map Resource Explorer 背景介绍--Kick off [Map 3D开发实战系列] Map Resource Explorer 之二-- 运行和 ...
- springboot 事务统一配置_Spring Boot实现分布式微服务开发实战系列(五)
最近已经推出了好几篇SpringBoot+Dubbo+Redis+Kafka实现电商的文章,今天再次回到分布式微服务项目中来,在开始写今天的系列五文章之前,我先回顾下前面的内容. 系列(一):主要说了 ...
- 微信小程序|开发实战篇之request请求(单个、多个参数,json对象,header)
开发实战篇之request请求 前言 1.发送单个.多个参数的request 2.发送JSON对象的request 3.发送header的request 前言 小程序发送网络请求常会遇到的问题: 请求 ...
最新文章
- robot简单功能测试脚本设计(例子)
- 【Qt】在ubuntu上打包发布Qt程序,可以不依赖Qt环境
- linux系统层次(转)
- ChoiceFormat:数字范围格式
- mybatis不等于某个字符串的值_MyBatis 的 4 个妙用,别再踩坑了!
- POJ 1154题解,此题不难理解方法就是DFS,属于水题。不过有一些细节要注意。...
- 《Ray Tracing from the Ground Up》中的坐标系是怎么确定的
- poj2485(Kruskal)
- html5回到顶部代码,JS返回顶部实例代码
- MATLAB 时间序列预测算法(有代码)
- 移动开发中的基础知识总结
- word页码不连续怎么办
- Numpy中矩阵向量乘法np.dot()及np.multiply()以及*区别
- 杯具”箴言成网络流行语
- 在Termux中安装Kali教程
- oracle escape关键字用法
- CSS3过渡:在2个不同的渐变色之间进行动画处理
- 利用U盘PE系统修复win7系统的启动引导文件
- Heart Disease UCI(心脏病相关数据集)
- 马云:我们唯一拥有的就是相信梦想,Never give up!