功能简介
上图是我们存放在服务器端的Json文件,上面是浏览器直接访问的效果,有点凌乱,我们将它格式化:
如图,它是词汇书中的一个单词,包含了,翻译英标,例句,联想记忆的图片Url等属性,我们需要做的就是将它下载到手机端,用Java对象进行封装, 然后就可以在App中使用了。
功能实现步骤:
下载文件保存到本地
将下载的json文件保存到本地,这样在下次用的时候就不用再去进行下载了。
这里我们使用OkHttpClient
OkHttpClient配置
我的这个版本是没有自带OkHttpClient模块的,配置方法和之前的模块一样:
implementation 'com.squareup.okhttp3:okhttp:3.4.1'
把这行代码加载build.gradle文件的dependencies里面就ok了。
OkHttpClient实现HTTP请求的发送和接收过程
- 创建一个OkHttpClient实例
- 创建一个Request实例
- 使用 OkHttpClient 创建一个Call并执行 execute()方法,得到一个Response对象
- 对Response 进行相关操作
OkHttpClient client = new OkHttpClient().newBuilder().build();
Request request = new Request.Builder().url("http://www.baidu.com").build();
Response response = client.newCall(request).execute();
ResponseBody responseBody = response.body();
是不是比我们之前的方法要简单很多
将文本内容格式化为json数组
这里的文本还不是标准的json数组,少了[],以及用来分割的逗号,所以要进行一下修正,
我们的格式:
{xxx:“xxx” …}
{xxx:“xxx” …}
{xxx:“xxx” …}
…
修正后:
[{xxx:“xxx” …},
{xxx:“xxx” …},
{xxx:“xxx” …}
…]
String resStr = response.body().string();
String s = resStr.replace("{\"wordRank\"", ",{\"wordRank\"");
String ss = "[" + s.substring(0) + "]"; //mijue
因为我们的json文本,的第一个属性一定是“wordRank”即单词序号,所以按照上面的写法就可以完成文本的替换。
文本的保存与读取
文本的保存
直接使用如下的demo,其中,context,就是我们上面格式化后的json数组文本,
title就是我要给文件取得名字,等我们读取文件的时候就可以根据这个名字读取到我们存储的文件。
void writefile(String context, String title){
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = openFileOutput(title, MODE_PRIVATE);
fileOutputStream.write(context.getBytes());
Log.i(TAG, context);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文本的读取
原理与文本的保存是一样的,根据上面的title,去读取我们存储的文本,文本以String的形式返回。
String readfile(String title){
InputStream inputStream = null;
Reader reader = null;
BufferedReader bufferedReader = null;
try {
File file=new File(getFilesDir().getPath(), title);
Log.i(TAG, "readfile: ");
inputStream = new FileInputStream(file);
reader = new InputStreamReader(inputStream);
bufferedReader = new BufferedReader(reader);
StringBuilder result = new StringBuilder();
String temp;
while ((temp = bufferedReader.readLine()) != null) {
result.append(temp);
}
String context = String.valueOf(result);
return context;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return "error";
}
解析json数组
刚刚只是将我们放在服务器端的json数组,搬到了本地,不能直接再我们的程序中使用这些资源,我们还需要对数据进行处理 --------将其解析为Java对象,这里我们使用一个很好用的模块:Gson
Gson简介:
Google Gson是一个简单的基于Java的库,用于将Java对象序列化为JSON,反之亦然。 它是由Google开发的一个开源库。
以下几点说明为什么应该使用这个库 :
- 标准化 - Gson是一个由Google管理的标准化库。
- 高效 - 这是对Java标准库的可靠,快速和高效的扩展。
- 优化 -Gson库经过高度优化。
- 支持泛型 - 它为泛型提供了广泛的支持。
- 支持复杂的内部类 - 它支持具有深度继承层次结构的复杂对象。
最主要的是:它是免费提供的。
处理JSON的三种方法Gson提供了三种处理JSON的替代方法 -
- 流媒体API 它读取和写入JSON内容作为离散事件。 JsonReader和JsonWriter将数据读取/写入令牌,称为JsonToken。 这是处理JSON的三种方法中最强大的方法。
它具有最低的开销,并且在读/写操作中速度非常快。 它类似于用于XML的Stax解析器。- 树模型它准备JSON文档的内存树表示。 它构建了一个JsonObject节点树。 这是一种灵活的方法,类似于XML的DOM解析器。
- 数据绑定它使用属性访问器将JSON转换为POJO(普通旧Java对象)并从中转换。 Gson使用数据类型适配器读取/写入JSON。 它类似于XML的JAXB解析器。
引用自:https://www.yiibai.com/gson/gson_overview.html
gson配置
和OkHttpClient一样:
implementation 'com.google.code.gson:gson:2.8.6'
加入这一行就OK了。
构建本地数据对象
为了方便的使用数据,我们需要建立结构化的对象来对数据进行操作,以每一个单词为单位,我们创建一个单词类:使用我们之前使用过的bean类。
package com.example.testapp.bean;
public class WordItem {
// 单词序号
private int wordRank;
// 单词名称
private String headWord;
// 单词内容
private JsonWordTotal content;
// 单词归属数目
private String bookId;
public int getWordRank() {
return wordRank;
}
public void setWordRank(int wordRank) {
this.wordRank = wordRank;
}
public String getHeadWord() {
return headWord;
}
public void setHeadWord(String headWord) {
this.headWord = headWord;
}
public JsonWordTotal getContent() {
return content;
}
public void setContent(JsonWordTotal content) {
this.content = content;
}
public String getBookId() {
return bookId;
}
public void setBookId(String bookId) {
this.bookId = bookId;
}
}
可以看到这里的内容与json的内容是一一对应的,这个就相当于我们用来接受json的容器,而且,我们还写了一些接口,用与对数据进行读取与操作。这只是第一层的对象,为了完整的将对象解析出来,我们需要按照原json文件的内容再去一一建立这样的数据对象:
这里就不一一展示了,感兴趣的可以去项目地址查看具体代码。
使用gson进行解析
List<WordItem> jiexi(String jsonContent){
Gson gson = new Gson();
List<WordItem> jsonWordList = gson.fromJson(jsonContent, new TypeToken<List<WordItem>>() {}.getType());
return jsonWordList;
}
使用上面那的代码就可以很方变得将我们的数据封装到jsonWordList里,这是一个list数组,里面存放的就是我们刚刚创建的WordItem,是不是超级简单。然后就可以使用索引对其中的内容进行操作了。
我们创建的bean对象一定要和我们的json一一对应
补充
- 本次内容就先不展示效果了,因为我们还需要将其与数据库结合。
- json url链接:https://nnggb.com/test/CET4luan_1.json 是来自网易的四级词汇(不可商用)。