本人刚刚毕业,自学Android不久,现在也是做Android应用开发工作。本人菜鸟一枚,如写的不好,代码有问题,请多多指教,谢谢!
由于一直在做Android应用开发的工作,代码写的多了,也就会发现很多问题。久而久之,自己写了一些公共类,封装起来,便于以后直接使用,方便自己也能和其它人共同学习交流!
废话不多说,进入正题!
在Android应用开发中,我们的每个Activity、Service或者其它组件想要请求网络获取数据,都必须要开启一条子线程去操作,然后向Handler去发送一条消息,告诉我们的UI线程子线程的工作完成了,该你们接着工作了(为什么要这样呢,不了解的童鞋请百度Android的运行机制)。还有其它很多办法去开启子线程请求网络,这里我不一一介绍,只说比较常用的。
具体的操作步骤如下:
1.开启一条线程
2.在线程里请求网络,获得一个返回值(常用的有json、xml等)
3.请求成功或者失败,通知一下handler
4.在子线程中继续解析请求返回值(有人说为什么要在线程里解析呢?因为如果您解析的json串,或者xml数据量很大,或者逻辑很得杂,这是一件很耗时的工作,如果在UI线程里做,可能会造成卡顿的现象)
5.解析成功,通知handler,让handler去做下一步的操作。线程的工作完成
虽然看起来业务并不复杂,但是如果一个Android APP中有很多个Activity,并且很多个Activity都需要请求网络数据,那么大家就需要写很多次这个过程,并且也只有请求的路径、参数和返回的值不同而已!(如果有同学说,我不怕麻烦,我不怕代码多,那您就没必要继续往下看了)
构造函数和初使化参数
设置参数
由于一直在做Android应用开发的工作,代码写的多了,也就会发现很多问题。久而久之,自己写了一些公共类,封装起来,便于以后直接使用,方便自己也能和其它人共同学习交流!
废话不多说,进入正题!
在Android应用开发中,我们的每个Activity、Service或者其它组件想要请求网络获取数据,都必须要开启一条子线程去操作,然后向Handler去发送一条消息,告诉我们的UI线程子线程的工作完成了,该你们接着工作了(为什么要这样呢,不了解的童鞋请百度Android的运行机制)。还有其它很多办法去开启子线程请求网络,这里我不一一介绍,只说比较常用的。
具体的操作步骤如下:
1.开启一条线程
2.在线程里请求网络,获得一个返回值(常用的有json、xml等)
3.请求成功或者失败,通知一下handler
4.在子线程中继续解析请求返回值(有人说为什么要在线程里解析呢?因为如果您解析的json串,或者xml数据量很大,或者逻辑很得杂,这是一件很耗时的工作,如果在UI线程里做,可能会造成卡顿的现象)
5.解析成功,通知handler,让handler去做下一步的操作。线程的工作完成
虽然看起来业务并不复杂,但是如果一个Android APP中有很多个Activity,并且很多个Activity都需要请求网络数据,那么大家就需要写很多次这个过程,并且也只有请求的路径、参数和返回的值不同而已!(如果有同学说,我不怕麻烦,我不怕代码多,那您就没必要继续往下看了)
根据面向对象的特点,我们要做到尽量减少代码冗余,尽量让代码提高可重用性。为此,我自己编写了一个能够尽量提高代码重用的公共类,在这和大家分享,共同学习!如有疑问或不足,请尽量告诉我!
代码很简单
首先定义变量、常量等属性:
/**
* 请求网络路径
*/
private String url;
/**
* 请求网络参数
*/
private List<NameValuePair> params;
/**
* 是否是Post请求 true为Post请求 false为Get请求
*/
private boolean isPost = false;
/**
* 是否在请求的是候,使用缓存机制
*/
private boolean isCache = false;
/**
* 请求json的回调函数
*/
private OnNetReturnsListener onNetReturnsListener;
/**
* 请求网络失败错误码
*/
private static final int CONNECT_ERROR = -99;
/**
* 请求json的回调函数空指针错误码
*/
private static final int NULLPOINT_EXCEPTION = -98;
/**
* json解析失败错误码
*/
public static final int PARSE_ERROR = -97;
/**
* json解析成功码
*/
public static final int PARSE_SUCCESS = 99;
构造函数和初使化参数
/**
* 构造函数,默认为Get请求,没有url路径,没有请求参数
*/
public BaseRunnable() {
init(false, "", null);
}
/**
* 构造函数,没有url路径,没有请求参数
*
* @param isPost
*/
public BaseRunnable(boolean isPost) {
init(isPost, "", null);
}
/**
* 构造函数,默认为Get请求,没有请求参数
*
* @param url
* url路径
*/
public BaseRunnable(String url) {
init(false, url, null);
}
/**
* 构造函数,没有请求参数
*
* @param isPost
* 是否为Post请求,true为Post请求,false为Get请求
* @param url
* url路径
*/
public BaseRunnable(boolean isPost, String url) {
init(isPost, url, null);
}
/**
* 构造函数,默认为Post请求
*
* @param url
* url路径
* @param params
* 请求参数
*/
public BaseRunnable(String url, List<NameValuePair> params) {
init(true, url, params);
}
/**
* 构造函数
*
* @param isPost
* 是否为Post请求,true为Post请求,false为Get请求
* @param url
* url路径
* @param params
* 请求参数
*/
public BaseRunnable(boolean isPost, String url, List<NameValuePair> params) {
init(isPost, url, params);
}
/**
* 初始化请求参数
*
* @param isPost
* 是否为Post请求,true为Post请求,false为Get请求
* @param url
* url路径
* @param params
* 请求参数
*/
private void init(boolean isPost, String url, List<NameValuePair> params) {
this.isPost = isPost;
this.url = url;
this.params = params;
}
设置参数
/**
* 设置请求方式
*
* @param isPost
* true为Post请求,false为Get请求
*/
public void setIsPost(boolean isPost) {
this.isPost = isPost;
}
/**
* 设置url请求路径
*
* @param url
*/
public void setUrl(String url) {
this.url = url;
}
/**
* 设置请求参数
*
* @param params
*/
public void setParams(List<NameValuePair> params) {
this.params = params;
}
/**
* 设置请求是否使用缓存机制
* @param isCache
*/
public void setIsCache(boolean isCache) {
this.isCache = isCache;
}
线程相关操作,此类继承Runnable,调用时new Thread就可以。Handler用于处理常用消息,比如网络异常
/**
* 开始执行线程
*/
public void start() {
new Thread(this).start();
}
@Override
public void run() {
String json = "";
try {
// 选择请求方式
if (isPost) {
json = Caller.doPost(url, params, isCache);
} else {
json = Caller.doGet(url, isCache);
}
} catch (Exception e) {
// 网络请求异常处理
ExceptionUtil.setException(e);
mHandler.sendEmptyMessage(CONNECT_ERROR);
return;
}
// 定义json解析返回值
int parseId = PARSE_SUCCESS;
// 如果回调函数对象不为空,执行回调函数
if (onNetReturnsListener != null) {
parseId = onNetReturnsListener.onNetReturnsListener(json);
} else {
// 如果回调函数对象为空,抛出空指针异常
mHandler.sendEmptyMessage(NULLPOINT_EXCEPTION);
throw new NullPointerException(
"you must implement OnNetReturnsListener before in BaseRunnable to do start() method ");
}
if (parseId == PARSE_SUCCESS) {
// 解析成功
mHandler.sendEmptyMessage(PARSE_SUCCESS);
} else {
// 解析失败
mHandler.sendEmptyMessage(PARSE_ERROR);
}
}
//此处用了一些我自定义的Log打印类和Toast消息类
private static Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case PARSE_SUCCESS:
// 解析成功处理
L.i(R.string.json_parse_success); //打印Log
break;
case PARSE_ERROR:
// 解析失败处理
T.showShort(R.string.json_parse_error_t); //提示Toast消息
L.e(R.string.json_parse_error);
break;
case NULLPOINT_EXCEPTION:
// 回调函数对象空指针处理
T.showShort(R.string.null_point_exception);
L.e(R.string.null_point_exception);
break;
case CONNECT_ERROR:
// 请求网络失败处理
T.showShort(R.string.send_error);
L.e(R.string.send_error);
break;
default:
// 通知编码出错
T.showShort(R.string.handler_msg_default);
L.d(R.string.handler_msg_default);
break;
}
}
};
回调接口处理
/**
* 设置json解析回调函数对象
*
* @param onNetReturns
* json解析回调函数对象
*/
public void setOnNetReturnsListener(
OnNetReturnsListener onNetReturnsListener) {
this.onNetReturnsListener = onNetReturnsListener;
}
/**
* json解析回调函数接口
*/
public interface OnNetReturnsListener {
/**
* json解析回调函数接口函数
*
* @param json
* json值
* @return 返回一个整型数值<br/>
* 建议使用:<br/>
* {@link PARSE_SUCCESS}为解析成功<br/>
* {@link PARSE_ERROR}为解析失败<br/>
*/
int onNetReturnsListener(String json);
}
全类的代码都帖出来了,如果觉得有什么不足的地方,告诉我一声,我也好改进,大家共同学习,谢谢!
下面附上此类的使用方法,同样很简单,而且很容易
BaseRunnable run = new BaseRunnable(url);
run.setOnNetReturnsListener(new OnNetReturnsListener() {
@Override
public int onNetReturnsListener(String json) {
try {
//此处用于解析json或者其它操作,
//需要注意的是,这里的代码是运行在子线程中,各位可不要把操作UI线程的代码写在这里
//如有需要操作UI线程的,请自定义一个Handler去控制
} catch (Exception e) {
return BaseRunnable.PARSE_ERROR;
}
return BaseRunnable.PARSE_SUCCESS;
}
});
run.start();