andriod开发,简单的封装网络请求并监听返回.

时间:2024-07-25 20:07:08

一.为什么封装

因为android 4.0 以后的发送网络请求必须要放到异步线程中,而异步线程必须跟handle合作才能更新主线程中的UI,所以建议用一个类继承handler来异步处理网络请求.

二.封装哪些功能.

首先,每次发送网络请求都需要先检测网络连接是否正常.其次需要向用户提供一个提示信息,比如ProgressDialog,然后简单粗暴的把网络请求结果设为3种:1->请求成功;2->请求失败;3->连接超时.请求成功的话就返回正确的结果,请求失败就提示网络请求失败.请求超时就询问是否重连.所以需要封装的就有:

1.检测网络

/**
* 判断网络连接
*/
private boolean isNetworkConnect() {
ConnectivityManager cm = (ConnectivityManager) activity
.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.getActiveNetworkInfo();
if (cm.getActiveNetworkInfo() != null) {
return cm.getActiveNetworkInfo().isAvailable();
}
return false;
} /**
* 打开网络对话框
*/
private void whetherOpenNet() {
if (dialog != null) {
dialog.cancel();
dialog = null;
}
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle("网络木有连接");
builder.setMessage("是否打开网络连接");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override
public void onClick(DialogInterface dialog, int which) {
activity.startActivityForResult(new Intent(
Settings.ACTION_WIRELESS_SETTINGS), OPEN_NETWORK);
}
});
builder.setNegativeButton("取消", null);
dialog = builder.create();
dialog.show();
}

2.进度条提示

/**
* 显示进度条提示
*
* @param message
*/
private void showPd(String message) {
showLog("start connect");
if (message == null || message.length() == 0) {
return;
}
if (pd != null) {
pd.cancel();
pd = null;
}
pd = new ProgressDialog(activity);
pd.setMessage(message);
pd.setOnCancelListener(new OnCancelListener() { @Override
public void onCancel(DialogInterface dialog) {
requestThread.interrupt();
}
});
pd.setCancelable(true);
pd.show();
}

3.处理请求结果

/**
* 发起一个post请求,返回string对象
*
* @param stringListener
* @param isLoadCache
* true 为加载缓存,false为不加载缓存
*/
public void postRequest(final String text,
final RequestStringListener stringListener) {
if (!isNetworkConnect()) {
whetherOpenNet();
return;
}
showPd(text);
Runnable task = new Runnable() { @Override
public void run() {
try {
final String result = postStringResult();
if (requestThread.isInterrupted()) {
showLog("is interrupted");
return;
}
if (result == null) {
netError();
return;
}
post(new Complete() { @Override
public void run() {
super.run();
stringListener.onComplete(result);
sendEmptyMessage(REQUEST_SUCCESS);
}
});
} catch (SocketTimeoutException e) {
timeOut(text, stringListener);
e.printStackTrace();
} catch (Exception e) {
netError();
e.printStackTrace();
} }
};
requestThread = new Thread(task);
requestThread.start();
} /**
* 网络连接超时
*
* @param text
* @param stringListener
*/
protected void timeOut(final String text,
final RequestStringListener stringListener) {
sendEmptyMessage(REQUEST_TIMEOUT);
Looper.prepare();
post(new Complete() { @Override
public void run() {
super.run();
new AlertDialog.Builder(activity)
.setTitle("网络连接超时")
.setNegativeButton("取消", null)
.setPositiveButton("重连",
new DialogInterface.OnClickListener() { @Override
public void onClick(DialogInterface dialog,
int which) {
showLog("重连");
postRequest(text, stringListener);
}
}).show();
}
}); } /**
* 网络连接错误或返回数据为空
*
*/
protected void netError() {
sendEmptyMessage(REQUEST_ERROR);
Looper.prepare();
post(new Complete() { @Override
public void run() {
super.run();
if (!isNetworkConnect()) {
whetherOpenNet();
} else {
Toast.makeText(getActivity(), "网络连接失败,请稍后重试",
Toast.LENGTH_LONG).show();
}
}
});
}

三.使用

封装完成后就可以使用了.

