赵 鹏,骆德汉,梅领亮
(1.广东工业大学 信息工程学院,广东 广州 510006; 2.广东正业科技股份有限公司,广东 东莞 523270)
一种基于JSON的Android终端远程获取解析数据的方法*
赵 鹏1,骆德汉1,梅领亮2
(1.广东工业大学 信息工程学院,广东 广州510006;2.广东正业科技股份有限公司,广东 东莞523270)
JSON作为一种轻量级的数据交换格式,具有安全、快速、通用、数据通信量小等优点,这些优点使JSON成为理想的数据交换语言。Android移动终端对数据的远程访问量正飞速增长,对数据的远程获取方法也提出了更高的要求,而JSON的众多优点使之能很好地满足这一要求。文章在Volley框架中使用GET方式远程获取JSON数据,然后对JSON数据进行解析处理,最终通过Handler把处理后的数据更新到UI控件上,从而实现JSON数据在Android终端上的远程获取解析和显示。
Android;JSON;Volley;Handler
在众多移动终端平台中,Android平台的市场占有率最高。由于移动终端无法进行海量数据的存储和计算,因此大多数Android应用都采用“客户端”+“云端”的模式,该模式的关键就在于移动终端与服务器端的交互。移动终端与服务器端的交互日益频繁,因此选择一种数据通信量小、快速、安全、通用的数据通信方式就显得尤为重要[1]。JSON作为一种轻量级的数据交换语言,具有安全、快速、通用、数据通信量小等特性,这让JSON成为了理想的数据通信方式。
Android终端远程获取解析JSON数据并显示的主要流程是:开启子线程,请求服务器,服务器对请求进行处理并做出响应,子线程接收响应,获取JSON数据,然后对数据进行解析,最后通过Handler在UI控件上显示解析后的数据。整个流程如图1所示。
图1 流程图
在整个流程中,请求服务器并获取JSON数据时,需要用到一种网络通信框架——Volley;Android终端获取JSON数据之后,解析JSON数据时,需要用到JSON解析技术;在Android开发中,耗时的操作(如请求服务器,从数据库中读取数据等)都要在子线程中进行,而在一般情况下,子线程中不能更新UI控件,因此,为了将解析后的JSON数据显示在UI控件上,还需要使用Handler。
综上可知,在整个流程中,需要使用三大关键技术:Volley、JSON解析和Handler。
1.1Volley
Android终端远程获取数据时,绝大部分都需要HTTP(超文本传输协议)来进行网络数据的交互。为了简化HTTP的通信操作,Android开发团队推出了一种网络通信架构——Volley。Volley简单易用,并且非常适合进行数据量不大但通信频繁的网络操作[2]。
HTTP协议的请求方式有两种:GET方式和POST方式。下面首先介绍在Volley框架中,GET方式的实现流程。该流程如下所示:
(1)下载volley.jar,并导入到Android项目中。
(2)获取RequestQueue对象,代码如下所示:
RequestQueue mQueue = Volley.newRequestQueue(context);
(3)创建StringRequest对象,代码如下所示:
StringRequest stringRequest = new StringRequest(url,new Response.Listener
@Override
public void onResponse(String response){
//服务器响应成功后执行的操作
}
}
new Response.ErrorListener(){
@Override
public void onErrorResponse(VolleyError error){
//服务器响应失败后执行的操作
}
});
StringRequest的构造方法需要传入三个参数,第一个参数就是服务器的URL地址,第二个参数是服务器响应成功的回调,第三个参数是服务器响应失败的回调。其中,public void onResponse(String response)的参数response就是请求成功之后,从服务器中获取的响应值。
(4)将StringRequest对象添加到RequestQueue中,代码如下:
mQueue.add(stringRequest);
以上就是在Volley框架中GET方式的实现流程,POST方式的实现流程与GET方式类似,只需把上述的第三步做如下修改即可:
StringRequest stringRequest = new StringRequest(Method.POST,url,listener,errorListener) {
@Override
protected Map
Map
map.put("key","value");
return map;
}
}
其中,listener和errorListener分别是服务器响应成功和失败后的回调,map用来添加要提交给服务器的参数。
1.2JSON解析
JSON的全称是JavaScript Object Notation,它是一种轻量级的数据交换格式,可以让人们很容易地进行阅读和编写,同时也可以方便机器进行生成和解析。JSON主要有两种表示结构:对象和数组。
1.2.1对象
对象结构以“{”开始,以“}”结束,中间部分由0个或多个以“,”分隔的“key(键):value(值)”对组成,其中键是字符串,值可以是字符串、对象或数组等。语法结构如下所示:
{
key1:value1,
key2:value2,
…
}
1.2.2数组
数组结构以“[”开始,以“]”结束,中间由0或多个以“,”分隔的值的列表组成。语法结构为:[value1,value2,value3]。
1.2.3解析
在实际应用中,从服务器中获取的JSON数据的具体形式千差万别,不过,解析思路基本一致。JSON主要有两种表示结构,这两种结构的解析思想是一样的。这里以JSON对象为例,来说明JSON解析的方法。
如果要解析的响应值response是一个JSON对象,那么首先可以用下面的代码获取一个JSONObject对象:
JSONObject rootJson=new JSONObject(response);
然后用rootJson调用对应的方法来获取想要的值。比如:如果要获取该JSON对象中的一个String类型的键值对“key”:“value”的值,那么可以使用如下代码:
String value=rootJson.getString(“key”);
如果想获取该JSON对象中的其他类型的数据,参考上述方法即可。
1.3Handler
在Android开发中,耗时的操作(如请求服务器、数据库的操作等)都需要在子线程中执行。但是Android中有这样一个审计机制:当activity完全展示(相当于activity的生命周期执行到onResume()方法)之后,系统会去检测子线程中有没有更新UI控件(除SurfaceView和Process类之外)的内容,如果有,那么整个程序就不能正常运行。
因此网络请求的相关操作需要放到子线程中进行,但是子线程中不能更新UI控件的内容,于是,就产生了矛盾。解决这一矛盾的方法就是使用Handler。
这里以更新TextView控件的内容为例,来说明Handler的一般使用流程。该流程如下所示(假定已经创建了一个TextView对象tv):
(1)在主线程中创建一个Handler对象,并重写其中的handleMessage方法,用来接收子线程中发来的消息,并更新tv的内容。代码如下所示:
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg){
String newData = (String)msg.obj;
tv.setText(newData);
}
}
(2)在子线程中获取Message对象msg,然后把要更新到TextView控件上的数据绑定给msg,最后通过Handler对象handler 把msg发送到主线程。代码如下所示:
new Thread(new Runnable() {
@Override
public void run() {
Message msg = Messge.obtain();
msg.obj = newData;
handler.sendMessage(msg);
}
}).start();
下面用一个实例来验证Android终端远程获取解析并显示JSON数据的这种方法。在该例中,服务器中已保存了工厂某台空调机的运行数据(已封装为JSON格式),Android终端直接获取解析并显示在UI控件上即可。
2.1请求网络
在Android应用程序的主线程中创建一个子线程,然后在子线程中利用volley框架,使用GET方式请求服务器,获取JSON数据。简洁起见,下面仅列出使用GET方式请求服务器的核心代码。
(1)子线程中请求服务器的核心代码:
VolleyConnection volleyConnection = new VolleyConnection();
volleyConnection.volleyGet(mContext,url,new VolleyManager() {
@Override
public void getResponse(String response) {
Message msg = Message.obtain();
//jsonProcess方法用来解析服务器的响应值(JSON格式)
msg.obj = jsonProcess(response);
handler.sendMessage(msg);
}
});
(2)VolleyConnection类中的核心代码:
public void volleyGet(Context context,String url,final VolleyManager volleyManager) {
RequestQueue mQueue = Volley.newRequestQueue(context);
StringRequest stringRequest = new StringRequest(url,new Response.Listener
@Override
public void onResponse(String response) {
volleyManager.getResponse(response);
//通过回调的方法,获取响应值response
}
}
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
volleyManager.getResponse("ERROR");
}
});
mQueue.add(stringRequest);
}
2.2解析JSON数据
从服务器中获取JSON数据之后,就可以进行解析。解析JSON数据的核心代码如下所示:
public static RootBean jsonProcess(String response){
RootBean rootBean = new RootBean();
try {
JSONObject rootJson = new JSONObject(response);
rootBean.Status = rootJson.getInt("Status");
rootBean.Msg = rootJson.getString("Msg");
try {
JSONArray jsonArray = rootJson.getJSONArray("Data");
DataBean dataBean = new DataBean();
dataBean.DeviceNo = jsonArray.getJSONObject(0).getString("DeviceNo");
dataBean.RoomNo = jsonArray.getJSONObject(0).getString("RoomNo");
dataBean.Floor= jsonArray.getJSONObject(0).getString("Floor");
dataBean.WorkStatus = jsonArray.getJSONObject(0).getString("WorkStatus");
dataBean.BeginTime = jsonArray.getJSONObject(0).getString("BeginTime");
dataBean.Timing = jsonArray.getJSONObject(0).getString("Timing");
dataBean.Model = jsonArray.getJSONObject(0).getString("Model");
dataBean.WindSpeed = jsonArray.getJSONObject(0).getString("WindSpeed");
dataBean.WindDirection = jsonArray.getJSONObject(0).getString("WindDirection");
dataBean.Temperature = jsonArray.getJSONObject(0).getString("Temperature");
dataBean.WorkerNo = jsonArray.getJSONObject(0).getString("WorkerNo");
rootBean.dataList.add(dataBean);
//dataList用来保存JSON中的每一个data数组
}catch (JSONException e){
rootBean.dataList = null;
e.printStackTrace();
}
return rootBean;
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
2.3Handler更新UI
在子线程中请求服务器,并对响应值进行JSON解析之后,要想在UI控件中显示解析后的数据,可以使用Handler。利用Handler把解析后的JSON数据更新到UI控件上的核心代码如下所示:
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
RootBean rootBean = (RootBean) msg.obj;
if(rootBean != null){
if(rootBean.Status == 1){
tv_DeviceNo.setText(rootBean.dataList.get(0).DeviceNo);
tv_RoomNo.setText(rootBean.dataList.get(0).RoomNo);
tv_Floor.setText(rootBean.dataList.get(0).Floor);
tv_WorkStatus.setText(rootBean.dataList.get(0).WorkStatus);
tv_BeginTime.setText(rootBean.dataList.get(0).BeginTime);
tv_Timing.setText(rootBean.dataList.get(0).Timing);
tv_Model.setText(rootBean.dataList.get(0).Model);
tv_WindSpeed.setText(rootBean.dataList.get(0).WindSpeed);
tv_WindDirection.setText(rootBean.dataList.get(0).WindDirection);
tv_Temperature.setText(rootBean.dataList.get(0).Temperature);
tv_WorkerNo.setText(rootBean.dataList.get(0).WorkerNo);
}else{
Toast.makeText(getApplicationContext(),rootBean.Msg,Toast.LENGTH_SHORT).show();
}
}else{Toast.makeText(getApplicationContext(),"未获取到数据!",Toast.LENGTH_SHORT).show();
}
}
}
2.4结果展示
整个程序的运行结果如图2所示。
图2 程序运行结果
根据实验结果可以看出,整个方法是完全可行的。JSON的诸多优点使得它在实际的工程开发中得到了非常广泛的应用,经过不断的发展和完善,Volley和Handler的综合性能已经非常卓越。因此,总体来说,上述的这种远程获取解析并显示JSON数据的方法是完全高效可行的。
[1] 龚成莹,邢敬宏,胡银保.基于JSON的Android移动终端与PHP及MySQL数据通信[J].工业仪表与自动化装置,2013(1):63-65.
[2] 孟远.Android网络通信框架Volley的解析和比较[J].软件,2014(12):66-68.
A method of obtaining and resolving data remotely on Android terminal based on JSON
Zhao Peng1, Luo Dehan1, Mei Lingliang2
(1.Information Engineering Institute,Guangdong University of Technology,Guangzhou 510006,China;2.Guangdong Zhengye Technology Stock Limited Company,Dongguan 523270,China)
As a lightweight data-interchange format,JSON has a lot of advantages,such as safe,fast,global,and small data traffic.Just because of those excellent merits,JSON becomes an ideal data-interchange language.The remote access traffic of data of Android mobile terminal is increasing in a very fast speed ,and it puts forward higher requirements to the method of remote access of data.The wonderful virtues of JSON make itself meets those requirements perfectly.In this paper,we use the method of GET in Volley communication framework to obtain JSON data remotely.Then,to resolve and handle JSON data,and update the handled JSON data to the widgets of UI finally though handler.By this way,we can obtain JSON data remotely,resolve it efficiently,and display it on Android mobile terminal easily.
Android; JSON; Volley; Handler
TP391.1
A
10.19358/j.issn.1674-7720.2017.21.018
赵鹏,骆德汉,梅领亮.一种基于JSON的Android终端远程获取解析数据的方法J.微型机与应用,2017,36(21):57-60.
广东省科技计划项目(2014B010124001,2016B030303011);广东省教育厅研究生教育创新计划项目(2015JGXM-ZD14)
2017-06-01)
赵鹏(1991-),男,硕士,主要研究方向:Android医疗监护系统。
骆德汉(1958-),通信作者,男,博士,教授,主要研究方向:机器仿真嗅觉/嗅觉传感技术,智能信息处理,绿色电子技术及应用,网络控制系统集成,智能仪器与嵌入式系统。
梅领亮(1973-),男,硕士,高级工程师,主要研究方向:光机电一体化。