一.为什么封装

因为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);
}
}

andriod开发,简单的封装网络请求并监听返回.的更多相关文章

  1. App 组件化/模块化之路——如何封装网络请求框架

    App 组件化/模块化之路——如何封装网络请求框架 在 App 开发中网络请求是每个开发者必备的开发库,也出现了许多优秀开源的网络请求库.例如 okhttp retrofit android-asyn ...

  2. 最简单的iOS网络请求

    做iOS开发,说到网络请求,大家可能都不约而同的提到AFN,可以说大家的网络请求都是用AFN封装而成,AFN的强大易用的确很好. 但是版本升级就会出现一些问题,所以就自己基于iOS原生封装了一个网络请 ...

  3. 微信小程序教学第二章(含视频):小程序中级实战教程之预备篇 - 封装网络请求及 mock 数据

    § 封装网络请求及 mock 数据 本文配套视频地址: https://v.qq.com/x/page/i05544fogcm.html 开始前请把 ch2-3 分支中的 code/ 目录导入微信开发 ...

  4. [iOS微博项目 - 3.3] - 封装网络请求

    github: https://github.com/hellovoidworld/HVWWeibo   A.封装网络请求 1.需求 为了避免代码冗余和对于AFN框架的多处使用导致耦合性太强,所以把网 ...

  5. 微信小程序开发——使用promise封装异步请求

    前言: 有在学vue的网友问如何封装网络请求,这里以正在写的小程序为例,做一个小程序的请求封装. 关于小程序发起 HTTPS 网络请求的Api,详情可以参考官方文档:wx.request(Object ...

  6. 09事件传递参数-封装网络请求api get和post合并整合在一起

    1==>通过点击事件进行传递参数 <view bindtap="goEdution" data-index="5">西南大学</view ...

  7. WebService如何封装XML请求 以及解析接口返回的XML

    原 WebService如何封装XML请求 以及解析接口返回的XML 置顶 2019年08月16日 15:00:47 童子泛舟 阅读数 28 标签: XML解析WebService第三方API 更多 ...

  8. Self Host模式下的ASP. NET Web API是如何进行请求的监听与处理的?

    构成ASP.NET Web API核心框架的消息处理管道既不关心请求消息来源于何处,也不需要考虑响应消息归于何方.当我们采用Web Host模式将一个ASP.NET应用作为目标Web API的宿主时, ...

  9. ASP.NET Core真实管道详解[2]:Server是如何完成针对请求的监听、接收与响应的【上】

    Server是ASP .NET Core管道的第一个节点,负责完整请求的监听和接收,最终对请求的响应同样也由它完成.Server是我们对所有实现了IServer接口的所有类型以及对应对象的统称,如下面 ...

随机推荐

  1. Java [Leetcode 172]Factorial Trailing Zeroes

    题目描述: Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be ...

  2. 数据库语言(二):SQL语法实例整理

    连接表达式: select * from student join takes on student.ID = takes.ID; 通过on后面的谓词作为连接条件,相同的属性可以出现两次,也就是等价于 ...

  3. 【jQuery】jQuery筛选器规则

    转载自:http://blog.csdn.net/lijinwei112/article/details/6938134 筛选器中加入变量 var ac = "select_" + ...

  4. iOS-利用AFNetworking(AFN 1.x)-实现文件上传

    转:http://www.kaifazhe.com/ios_school/380067.html 官方建议AFN的使用方法 1. 定义一个全局的AFHttpClient:包含有 1> baseU ...

  5. 写的cursor demo仅作记录

    declare @objectID int; declare objcur cursor for object_id from m_object open objcur fetch next from ...

  6. PHP 获取远程文件的大小的3种方法

    1.使用file_get_contents() <?php $file = file_get_contents($url); echo strlen($file); ?> 2. 使用get ...

  7. SSH整合常见错误

    spring+hibernate出错小结: (1)java.lang.NoClassDefFoundError: org/hibernate/context/CurrentSessionContext ...

  8. 深入浅出Zookeeper

    能找到的一些zookeeper的资料一上来不是扯一通paxos算法就是一大坨一大坨的代码.很多人对zookeeper更多的是听过,所以这一篇文章就尝试用尽可能用精简的语言科普zookeeper. zo ...

  9. work8

    使用裸指针: #include <iostream>#include <memory>#include <stdio.h>#include <cstring& ...

  10. 经典代码-C宏 #转字符串【瓦特芯 笔记】

    在调试C语言程序时,有时需要打印宏的名字.可以通过定义宏,宏名字的数组来获得. 例如: #include <stdio.h> #define MACRO_STR(x) {x, #x} ty ...