1.写在前面
大部分andriod应用需要与服务器进行数据交互,HTTP、FTP、SMTP或者是直接基于SOCKET编程都可以进行数据交互,但是HTTP必然是使用最广泛的协议。
本文并不针对HTTP协议的具体内容,仅探讨android开发中使用HTTP协议访问网络的两种方式——HttpURLConnection和HttpClient
因为需要访问网络,需在AndroidManifest.xml中添加如下权限
1
|
< uses-permission android:name = "android.permission.INTERNET" />
|
2.HttpURLConnection
2.1 GET方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
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的实例
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方式
1
2
3
4
5
6
|
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方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
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();
//传入网址,然后执行
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方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
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();
// 使用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方式一致
|
3.3 android 6.0移除HttpClient
android 6.0(API 23)版本的SDK已将Apache HttpClient相关类移除,解决办法自行GOOGLE,推荐使用HTTPURLConnection。
若还需使用该类,点击查看解决办法。
4.HttpURLConnection实战
如果你使用过JQuery(一个javasript库),你一定对JQuery的网路编程印象深刻,比如一个HTTP请求只需以下几行代码。
1
2
3
4
5
6
7
8
9
10
11
|
// JQuery的post方法
"stu_no" : 12345 ,
"stu_name" : "Tom" ,
}).done(function(){
//...请求成功的代码
}).fail(function(){
//...请求失败的代码
}).always(function(){
//...总会执行的代码
})
|
我们当然不希望每次网络请求都写下2.1中那么繁琐的代码,那么android的HTTP请求能否像JQuery那么简单呢?当然可以!下面的代码实现了HttpURLConnection的HTTP请求方法封装:
4.1 定义接口HttpCallbackListener,为了实现回调
1
2
3
4
5
6
|
// 定义HttpCallbackListener接口
// 包含两个方法,成功和失败的回调函数定义
public interface HttpCallbackListener {
void onFinish(String response);
void onError(Exception e);
}
|
4.2 创建HttpTool类,抽象请求方法(GET)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
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 调用示例
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//使用该HttpTool发起GET请求
HttpTool.sendRequest(url, new HttpCallbackListener(){
@Override
public void onFinish(String response) {
// ...省略对返回结果的处理代码
}
@Override
public void onError(Exception e) {
// ...省略请求失败的处理代码
}
});
|
4.4 抽象请求方法(POST)
1
2
3
4
5
6
7
|
/* 在GET方法实现的基础上增加一个参数params即可,
* 将参数转换为字符串后传入
* 也可以传入键值对集合,再处理 */
public static void sendRequest( final String address,
final String params, final HttpCallbackListener listener){
//...
}
|
以上就是本文的全部内容,希望对大家的学习有所帮助。