Android——使用Volley+fastJson在新线程中读取网络接口获取天气信息

来源:互联网 发布:公安大数据情报分析 编辑:程序博客网 时间:2024/06/06 03:47



一,关于Volley


           其实最初对于网络数据的访问,我是没想到要用框架的,使用HttpURLConnection或者HttpGet or HttpPost都可以实现。但是why? why I have to use Volley?


       Before Volley:

              

class HttpURLConnection_post extends Thread{@Overridepublic 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-typeurlConn.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 blocke.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). 提供简便的图片加载工具。


       基于它有这么多的优点,而且比较官方正统,是在原始网络访问类的基础上的一个扩展及优化,所以,我们使用它来从网络中读写数据。


二,使用fastJson   

 

       安卓中的数据是以轻量高效的数据传输格式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 blocke.printStackTrace();}

     

       但是这种做法并不高效,因此,我们可以使用fastjson或者jackjson来实现这个过程的简单操作。


三,关于安卓的开启新线程及为什么要使用异步处理消息类

       

     安卓系统的线程模型属于单线程模型,假如在非UI线程中去访问或者更新只能在UI线程中去更新的视图类就会报异常。但是很多耗时的操作又不能放在UI线程中,我们只能在主线程上start一个新线程,然后再新线程中放入我们的网络访问,IO访问等操作。

     但是当我们取到数据之后,因为在非UI线程中是不允许更新UI的组件视图的,所以我们要使用异步处理的消息类去通知主线程,完成更新视图的操作。

 

三,简单Demo


       首先是跟我的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;}}

    原json:

 

{    "result": 0,     "content": "★ 北京天气{br}霾,18℃,东北风2级{br}★ 三天预测{br}[10月06日] 白天:霾,25℃,无持续风向;夜晚:雾,15℃,无持续风向{br}[10月07日] 白天:阴,25℃,无持续风向;夜晚:晴,13℃,北风{br}[10月08日] 白天:晴,19℃,北风;夜晚:多云,9℃,无持续风向"}

   接着引用volley跟fastjson的jar包:



在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线程中执行@Overridepublic 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;}} };@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.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{@Overridepublic 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 blocke.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整体框架正在完善中,欢迎补充!




      


3 2
原创粉丝点击