NetApi netApi = new NetApi(MainActivity.this,
"http://192.168.10.233:8089/web_test/json");
netApi.addParams("test", "test");
netApi.postRequest("测试请求", new RequestStringListener() { @Override
public void onComplete(String result) {
Log.d("test", "result is --->" + result);
}
});

四.贴出完整代码

package com.example.test_android;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map; import org.json.JSONException; import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast; /**
* 网络接口,post请求string或者get请求json,里面只包含一个线程,只能同时发送一个网络请求
*
* @author oldfeel
*
*/
public class NetApi extends Handler {
/** 打开网络连接 */
public static final int OPEN_NETWORK = -1;
/** 请求成功 */
public static final int REQUEST_SUCCESS = 1;
/** 请求失败 */
public static final int REQUEST_ERROR = 2;
/** 网络连接超时 */
public static final int REQUEST_TIMEOUT = 3;
/** 超时时间限制 */
private static final int TIME_OUT = 30 * 1000;
private Activity activity;
private Map<String, String> params = new HashMap<String, String>();
private String path = "";
private ProgressDialog pd;
private Thread requestThread;
private AlertDialog dialog; /**
* 构造一个netapi对象
*
* @param context
*
* @param path
* 这次请求需要调用的url
*/
public NetApi(Activity activity, String path) {
this.activity = activity;
this.path = path;
} /**
* 添加参数,用url编码格式
*
* @param key
* @param value
*/
public void addParams(String key, Object value) {
if (!isEmpty(key) && !isEmpty(value)) {
params.put(key.trim(), value.toString().trim());// *.trim(),取消首尾空格
}
} /**
* 补充路径,比如添加 /信息类别id/新闻id
*
* @param objects
*/
public void addPath(Object... objects) {
for (Object object : objects) {
path = path + "/" + getUrlEncode(object);
}
} /**
* 检查该参数是否有内容,没有的话就不用添加了
*
* @param str
* @return true为没有内容,false为有内容
*/
public boolean isEmpty(Object str) {
if (str == null || str.toString().length() == 0)
return true;
else
return false;
} /**
* 获取url编码的字符串
*
* @param value
* @return
*/
private String getUrlEncode(Object value) {
try {
return URLEncoder.encode(value.toString().trim(), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
} /**
* get请求,拼接url路径,并对参数进行urlencode
*/
public String getPath() {
if (params.size() == 0) {
return path;
}
StringBuilder sb = new StringBuilder();
boolean first = path.indexOf("?") == -1; // 不包含?(first=true)说明是第一次添加参数,包含?说明url中带有参数
for (String key : params.keySet()) {
if (first) {
first = false;
sb.append("?");
} else {
sb.append("&");
}
sb.append(key + "=" + getUrlEncode(params.get(key)));
}
return path + sb.toString();
} /**
* post请求,传入的参数
*
* @return
*/
private String postParams() {
if (params.size() == 0) {
return path;
}
boolean isFrist = true;
StringBuilder sb = new StringBuilder();
for (String key : params.keySet()) {
if (isFrist) {
sb.append(key + "=" + params.get(key));
isFrist = false;
} else {
sb.append("&" + key + "=" + params.get(key));
}
}
return sb.toString();
} /**
* 显示进度条提示
*
* @param message
*/
private void showPd(String message) {
showLog("start connect");
if (message == null || message.length() == 0) {
return;
}
if (pd != null) {
pd.cancel();
pd = null;
}
pd = new ProgressDialog(activity);
pd.setMessage(message);
pd.setOnCancelListener(new OnCancelListener() { @Override
public void onCancel(DialogInterface dialog) {
requestThread.interrupt();
}
});
pd.setCancelable(true);
pd.show();
} /**
* 发起一个post请求,返回string对象
*
* @param stringListener
* @param isLoadCache
* true 为加载缓存,false为不加载缓存
*/
public void postRequest(final String text,
final RequestStringListener stringListener) {
if (!isNetworkConnect()) {
whetherOpenNet();
return;
}
showPd(text);
Runnable task = new Runnable() { @Override
public void run() {
try {
final String result = postStringResult();
if (requestThread.isInterrupted()) {
showLog("is interrupted");
return;
}
if (result == null) {
netError();
return;
}
post(new Complete() { @Override
public void run() {
super.run();
stringListener.onComplete(result);
sendEmptyMessage(REQUEST_SUCCESS);
}
});
} catch (SocketTimeoutException e) {
timeOut(text, stringListener);
e.printStackTrace();
} catch (Exception e) {
netError();
e.printStackTrace();
} }
};
requestThread = new Thread(task);
requestThread.start();
} /**
* 网络连接超时
*
* @param text
* @param stringListener
*/
protected void timeOut(final String text,
final RequestStringListener stringListener) {
sendEmptyMessage(REQUEST_TIMEOUT);
Looper.prepare();
post(new Complete() { @Override
public void run() {
super.run();
new AlertDialog.Builder(activity)
.setTitle("网络连接超时")
.setNegativeButton("取消", null)
.setPositiveButton("重连",
new DialogInterface.OnClickListener() { @Override
public void onClick(DialogInterface dialog,
int which) {
showLog("重连");
postRequest(text, stringListener);
}
}).show();
}
}); } /**
* 网络连接错误或返回数据为空
*
*/
protected void netError() {
sendEmptyMessage(REQUEST_ERROR);
Looper.prepare();
post(new Complete() { @Override
public void run() {
super.run();
if (!isNetworkConnect()) {
whetherOpenNet();
} else {
Toast.makeText(getActivity(), "网络连接失败,请稍后重试",
Toast.LENGTH_LONG).show();
}
}
});
} /**
* 发送post上传文件,获取字符串结果
*
* @param isLoadCache
* true为加载缓存,false为不加载缓存
*/
public String postStringResult() throws IOException, JSONException {
showLog("path is " + path);
showLog("post is " + postParams());
HttpURLConnection conn = getConn(path, "POST");
// 配置post请求的参数
DataOutputStream outputStream = new DataOutputStream(
conn.getOutputStream());
outputStream.writeBytes(postParams());
outputStream.flush();
outputStream.close(); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
String data = formatStreamToString(conn);
showLog("result is " + data);
return data;
}
return null;
} /**
* 根据url获取网络链接
*
* @param path
* @param requestType
* 请求方式,post或者get
* @return
* @throws IOException
*/
private HttpURLConnection getConn(String path, String requestType)
throws IOException {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod(requestType);
conn.setConnectTimeout(TIME_OUT);
conn.setReadTimeout(TIME_OUT);
conn.connect();
return conn;
} /**
* 将网络连接中的输入流转换成string字符串
*
* @param conn
* @return
* @throws IOException
*/
private String formatStreamToString(HttpURLConnection conn)
throws IOException {
StringBuffer out = new StringBuffer();
BufferedReader input = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
String line = null;
while ((line = input.readLine()) != null) {
out.append(line);
}
input.close();
return out.toString();
} class Complete implements Runnable {
@Override
public void run() {
if (pd != null) {
pd.cancel();
}
requestThread.interrupt();
}
} /**
* 判断网络连接
*/
private boolean isNetworkConnect() {
ConnectivityManager cm = (ConnectivityManager) activity
.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.getActiveNetworkInfo();
if (cm.getActiveNetworkInfo() != null) {
return cm.getActiveNetworkInfo().isAvailable();
}
return false;
} /**
* 打开网络对话框
*/
private void whetherOpenNet() {
if (dialog != null) {
dialog.cancel();
dialog = null;
}
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle("网络木有连接");
builder.setMessage("是否打开网络连接");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override
public void onClick(DialogInterface dialog, int which) {
activity.startActivityForResult(new Intent(
Settings.ACTION_WIRELESS_SETTINGS), OPEN_NETWORK);
}
});
builder.setNegativeButton("取消", null);
dialog = builder.create();
dialog.show();
} /**
* 打印日志
*
* @param log
*/
private void showLog(String log) {
Log.d("example", log);
} /**
* 获取当前NetApi绑定的activity
*
* @return
*/
public Activity getActivity() {
return this.activity;
} /**
* 请求string的监听
*/
public interface RequestStringListener {
/** 返回字符串 */
public void onComplete(String result);
}
}