Android 网络数据JSON解析使用(建议收藏)
Posted 彬sir哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 网络数据JSON解析使用(建议收藏)相关的知识,希望对你有一定的参考价值。
(一)数据请求的准备和分析
这里使用的网络中请求的数据,相当于一个完整的app数据
这里推荐一个请求json数据的一个平台网站:showapi
必须先在平台注册账号,可以使用邮箱注册账号,注册账号后,可以兔费使用指定的一些接口,也可以付费使用一些付费接口
在showapi网址上输入“笑话大全”,按下图操作:
这代码中URL必须要添加showapi_appid和showapi_sign后才能在URL中请求到数据的
我们可以得到一个简单的URL字符串地址:http://route.showapi.com/341-1?showapi_appid=763801&time=&page=&maxResult=&showapi_sign=b60a1ce58a124536b5ff9eb33587c284点击这链接后显示json数据如下图:
对于这个返回的字符串我们也是要去看一下的,因为我们的json解析是从外到内一层一层去解析数据的。这里最好下载一个json数据格式化的工具,或者在网页中直接使用json格式工具,可以把一长串的字符串显示为json格式,方便我们去解析它的数据。
数据解析前,如图所示:
数据显示的是连接在一起的,很难区分标签和段落所以使用解析工具就非常重要了。
数据解析后,如图所示:
一、解析网络中复杂的json数据的程序示例
这里设计一个简易的笑话大全的软件
程序运行后显示的界面:
这里的布局设计的是两个按钮,单击“java请求”获取的是页面源码的json数据
点击“android请求笑话大全”,跳转到另一个页面显示解析后的数据
2.布局文件activity_main.xml的设计
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="conn1"
android:text="java请求" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/main_et_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:background="@null"
android:hint="输入页数"
android:singleLine="true" />
<CheckBox
android:id="@+id/main_cb_isImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="选择图片" />
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="conn2"
android:text="Android请求笑话大全" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/main_tv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ScrollView>
</LinearLayout>
上面使用一个ScrollView来显示获取到的json数据
3.布局文件activity_joke.xml的设计
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="@+id/joke_tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="title"
android:textColor="@android:color/black"
android:textSize="18sp" />
<TextView
android:id="@+id/joke_tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="content"
android:textColor="@android:color/black"
android:textSize="16sp" />
<ImageView
android:id="@+id/joke_iv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:adjustViewBounds="true"
android:scaleType="fitXY" />
<TextView
android:id="@+id/joke_tv_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:gravity="right"
android:text="时间"
android:textSize="14sp" />
</LinearLayout>
上面的布局是每一个笑话内容显示的布局设计
4.创建一个json解析和数据收集的类
package com.lwz.conn;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.Serializable;
import java.util.ArrayList;
/**
* 这是一个数据解析的工具类,
* <p>
* 这里是从源码中取出属性值
* 这里是使用从外到内一层一层的去获取资源数据,最里面一层的数据才是我们要显示在页面上的数据
* 这里的处理的方式是比较麻烦的一种,其中它处理的方式可以有好几种
* 这里的数据层层嵌套,就像xml资源的子标签一样
*/
/*下面是提供API网站给我们的数据的提示,xml文件中下面的某些变量,我们可以选择性的去使用,
但是这些变量的名字是固定的,更改了就获取不到了
allNum String 345 所有记录数
allPages String 45 所有页数。每页20条。
contentlist JokeItem[] 笑话条目内容
- title String 吃了一百年的玉米 笑话标题
- text String 笑话正文
- ct String 2015-07-10 05:54:00.000 生成时间
currentPage String 1 当前第几页
maxResult String 20 每页最多显示几条*/
//因为要Intent来实现数据的传递,所以要实现序列化
public class JokeBean implements Serializable {
//最外层的属性值
int showapi_res_code;
String showapi_res_error;
Body showapi_res_body;//这个才是有用的信息数据,上面的实现其实也是可以不用去定义的
@Override
public String toString() {
return "JokeBean{" +
"showapi_res_body=" + showapi_res_body +
", showapi_res_code=" + showapi_res_code +
", showapi_res_error='" + showapi_res_error + '\\'' +
'}';
}
class Body implements Serializable {
int allNum;
int allPages;
int currentPage;//当前第几页
int maxResult;
int ret_code;
ArrayList<Content> contentlist;
@Override
public String toString() {
return "Body{" +
"allNum=" + allNum +
", allPages=" + allPages +
", currentPage=" + currentPage +
", maxResult=" + maxResult +
", ret_code=" + ret_code +
", contentlist=" + contentlist +
'}';
}
class Content implements Serializable {
String id;
String ct;//生成时间
String text;//笑话正文
String title;//笑话标题
int type;//文本笑话,图片笑话,动态图笑话
String img;//笑话的图片连接地址URL
//重写toString方法,查看数据
@Override
public String toString() {
return "Content{" +
"ct='" + ct + '\\'' +
", id='" + id + '\\'' +
", text='" + text + '\\'' +
", title='" + title + '\\'' +
", type=" + type +
", img='" + img + '\\'' +
'}';
}
}
}
/**
* 创建一个静态的转换方法
* 将字符串使用json解析的方式,转换成对象
* 用于把资源代码的字符串中某些值赋值给某些需要的变量
*/
public static JokeBean getBeanValue(String json) {
try {
//1.将最外层的字符串,转换为json对象
JSONObject jsonObject = new JSONObject(json);
//2.创建返回的对象
JokeBean jokeBean = new JokeBean();
//3.取外层的数据,两种方法opt和get,其中opt更好,get在数据不匹配时会报错
jokeBean.showapi_res_code = jsonObject.optInt("showapi_res_code");
jokeBean.showapi_res_error = jsonObject.optString("showapi_res_error");
//4.取第二层数据,是一个对象
JSONObject bodyObject = jsonObject.optJSONObject("showapi_res_body");
//5.通过这个对象的值,再去取数据
//创建内部对象,把获取到的数据赋值给这个类的对象
Body body = jokeBean.new Body();
body.allNum = bodyObject.optInt("allNum");
body.allPages = bodyObject.optInt("allPages");
body.currentPage = bodyObject.optInt("currentPage");
body.maxResult = bodyObject.optInt("maxResult");
body.ret_code = bodyObject.optInt("ret_code");
//Log.e("TAG", "jokeBean------------>" + jokeBean.toString());
// Log.e("TAG", "body------------>" + body.toString());
//这里的contentlist的数据是数组类型的!
JSONArray array = bodyObject.optJSONArray("contentlist");
//创建一个集合用来存放数组
body.contentlist = new ArrayList<>();
//通过数据遍历循环去取所有的对象
for (int i = 0; i < array.length(); i++) {
Body.Content content = body.new Content();
//再次使用json解析数据
//集合通过optXXX(index)的方法去取值
JSONObject obj = array.optJSONObject(i);
content.ct = obj.optString("ct");//笑话的创建时间
content.id = obj.optString("id");//笑话的id编号
content.title = obj.optString("title");//笑话的标题
content.type = obj.optInt("type");//笑话的类别,1代表文本,2代表图像
//对类别的判断
if (content.type == 2) {
content.img = obj.optString("img");
} else {
content.text = obj.optString("text");
}
body.contentlist.add(content);
}
//Log.e("TAG", "body.c------------>" + body.contentlist.toString());
jokeBean.showapi_res_body = body;
//返回一个JokeBean对象,里面包含所有的数据
return jokeBean;
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
5.创建一个异步任务类,用来下载json数据
package com.lwz.conn.utils;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.util.Log;
import com.lwz.conn.JokeBean;
import com.lwz.conn.ShowActivity;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* 异步任务的创建
* 这里的任务是下载网络的资源文件
*/
public class MyAsyncTask extends AsyncTask<String, Void, String> {
Context context;
public MyAsyncTask(Context context) {
this.context = context;
}
//在子线程中做资源的下载
@Override
protected String doInBackground(String... params) {
try {
//从params中获取传过来的URL
URL url = new URL(params[0]);
Log.e("TAG", params[0]);
//使用URLconnection的子类HttpURLconnection来请求连接更好
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);//设置要读取文件
conn.setConnectTimeout(10000);//设置连接的最长时间
InputStream is = conn.getInputStream();//获取连接的输入流
ByteArrayOutputStream baos = new ByteArrayOutputStream(); //创建一个高速的输出流来读取输入流
//对数据的读取(边读边取)
int len = 0;
byte[] buf = new byte[1024];
while ((len = is.read(buf)) != -1) {
baos.write(buf, 0, len);
}
//获得的输出流变成String类型的字符串,用于最后的返回
String result = new String(baos.toByteArray(), "utf-8");//设置编码格式
//返回的是获取的一大串文本资源源码
Log.e("TAG","-------------->"+ result);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//任务完成后页面的跳转,把相关数据带到要跳转的页面
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
//这里接收的s,就是从网络中获取到的一大串字符串的文件源码
//这里要使用json解析,从源码中来获取我们需要的数据
Log.e("TAG", s);
JokeBean jokeBean = JokeBean.getBeanValue(s)Go 要如何才能解释的清!和 Json 之间的种种映射关系! 「含解决方案 & 代码实现,建议收藏!」