码迷,mamicode.com
首页 > 移动开发 > 详细

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

时间:2015-10-06 16:55:31      阅读:1553      评论:0      收藏:0      [点我收藏+]

标签:android   开源框架   多线程   java   



一,关于Volley


           其实最初对于网络数据的访问,我是没想到要用框架的,使用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). 提供简便的图片加载工具。


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


二,使用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 block
			e.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线程中执行
		@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在新线程中读取网络接口获取天气信息

标签:android   开源框架   多线程   java   

原文地址:http://blog.csdn.net/lhc1105/article/details/48931707

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!