前文已经介绍了ListView和RecyclerView等各种列表控件,在实际的开发中,会经常遇到大批量的数据加载和展示的问题,本节课来具体的学习一下常见的方式和步骤。
一、json解析
移动端和服务器交互一般用得较多的数据传递方式都是 Json 字符串的形式, 保存对象,我们也可以写成一个 Json 字符串然后存储。
常见的解析 Json的方式有Android自带Json解析器, Gson,Fastjson,jackson 等。
1.0Json.cn工具
通过一个在线网站工具可以实时的实现json数据的格式化:www.json.cn/
1.1 Android自带的Json解析器
自带的解析器的API都存在于org.json包下,用到的类有下面这些:
- JSONObject: Json对象,可以完成Json字符串与Java对象的相互转换
- JSONArray: Json数组,可以完成Json字符串与Java集合或对象的相互转换,[]
- JSONStringer: Json文本构建类,这个类可以帮助快速和便捷的创建JSON text, 每个JSONStringer实体只能对应创建一个JSON text
- JSONTokener:Json解析类
- JSONException:Json异常
使用方法参见案例17的原生解析方法,如下:
private List<Lesson> parseJsonByNative(String jsonStr) {
List<Lesson> lessons = new ArrayList<>();
try {
JSONObject jsonObject = new JSONObject(jsonStr);
int code = jsonObject.getInt("status");
if (code != 1) {
return null;
}
JSONArray dataArray = jsonObject.getJSONArray("data");
for (int i = 0; i < dataArray.length(); i++) {
JSONObject lessonObject = dataArray.getJSONObject(i);
int id = lessonObject.getInt("id");
String name = lessonObject.getString("name");
String picSmall = lessonObject.getString("picSmall");
String picBig = lessonObject.getString("picBig");
String description = lessonObject.getString("description");
int learner = lessonObject.getInt("learner");
Lesson lesson = new Lesson();
lesson.setId(id);
lesson.setName(name);
lesson.setPicSmall(picSmall);
lesson.setPicBig(picBig);
lesson.setDescription(description);
lesson.setLearner(learner);
lessons.add(lesson);
}
} catch (JSONException e) {
e.printStackTrace();
}
return lessons;
}
1.2 Gson解析库
Gson是google开源的一款用于json解析的库,受到很多开发者的喜爱。
Gson在github的开源库地址:github.com/google/gson
在Android中使用gson有两种方式:
- 在build.gradle文件中设置库依赖:implementation 'com.google.code.gson:gson:2.8.6'
- 下载gson.jar包,放在Android项目恶libs目录中
设置依赖后,即可在项目中使用Gson解析数据,如下所示:
private Lesson[] parseByGson(String jsonStr) {
Gson gson = new Gson();
Type type = new TypeToken<Common<Lesson>>() {
}.getType();
Common<Lesson> common = gson.fromJson(jsonStr, type);
return common.data;
}
1.3 FastJson解析库
fastjson是阿里巴巴团队开源的一款json解析库,使用的项目和团队也很多。在github上的star数达到了21.2k,超过了gson。
FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。FastJson采用独创的算法,将parse的速度提升到极致,超过所有json库。
fastjson开源库在github的开源地址:github.com/alibaba/fas…
在Android中使用fastjson,需要在项目的build.gradle文件中设置依赖:
compile 'com.alibaba:fastjson:1.1.71.android'
同样的和gson一样,也可以下载最新的jar文件,放在android项目的libs目录中进行依赖设置。
public static List<Lesson> parseByFastJson(String jsonStr) {
com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(jsonStr);
com.alibaba.fastjson.JSONArray jsonArray = jsonObject.getJSONArray("data");
return jsonArray.toJavaList(Lesson.class);
}
1.4 Jackson
Jackson是当前用的比较广泛的,用来序列化和反序列化json的Java开源框架。Jackson是最流行的json解析器之一,Java应用框架中很多都是使用Jackson库。目前github上Jackson的star数量达到5.5K。
Jackson在github上的地址如下:github.com/FasterXML/j…
使用Jackson:
- 先下载jar包
- 放入到项目的libs目录中,设置依赖为library
- 在x项目中进行使用
此处省略案例,可自行练习。
1.5 解析库对比和总结
- 反序列化操作:总体上JSONObject处理性能比较突出,但是JSONObject的缺点是啰嗦,代码量多,需要些try...catch等冗余代码。
- Gson:随着数据量的增大,Gson库耗时会增加。
- FastJson操作:性能比较好,数据的量级对内存消耗影响较小,且消耗内存比较小。
- JSONObject原生:数据量大时,JSONObject内存消耗很明显。
- Jackson:耗时和内存消耗上都较大。
① 数据量小时,可以选择JSONObject进行处理,要接收代码量冗余。Gson和FastJson差不多。
② 数据量大时,或者数据量会有明显的量级的增加变化,FastJson综合表现更好。
二、加载网络数据的注意事项
json数据通常都是通过网络接口请求而来,因此需要进行网络访问获取数据,包括图片的加载也是需要网络的。
uses-permission网络权限
使用网络,需要在AndroidMainfest.xml文件中设置使用网络权限。
<!--网络权限-->
<uses-permission android:name="android.permission.INTERNET"/>
Https规范
在Android P版本开始,为了安全起见,不在允许使用http形式的接口。为了解决这个问题,可以通过在AndroidManifest.xml文件的Application文件中,设施usesCleartextTraffic属性为true来,表示使用明文网络流量。推荐还是尽快转换接口升级为https。
数据请求更新规范
① 在Android中,不能在主线程请求网络,否则会报错,网络请求需要放在工作子线程中。
② 在Android中,请求数据完毕,不能在子线程中操作UI,否则会报错。
图片加载开源库
图片加载在android中可以使用比较成熟的开源库来解决,常用的图片加载开源库是Glide,picasso等。
glide
glide在github上的开源地址是:github.com/bumptech/gl…
使用时首先需要引入glide库的依赖:
//图片网络库
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
在图片控件加载的地方,执行如下操作:
Glide.with(mContext).load(lesson.getPicBig()).into(holder.imgCover);
picasso
picasso在github上的开源地址是:github.com/square/pica…
使用时首先需要引入glide库的依赖:
implementation 'com.squareup.picasso:picasso:2.71828'
在图片控件加载的地方,执行如下操作:
Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView);