其实最初对于网络数据的访问,我是没想到要用框架的,使用HttpURLConnection或者HttpGet or HttpPost都可以实现。但是why? why I have to use Volley?
Before Volley:
class HttpURLConnection_post extends Thread{
@Override
public void run() {
//设置请求的路径
String strUrl="http://api.qingyunke.com/api.php";
//
//将请求的参数进行UTF-8编码,并转换成byte数组=
try {
String params="key="+URLEncoder.encode("free","UTF-8")+"appid="+URLEncoder.encode("0","UTF-8")+"msg="+URLEncoder.encode("天气梅州","UTF-8");
byte[] postData=params.getBytes();
//创建一个URL对象
URL url=new URL(strUrl);
//打开一个HttpURLConnection连接
HttpURLConnection urlConn=(HttpURLConnection)url.openConnection();
//设置连接超时的时间
urlConn.setDoOutput(true);
//在使用post请求的时候,设置不能使用缓存
urlConn.setUseCaches(false);
//设置该请求为post请求
urlConn.setRequestMethod("POST");
urlConn.setInstanceFollowRedirects(true);
//配置请求content-type
urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencode");
//执行连接操作
urlConn.connect();
//发送请求的参数
DataOutputStream dos=new DataOutputStream(urlConn.getOutputStream());
dos.write(postData);
dos.flush();
dos.close();
//若请求成功通过读取连接的数据流,则获取返回的数据
if(urlConn.getResponseCode()==200){
//显示
InputStreamReader isr = new InputStreamReader(urlConn.getInputStream(), "utf-8");
int i;
String strResult = "";
// read
while ((i = isr.read()) != -1) {
strResult = strResult + (char) i;
}
isr.close();
textview=(TextView)findViewById(R.id.textview1);
textview.setText(strResult); //显示在textView中
}else
{
textview.setText(urlConn.getResponseCode()); //显示在textView中
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
对于上面代码,我只能说只能将就着用。
volley来源:
Volley 是 Google 推出的 Android 异步网络请求框架和图片加载框架。在 Google I/O 2013 大会上发布。
从名字由来和配图中无数急促的火箭可以看出 Volley 的特点:特别适合数据量小,通信频繁的网络操作。(个人认为 Android 应用中绝大多数的网络操作都属于这种类型)。
主要特点:
(1). 扩展性强。Volley 中大多是基于接口的设计,可配置性强。
(2). 一定程度符合 Http 规范,包括返回 ResponseCode(2xx、3xx、4xx、5xx)的处理,请求头的处理,缓存机制的支持等。并支持重试及优先级定义。
(3). 默认 Android2.3 及以上基于 HttpURLConnection,2.3 以下基于 HttpClient 实现,这两者的区别及优劣在4.2.1 Volley
中具体介绍。
(4). 提供简便的图片加载工具。
基于它有这么多的优点,而且比较官方正统,是在原始网络访问类的基础上的一个扩展及优化,所以,我们使用它来从网络中读写数据。
安卓中的数据是以轻量高效的数据传输格式json作为载体的。所以,在安卓开发中,有很大一部分代码,我们是要对JSON字符串及对象或者集合进行转换的代码。
我们可以使用传统的JSONObject或者JSONArray:
//创建一个对象
JSONObject person=new JSONObject();
//创建数组对象
JSONArray phone=new JSONArray();
phone.put("123445");
try {
person.put("name", "lhc");
person.put("age", 100);
//创建一个对象
JSONObject address=new JSONObject();
address.put("country","china");
address.put("province","hebei");
person.put("address", address);
//JSON文本的解析
JSONObject object=new JSONObject(person.toString());
JSONArray array=object.getJSONArray("phone");
String phonenum=(String) array.get(0);
String name=object.getString("name");
int age=object.getInt("age");
JSONObject object1=object.getJSONObject("address");
String country=object1.getString("country");
String province=object1.getString("province");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
但是这种做法并不高效,因此,我们可以使用fastjson或者jackjson来实现这个过程的简单操作。
安卓系统的线程模型属于单线程模型,假如在非UI线程中去访问或者更新只能在UI线程中去更新的视图类就会报异常。但是很多耗时的操作又不能放在UI线程中,我们只能在主线程上start一个新线程,然后再新线程中放入我们的网络访问,IO访问等操作。
但是当我们取到数据之后,因为在非UI线程中是不允许更新UI的组件视图的,所以我们要使用异步处理的消息类去通知主线程,完成更新视图的操作。
首先是跟我的Json对应的实体类:
package com.example.demoproject;
public class WeatherInfo {
private String result;//请求的结果
private String content;//返回的内容
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
{ "result": 0, "content": "★ 北京天气{br}霾,18℃,东北风2级{br}★ 三天预测{br}[10月06日] 白天:霾,25℃,无持续风向;夜晚:雾,15℃,无持续风向{br}[10月07日] 白天:阴,25℃,无持续风向;夜晚:晴,13℃,北风{br}[10月08日] 白天:晴,19℃,北风;夜晚:多云,9℃,无持续风向" }
在AndroidManifest.xml中配置网络的访问权限:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
Activity中代码:
package com.example.demoproject;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import com.alibaba.fastjson.JSON;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.Request.Method;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.ActionBarActivity;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity {
private static final int MSG_SUCCESS = 0;//获取天气信息成功的标识
private static final int MSG_FAILURE = 1;//获取天气信息失败的标识
private TextView textView;
/*
* 这里拿到的RequestQueue是一个请求队列对象,
* 它可以缓存所有的HTTP请求,然后按照一定的算法并发地发出这些请求。
* RequestQueue内部的设计就是非常合适高并发的,
* 因此我们不必为每一次HTTP请求都创建一个RequestQueue对象,
* 这是非常浪费资源的,基本上在每一个需要和网络交互的Activity中创建一个RequestQueue对象就足够了。
* */
private RequestQueue mQueue;
//用于更新UI线程的handler
private Handler mHandler=new Handler(){
//此方法在UI线程中执行
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case MSG_SUCCESS:
WeatherInfo weather=(WeatherInfo)msg.obj; //获取消息信息
textView.setText(weather.getContent());
break;
case MSG_FAILURE:
textView.setText("获取信息失败,请稍后重试");
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textview1);
mQueue=Volley.newRequestQueue(MainActivity.this);
new Thread(new WeatherTest()).start();//在新线程中读取数据并绑定
}
/*
* 读取天气数据使用的新线程
* 天气接口示例:
* http://api.qingyunke.com/api.php?key=free&appid=0&msg=天气北京
* */
class WeatherTest implements Runnable{
@Override
public void run() {
String strURL="http://api.qingyunke.com/api.php?key=free&appid=0&msg=";//请求数据的地址
String strCity="";
try {
/*
* 注:volley中的参数必须进行编码,不然会出现乱码问题
* */
strCity=URLEncoder.encode("天气北京","UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
strURL+=strCity;
/*
* 使用Volley中封装的StringRequest对象来发送HTTP请求
* StringRequest需要三个参数:
* 0,获取数据的方法
* 1,目标服务器的URL地址
* 2,服务器响应成功的回调
* 3,服务器响应失败的回调
* */
StringRequest stringRequest = new StringRequest(Method.GET,strURL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
/*成功获取到数据之后的处理*/
WeatherInfo weatherInfo=null;
//将json串转为对象
weatherInfo=JSON.parseObject(response.toString(),WeatherInfo.class);
//绑定数据过程
mHandler.obtainMessage(MSG_SUCCESS,weatherInfo).sendToTarget();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
//读取失败的处理
mHandler.obtainMessage(MSG_FAILURE).sendToTarget();
}
});
mQueue.add(stringRequest); //将请求添加到请求队列中
}}
}
JRKJ整体框架正在完善中,欢迎补充!
版权声明:本文为博主原创文章,未经博主允许不得转载。
Android——使用Volley+fastJson在新线程中读取网络接口获取天气信息
原文地址:http://blog.csdn.net/lhc1105/article/details/48931707