鸿蒙开发实战系列之一:鸿蒙开发实战系列之一:圆角

鸿蒙开发实战系列之二:鸿蒙开发实战系列之二:事件总线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)相关推荐

  1. 鸿蒙开发实战系列之五:鸿蒙系统原生数据库

    鸿蒙开发实战系列之一:鸿蒙开发实战系列之一:圆角 鸿蒙开发实战系列之二:鸿蒙开发实战系列之二:事件总线EventBus/RxBus 鸿蒙开发实战系列之三:鸿蒙开发实战系列之三:网络请求(原生+ Ret ...

  2. 鸿蒙开发-使用fetch发起网络请求

    场景 鸿蒙基于JS搭建HelloWorld并修改国际化文件: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/118274050 在 ...

  3. AI应用开发实战系列之三:手写识别应用入门

    AI应用开发实战 - 手写识别应用入门 手写体识别的应用已经非常流行了,如输入法,图片中的文字识别等.但对于大多数开发人员来说,如何实现这样的一个应用,还是会感觉无从下手.本文从简单的MNIST训练出 ...

  4. 鸿蒙系统开发者如何加入,鸿蒙开发实战系列之五:鸿蒙系统原生数据库

    前言 上文介绍了ObjectBox,属于神器,但是作为一个合格的码农,上的了厅堂,下得了猪圈,神器好用,菜刀也是要会使的嘛,这篇我们就来介绍下鸿蒙系统的数据库如何使用 鸿蒙的关系型数据库是基于SQLi ...

  5. 微信小程序|开发实战篇之三

    开发实战篇之三 前言 1.使用Promise获取多个异步方法的结果 2.高阶组件-search 2.1 search组件的基本结构 2.1.1 search组件的骨架index.wxml文件 2.1. ...

  6. springboot 插入返回id_Spring Boot实现分布式微服务开发实战系列(七)

    今天已经进入第七讲了,整个微服务架构的搭建工作也基本完成.那到目前为止究竟使用了那些技术及实现了什么功能呢?我们先回顾一下. 使用的技术:SpringBoot.Dubbo.Zookeeper.Redi ...

  7. [Map 3D开发实战系列] Map Resource Explorer 之四-- Map3D开发中的WPF

    目录 [Map 3D开发实战系列] Map Resource Explorer 背景介绍--Kick off [Map 3D开发实战系列] Map Resource Explorer 之二-- 运行和 ...

  8. springboot 事务统一配置_Spring Boot实现分布式微服务开发实战系列(五)

    最近已经推出了好几篇SpringBoot+Dubbo+Redis+Kafka实现电商的文章,今天再次回到分布式微服务项目中来,在开始写今天的系列五文章之前,我先回顾下前面的内容. 系列(一):主要说了 ...

  9. 微信小程序|开发实战篇之request请求(单个、多个参数,json对象,header)

    开发实战篇之request请求 前言 1.发送单个.多个参数的request 2.发送JSON对象的request 3.发送header的request 前言 小程序发送网络请求常会遇到的问题: 请求 ...

最新文章

  1. robot简单功能测试脚本设计(例子)
  2. 【Qt】在ubuntu上打包发布Qt程序,可以不依赖Qt环境
  3. linux系统层次(转)
  4. ChoiceFormat:数字范围格式
  5. mybatis不等于某个字符串的值_MyBatis 的 4 个妙用,别再踩坑了!
  6. POJ 1154题解,此题不难理解方法就是DFS,属于水题。不过有一些细节要注意。...
  7. 《Ray Tracing from the Ground Up》中的坐标系是怎么确定的
  8. poj2485(Kruskal)
  9. html5回到顶部代码,JS返回顶部实例代码
  10. MATLAB 时间序列预测算法(有代码)
  11. 移动开发中的基础知识总结
  12. word页码不连续怎么办
  13. Numpy中矩阵向量乘法np.dot()及np.multiply()以及*区别
  14. 杯具”箴言成网络流行语
  15. 在Termux中安装Kali教程
  16. oracle escape关键字用法
  17. CSS3过渡:在2个不同的渐变色之间进行动画处理
  18. 利用U盘PE系统修复win7系统的启动引导文件
  19. Heart Disease UCI(心脏病相关数据集)
  20. 马云:我们唯一拥有的就是相信梦想,Never give up!

热门文章

  1. 2015年智能家居大事记 合纵连横成主旋律
  2. kotlin Anko的实际用法
  3. spring boot 使用javaMailSender 发送qq邮箱验证码
  4. FPGA通过PCIe读写DDR4仿真IP核
  5. 分享、活动、地推、广告:openinstall全渠道多场景解决方案
  6. win10笔记本相机打开黑屏无法打开笔记本相机
  7. 哇哦,它让美味随心所“鲜”
  8. PAT难题精选题汇总,代码保存下来以供自己学习
  9. a链接实现alt提示
  10. faker.js生成手机号