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

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



一,关于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整体框架正在完善中,欢迎补充!




      


目录
相关文章
|
2天前
|
安全 API 数据库
【转】Android线程模型(AsyncTask的使用)
【转】Android线程模型(AsyncTask的使用)
|
3天前
|
SQL 安全 算法
网络防线的构筑者:深入网络安全与信息保护
【5月更文挑战第8天】在数字时代,数据成为了新的金矿,而网络安全则是守护这些宝贵资源的堡垒。本文将探讨网络安全漏洞的形成、加密技术的应用以及提升个人和企业的安全意识的重要性。通过对网络威胁的剖析和防护策略的介绍,旨在为读者提供一系列实用的网络安全知识与实践指导。
7 1
|
4天前
|
Shell 开发工具 Android开发
android 修改kernel编译版本信息
android 修改kernel编译版本信息
13 0
|
4天前
|
Android开发
Android 获取签名信息
Android 获取签名信息
7 0
|
4天前
|
Shell Android开发
android mk中打印信息
android mk中打印信息
9 0
|
4天前
|
安全 算法 网络安全
网络防线的构筑者:洞悉网络安全与信息保护
【5月更文挑战第7天】在数字化时代,数据成为了新的石油。随之而来的是对数据安全和隐私保护的挑战。本文深入探讨了网络安全漏洞的概念、成因以及它们对个体和企业造成的潜在危害。同时,文章将解析加密技术的种类和原理,以及它们如何成为维护信息安全不可或缺的工具。此外,强调了提升安全意识的重要性,并提出了实用的策略和建议,以增强个人和组织在面对日益复杂的网络威胁时的防御能力。
39 4
|
4天前
|
云安全 安全 网络安全
构筑安全之云:云计算环境下的网络安全与信息保护
【5月更文挑战第7天】 随着信息技术的飞速发展,云计算已成为支撑现代企业运作的重要基石。然而,伴随其便利性与高效性的,是对网络安全和信息保护的新挑战。本文旨在深入探讨云计算环境中所面临的核心安全威胁,并分析现有及新兴的安全技术如何协同作用以强化数据保护。通过综合评估不同防护策略的优势与局限,文章提出了一个多层次、动态适应的安全框架,以期为构建更为坚固的云上防线提供参考和启示。
|
5天前
|
Java 开发工具 Android开发
如何访问 android系统hide的类或接口
如何访问 android系统hide的类或接口
13 1
|
5天前
|
SQL 安全 网络安全
网络堡垒的构建者:深入网络安全与信息保护
【5月更文挑战第6天】 在数字化浪潮不断推进的今天,网络安全和信息安全成为了维护个人隐私、企业商业秘密和国家安全的重要议题。本文将探讨网络安全中的漏洞问题、加密技术的进展以及提升安全意识的必要性。通过分析当前网络攻击手段的复杂性,我们揭示了安全漏洞产生的原因及其对系统安全的潜在威胁。同时,文章还将介绍最新的加密技术如何为数据传输提供强有力的保护,并讨论如何通过培训和教育来增强用户的安全意识,以形成更为坚固的网络防线。
|
7天前
|
存储 安全 物联网
网络防御前线:洞悉网络安全漏洞与加固信息防线
【5月更文挑战第4天】 在数字化时代,网络安全已成为维护信息完整性、确保数据传输安全的关键阵地。本文将深入探讨网络安全领域的重要议题—包括识别和应对安全漏洞、应用加密技术以及提升个体和企业的安全意识。通过对这些关键要素的剖析,我们旨在为读者提供一个关于如何构建坚固网络防御体系的全面视角。
28 6