Android-处理 JSON数据(PhotoGallery应用)

解析 JSON 数据

这是通过使用 google 插件 postman 排好的格式

json.org API 提供有对应 JSON 数据的 Java 对象如 JSONObject 和 JSONArray。 使用 JSONObject(String) 构造函数,可以把 JSON 数据解析进相应的 Java 对象。

1
JSONObject jsonObject=new JSONObject(jsonString);

当将 json 字符串传入 JSONObject 对象后,会生成与原始 JSON 数据对应的对象树,如上图。

获取对应图片的信息并创建模型类
创建 GalleryItems ,并在网络类创建一个方法获取每张图片信息,需要获取的信息为模型类的字段

  1. id
  2. title
  3. url_s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*创建 parseItems() 获取 json字符串中我们想获得的并添加给 模型层*/
private void parseItems(List<GalleryItem> items, JSONObject jsonObject) throws JSONException {
// 获取 JSONObject
JSONObject jsonObject1 = jsonObject.getJSONObject("photos");
// 获取对象里面的数组
JSONArray jsonArray = jsonObject1.getJSONArray("photo");
// 循环遍历找出每一个对应的标题和id
for (int i = 0; i <= jsonArray.length(); i++) {
// 获取每一个 JSONObject 对象
JSONObject eachJSONObject=jsonArray.getJSONObject(i);
// 创建一个模型层的类,用于添加信息
GalleryItem item= new GalleryItem();
item.setId(eachJSONObject.getString("id"));
item.setCaption(eachJSONObject.getString("title"));
// 检查 是否有 url_s 的键
if(!eachJSONObject.has("url_s")){
continue;
}
item.setUrl(eachJSONObject.getString("url_s"));
items.add(item);
}
}

创建 ViewHolder 和 Adapter 内部类 实现 RecyclerView 的视图以及数据加载(代码部分省略)

从 AsyncTask 回到主线程

我们需要注意的是在后台我们获取了数据,需要把数据适配到前台中,不能再后台线程中调用设置适配器。在计算机里,内存对象间步调不一致冲突会让应用崩溃,所以不允许从后台更新 UI 线程

回顾AsyncTask

使用 onPostExecute(Result)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*创建一个 AsyncTask 的内部类,后台处理网络*/
private class FetchItemsTask extends AsyncTask<Void, Void, List<GalleryItem>> {
@Override
protected List<GalleryItem> doInBackground(Void... voids) {
// 获取网络中的String 数据
/* String result = new FlickerFerchr()
.getUrlString("http://www.bignerdranch.com");
// log 显示 String
Log.i("TAG","Fetched contents of URL:+"+result);*/
return new FlickerFerchr().fetchItems();
}
@Override
protected void onPostExecute(List<GalleryItem> items) {
mItems = items;
setupAdapter();
}
}

运行结果

清理 AsyncTask

一开始我们保留了 fragment(调用了 setRetainInstance(true) ),这样即使设备旋转,也不会重复创建新的 AsyncTask 去获取 JSON 数据。但是有些时候必须掌控它,让他能够随时撤销或重新运行 AsyncTask

AsyncTask.cancel(boolean)撤销

  1. 温和的(false)
  2. 粗暴的(true)

第一种,传入参数为 false ,它可能温和的设置 isCancel() 的状态,然后提前结束运行

第二种,传入参数为 true ,它会粗暴地终止 doInBackground() 方法当前所在的线程,应尽量避免使用这种方式

什么时候使用撤销?

当 fragment 和 activity 已经销毁了或者看不到了,就在 onStop() 方法里(看不到视图),或者 onDestory()方法里(fragment/activity) 实例已销毁撤销 AsyncTask 实例

fragment 和 activity 已经销毁了 不去销毁 AsyncTask 可能引发内存泄漏,也可能出现 UI 更新问题

(*^▽^*)