开发一个可以看小姐姐照片的鸿蒙应用 鸿蒙开发入门
- 效果图
- 前言
- 实现思路
- 具体实现
- 建立项目
- 建立http链接拿取图片链接
- 设置网络权限
- 设置允许http请求
- 发起http请求,并获取返回的数据
- json数据解析
- 发起请求,获得响应内容
- 将获取的图片链接放入内存中
- 获取网络图片并展示在页面上
- http请求工具类
- 字节流转图片工具类
- 图片展示在页面
- 总结
效果图
先整张效果图,丑点是丑点,但可以用,买不起鸿蒙系统手机的我,只配用虚拟机。
前言
要说目前最火的手机操作系统,要我来看的话那必然是鸿蒙无疑。16号刚刚结束了第五次鸿蒙内测,在看到这次的内测名单之后,居然有970的机器,这是不是说明俺这手里奋战了三年的荣耀play也可以生鸿蒙了,但现实是970三孤儿果然名不虚传,还是没有我们。
那么言归正传,这次突然想做一个基于鸿蒙的小demo,然后又想到了我之前爬取的小姐姐图片链接还没有用武之地,这俩是不是可以结合一下?上次有这样的想法还是上一次,那么就做一个看小姐姐的小demo吧,开整开整。
实现思路
之前在网上看到有直接把图片下载下来然后放进项目中的,这个很明显不适合我,不仅占的空间大,而且图片还得手动更新,这可不行
我们采用的是调用图片链接接口获取所有的图片链接,一个链接只是一个字符串要比图片占的空间小太多了,将这些链接存储在内存中,有兴趣的可以存在数据库里,然后每次随机获取一条链接就可以,由这条链接获取图片信息,将图片渲染到页面就可以。
整个流程简单的一塌糊涂,总结一下就是
- 拿取图片链接
- 由链接获取图片信息
- 渲染至显示页面
具体实现
建立项目
这个比较基础了,就不说了,如果不大了解的兄弟们,直接去官方文档看看就可以,建立流程非常简单。
建立http链接拿取图片链接
设置网络权限
我们需要访问网络,就必须要设置网络权限,来到config.json文件中,添加以下内容
"reqPermissions": [
{
"name": "ohos.permission.INTERNET"
},
{
"name": "com.wxr.xiaowpic.DataAbilityShellProvider.PROVIDER"
},
{
"name": "ohos.permission.GET_NETWORK_INFO"
},
{
"name": "ohos.permission.SET_NETWORK_INFO"
}
],
直接在module中添加如上内容,如下图
设置允许http请求
这里注意,重点哈,鸿蒙默认的是发起https请求,因此如果我们发起http请求是会报错的,这里需要修改一下
还是在config.json下,在deviceConfig中添加以下内容
"default": {
"network": {
"cleartextTraffic": true
}
}
如下图所示,这里吐槽一下,我再寻找怎么设置允许发起http响应的时候,发现好多文章都一样,而且都不适用于我这个项目,还有的人复制别人的文章也能复制错,绝了。
发起http请求,并获取返回的数据
json数据解析
这里要使用到alibaba的fastjson工具类,在build.gradle引入如下依赖
implementation group: 'com.alibaba', name: 'fastjson', version: '1.2.73'
如下图所示
发起请求,获得响应内容
这里使用的是大佬封装好的专门用于请求接口的一个工具,ZZRHttp,同样需要引入依赖,引入过程和上面fastjson引入过程一致。
implementation 'com.zzrv5.zzrhttp:ZZRHttp:1.0.1'
获取接口数据的具体实现如下,这里解释一下,https://2fd8e89d.cpolar.io/getAll这个接口地址,是获取图片链接的,是我本地的服务,所以大家如果需要的话,我可以把我的服务代码发给你们,包括存储图片链接的数据库。
ZZRHttp.get("https://2fd8e89d.cpolar.io/getAll", new ZZRCallBack.CallBackString() {
@Override
public void onFailure(int code, String errorMessage) {
//http访问出错,此部分在主线程中工作,可以更新UI等操做。
MyLabel.error("访问图片链接接口出错");
new ToastDialog(getContext()).setText("网络连接出问题了,请稍后重试").show();
}
@Override
public void onResponse(String response) {
//http访问成功,此部分在主线程中工作,可以更新UI等操作。
MyLabel.info("获取图片链接成功");
new ToastDialog(getContext()).setText("正在初始化,稍后").show();
//将字符串转换为json对象
JSONObject jsonObject = JSONObject.parseObject(response);
//将其中返回的图片链接转换为列表
JSONArray info = (JSONArray) jsonObject.get("info");
MyLabel.info("拿取数据量:" + info.size());
info.forEach(item -> {
srcs.add(item.toString());
});
new ToastDialog(getContext()).setText("初始化成功,开始你的快乐吧").show();
MyLabel.info("内存中数据数量" + srcs.size());
}
});
将获取的图片链接放入内存中
就是声明一个静态列表变量,目的是为了下次获取图片链接时可以直接在这里拿取图片链接
public void initData() {
PicDao picDao = new PicDaoImpl(getContext());
//使用后台线程进行初始化
TaskDispatcher refreshUITask = createParallelTaskDispatcher("", TaskPriority.DEFAULT);
refreshUITask.syncDispatch(() -> {
// List<PicSrc> list = picDao.list();
//判断内存中有无数据
if (srcs.size() == 0) {
MyLabel.info("内存中没东西,第一次打开应用");
MyLabel.info("调用图片接口获取图片链接列表");
ZZRHttp.get("https://2fd8e89d.cpolar.io/getAll", new ZZRCallBack.CallBackString() {
@Override
public void onFailure(int code, String errorMessage) {
//http访问出错,此部分在主线程中工作,可以更新UI等操做。
MyLabel.error("访问图片链接接口出错");
new ToastDialog(getContext()).setText("网络连接出问题了,请稍后重试").show();
}
@Override
public void onResponse(String response) {
//http访问成功,此部分在主线程中工作,可以更新UI等操作。
MyLabel.info("获取图片链接成功");
new ToastDialog(getContext()).setText("正在初始化,稍后").show();
JSONObject jsonObject = JSONObject.parseObject(response);
JSONArray info = (JSONArray) jsonObject.get("info");
MyLabel.info("拿取数据量:" + info.size());
info.forEach(item -> {
srcs.add(item.toString());
});
new ToastDialog(getContext()).setText("初始化成功,开始你的快乐吧").show();
MyLabel.info("内存中数据数量" + srcs.size());
}
});
} else {
MyLabel.info("已经有内容了");
}
});
}
获取网络图片并展示在页面上
http请求工具类
这个类的主要作用就是发起http请求,并返回响应字节流,其实就是获取图片的字节流,代码如下
package com.wxr.xiaowpic.util;
import com.wxr.xiaowpic.label.MyLabel;
import com.zzrv5.mylibrary.ZZRCallBack;
import com.zzrv5.mylibrary.ZZRHttp;
import ohos.hiviewdfx.HiLog;
import ohos.utils.net.Uri;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class HttpUtils {
//url就是要访问的网络资源,methodType就是请求方式
public static InputStream getInput(String url,String methodType){
InputStream inputStream = null;
try {
URL url1=new URL(url);
HttpURLConnection urlConnection = (HttpURLConnection) url1.openConnection();
urlConnection.setRequestMethod(methodType);
urlConnection.connect();
int rescode=urlConnection.getResponseCode();
if(rescode==HttpURLConnection.HTTP_OK){
inputStream=urlConnection.getInputStream();
}
} catch (Exception e) {
HiLog.error(MyLabel.LABEL_LOG,e.getMessage());
HiLog.error(MyLabel.LABEL_LOG,e.getCause().toString());
}
return inputStream;
}
}
字节流转图片工具类
没啥好说的,复制就可以用
package com.wxr.xiaowpic.util;
import com.wxr.xiaowpic.label.MyLabel;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import java.io.InputStream;
public class ImageUtils {
private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "XiaoW");
public static PixelMap createPixelMap(String imageUrl) {
//获取图片字节流信息
InputStream inputStream = HttpUtils.getInput(imageUrl,"GET");
PixelMap pixelMap=null;
ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
sourceOptions.formatHint = "image/jpeg";
HiLog.info(MyLabel.LABEL_LOG,(inputStream==null)+"");
try {
ImageSource imageSource = ImageSource.create(inputStream,sourceOptions);
pixelMap = imageSource.createPixelmap(null);
}
catch (Exception e){
HiLog.info(LABEL_LOG,e.getMessage());
}
return pixelMap;
}
}
图片展示在页面
这里采用的是按钮点击之后进行图片的渲染,其中图片链接是在我们获取的图片链接随机读取一个,然后将该照片渲染至页面
button.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
TaskDispatcher refreshUITask = createParallelTaskDispatcher("", TaskPriority.DEFAULT);
refreshUITask.syncDispatch(() -> {
//在链接列表中随机取一个数据
int index = (int) (Math.random() * srcs.size());
MyLabel.info(srcs.get(index));
String url=srcs.get(index);
MyLabel.info("开始获取图片");
//访问线上图片
PixelMap pixelMap = ImageUtils.createPixelMap(url);
getContext().getUITaskDispatcher().asyncDispatch(new Runnable() {
@Override
public void run() {
//Image组件填充位图数据,ui界面更新
image.setPixelMap(pixelMap);
pixelMap.release();
}
});
});
}
});
总结
之前没有自己做过移动端的demo,总之收获还是不少的,所以期间出了不少问题,需要全部代码的兄弟们私信就好。