博客逐步迁移至 极客兔兔的小站javascript
大部分andriod应用须要与服务器进行数据交互,HTTP、FTP、SMTP或者是直接基于SOCKET编程均可以进行数据交互,可是HTTP必然是使用最普遍的协议。
本文并不针对HTTP协议的具体内容,仅探讨android开发中使用HTTP协议访问网络的两种方式——HttpURLConnection
和HttpClient
由于须要访问网络,需在AndroidManifest.xml中添加以下权限html
<uses-permission android:name="android.permission.INTERNET" />
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; // 如下代码实现了以GET方式发起HTTP请求 // 链接网络是耗时操做,通常新建线程进行 private void connectWithHttpURLConnection() { new Thread( new Runnable() { @Override public void run() { HttpURLConnection connection = null; try { // 调用URL对象的openConnection方法获取HttpURLConnection的实例 URL url = new URL("http://www.cnblogs.com/gzdaijie"); connection = (HttpURLConnection) url.openConnection(); // 设置请求方式,GET或POST connection.setRequestMethod("GET"); // 设置链接超时、读取超时的时间,单位为毫秒(ms) connection.setConnectTimeout(8000); connection.setReadTimeout(8000); // getInputStream方法获取服务器返回的输入流 InputStream in = connection.getInputStream(); // 使用BufferedReader对象读取返回的数据流 // 按行读取,存储在StringBuider对象response中 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } //.......... // 此处省略处理数据的代码 // 若须要更新UI,需将数据传回主线程,具体可搜索android多线程编程 } catch (Exception e){ e.printStackTrace(); } finally { if (connection != null){ // 结束后,关闭链接 connection.disconnect(); } } } }).start(); }
import java.io.DataOutputStream; //将对应部分改成 connection.setRequestMethod("POST"); DataOutputStream data = new DataOutputStream(connection.getOutputStream()); data.writeBytes("stu_no=12345&stu_name=Tom");
- 传入多个参数用 & 隔开
- 如需传入复杂的参数,可以使用JSON,关于
JSON的用法介绍
,能够参考个人另外一篇随笔JSON解析的两种方法。
import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.HttpResponse; import org.apache.http.HttpEntity; import org.apache.http.HttpStatus; // 建立DefaultHttpClient实例 HttpClient httpClient = new DefaultHttpClient(); //传入网址,而后执行 HttpGet httpGet = new HttpGet("http://www.cnblogs.com/gzdaijie"); HttpResponse httpResponse = httpClient.execute(httpGet); // 由状态码判断请求结果, // 常见状态码 200 请求成功,404 页面未找到 // 关于HTTP的更多状态码直接GOOGLE if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { // 请求成功,使用HttpEntity得到返回数据 // 使用EntityUtils将返回数据转换为字符串 HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity); //若是是中文,指定编码 //==>String response = EntityUtils.toString(entity, "utf-8"); }
import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.message.BasicNameValuePair; HttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost("http://www.cnblogs.com/gzdaijie"); // 使用NameValuePair(键值对)存放参数 List<NameValuePair> data = new ArrayList<NameValuePair>(); // 添加键值对 data.add(new BasicNameValuePair("stu_no", 12345)); data.add(new BasicNameValuePair("stu_name", "Tom")); // 使用setEntity方法传入编码后的参数 httpPost.setEntity(new UrlEncodedFormEntity(data, "utf-8")); // 执行该POST请求 HttpResponse httpResponse = httpClient.execute(httpPost); // .....省略处理httpResponse的代码,与GET方式一致
- android 6.0(API 23)版本的SDK已将Apache HttpClient相关类移除,解决办法自行GOOGLE,推荐使用HTTPURLConnection。
- 若还需使用该类,点击查看解决办法。
若是你使用过JQuery
(一个javasript库),你必定对JQuery的网路编程印象深入,好比一个HTTP请求只需如下几行代码。java
// JQuery的post方法 $.post("http://www.cnblogs.com/gzdaijie",{ "stu_no":12345, "stu_name":"Tom", }).done(function(){ //...请求成功的代码 }).fail(function(){ //...请求失败的代码 }).always(function(){ //...总会执行的代码 })
咱们固然不但愿每次网络请求都写下2.1中那么繁琐的代码,那么android的HTTP请求可否像JQuery那么简单呢?固然能够!下面的代码实现了HttpURLConnection的HTTP请求方法封装
:android
// 定义HttpCallbackListener接口 // 包含两个方法,成功和失败的回调函数定义 public interface HttpCallbackListener { void onFinish(String response); void onError(Exception e); }
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; /* 建立一个新的类 HttpTool,将公共的操做抽象出来 * 为了不调用sendRequest方法时需实例化,设置为静态方法 * 传入HttpCallbackListener对象为了方法回调 * 由于网络请求比较耗时,通常在子线程中进行, * 为了得到服务器返回的数据,须要使用java的回调机制 */ public class HttpTool { public static void sendRequest(final String address, final HttpCallbackListener listener) { new Thread(new Runnable() { @Override public void run() { HttpURLConnection connection = null; try { URL url = new URL(address); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); InputStream in = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } if (listener != null) { // 回调方法 onFinish() listener.onFinish(response.toString()); } } catch (Exception e) { if (listener != null) { // 回调方法 onError() listener.onError(e); } } finally { if (connection != null) { connection.disconnect(); } } } }).start(); } }
//使用该HttpTool发起GET请求 String url = "http://www.cnblogs.com/gzdaijie"; HttpTool.sendRequest(url,new HttpCallbackListener(){ @Override public void onFinish(String response) { // ...省略对返回结果的处理代码 } @Override public void onError(Exception e) { // ...省略请求失败的处理代码 } });
/* 在GET方法实现的基础上增长一个参数params便可, * 将参数转换为字符串后传入 * 也能够传入键值对集合,再处理 */ public static void sendRequest(final String address, final String params, final HttpCallbackListener listener){ //... }