1.写在前面

大部分andriod应用需要与服务器进行数据交互,HTTP、FTP、SMTP或者是直接基于SOCKET编程都可以进行数据交互,但是HTTP必然是使用最广泛的协议。

本文并不针对HTTP协议的具体内容,仅探讨android开发中使用HTTP协议访问网络的两种方式——HttpURLConnection和HttpClient

因为需要访问网络,需在AndroidManifest.xml中添加如下权限

2.HttpURLConnection

2.1 GET方式

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("https://www.jb51.net");

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();

}

2.2 POST方式

import java.io.DataOutputStream;

//将对应部分改为

connection.setRequestMethod("POST");

DataOutputStream data = new DataOutputStream(connection.getOutputStream());

data.writeBytes("stu_no=12345&stu_name=Tom");

传入多个参数用&隔开

如需传入复杂的参数,可使用JSON,关于JSON的用法介绍,可以参考我的另一篇随笔JSON解析的两种方法。

3.HttpClient

3.1 GET方式

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("https://www.jb51.net");

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");

}

3.2 POST方式

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("https://www.jb51.net");

// 使用NameValuePair(键值对)存放参数

List data = new ArrayList();

// 添加键值对

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方式一致

3.3 android 6.0移除HttpClient

android 6.0(API 23)版本的SDK已将Apache HttpClient相关类移除,解决办法自行GOOGLE,推荐使用HTTPURLConnection。

若还需使用该类,点击查看解决办法。

4.HttpURLConnection实战如果你使用过JQuery(一个javasript库),你一定对JQuery的网路编程印象深刻,比如一个HTTP请求只需以下几行代码。

// JQuery的post方法

$.post("https://www.jb51.net",{

"stu_no":12345,

"stu_name":"Tom",

}).done(function(){

//...请求成功的代码

}).fail(function(){

//...请求失败的代码

}).always(function(){

//...总会执行的代码

})

我们当然不希望每次网络请求都写下2.1中那么繁琐的代码,那么android的HTTP请求能否像JQuery那么简单呢?当然可以!下面的代码实现了HttpURLConnection的HTTP请求方法封装:

4.1 定义接口HttpCallbackListener,为了实现回调

// 定义HttpCallbackListener接口

// 包含两个方法,成功和失败的回调函数定义

public interface HttpCallbackListener {

void onFinish(String response);

void onError(Exception e);

}

4.2 创建HttpTool类,抽象请求方法(GET)

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();

}

}

4.3 调用示例

//使用该HttpTool发起GET请求

String url = "https://www.jb51.net";

HttpTool.sendRequest(url,new HttpCallbackListener(){

@Override

public void onFinish(String response) {

// ...省略对返回结果的处理代码

}

@Override

public void onError(Exception e) {

// ...省略请求失败的处理代码

}

});

4.4 抽象请求方法(POST)

/* 在GET方法实现的基础上增加一个参数params即可,

* 将参数转换为字符串后传入

* 也可以传入键值对集合,再处理 */

public static void sendRequest(final String address,

final String params, final HttpCallbackListener listener){

//...

}

以上就是本文的全部内容,希望对大家的学习有所帮助。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