android里网络请求的封装整体思路差不多,可以参考我之前写的okhttp的封装。http://www.jianshu.com/p/92b37a5f414d
这里我主要写一下nohttp结合项目使用,在请求服务器,更新界面内容时的封装。
还是先写一下nohttp简单的使用代码。
nohttp的网络层有HttpURLConnection和OkHttp两种,可以根据自己的习惯和实际情况自由选择。用之前还是要先添加依赖和权限。(不知道为什么我在写例子的时候忘记添加权限,在模拟器上依然正常运行,弄得我很方。)
依赖:
如果使用HttpURLConnection作为网络层:
compile 'com.yanzhenjie.nohttp:nohttp:1.1.1'
如果要使用OkHttp作为网络层,请再依赖:
compile 'com.yanzhenjie.nohttp:okhttp:1.1.1'
权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
NoHttp初始化需要一个上下文,一般我们会自己写一个MyApplication类,让他继承Application。在onCreate()方法里对NoHttp进行初始化,这样只要项目一启动就完成了对NoHttp的初始化。初始化过程中创建的请求队列对象同样也使用了单例模式。
public class MyApplication extends Application {
//请求队列
private static RequestQueue mRequestQueue;
public static RequestQueue getmRequestQueue(){
return mRequestQueue;
}
@Override
public void onCreate() {
super.onCreate();
//默认初始化
// NoHttp.initialize(this);
//自定义初始化
NoHttp.initialize(this, new NoHttp.Config()
//设置网络层使用okhttp;如果不设置默认优先使用okhttp;
.setNetworkExecutor(new OkHttpNetworkExecutor())
//设置链接超时时间为10秒
.setConnectTimeout(10000));
mRequestQueue = NoHttp.newRequestQueue();
}
}
不能忘了还要在清单文件里设置我们自己的MyApplication
<application
android:name=".MyApplication"
···
初始化完成,我们在项目中使用网络请求时主要是请求服务器,返回json字符串,所以我就用String请求作为例子。
//访问的服务器地址
String url = "http://www.baidu.com";
//创建String请求;第一个参数是地址,第二个参数指定请求方法
Request<String> request = NoHttp.createStringRequest(url, RequestMethod.GET);
//创建请求队列
RequestQueue queue = MyApplication.getmRequestQueue();
//请求回调
OnResponseListener<String> callBack = new OnResponseListener<String>() {
//这些方法都运行在主线程中,可以直接更新界面,同时也意味着不能做耗时操作
@Override
public void onStart(int what) {
//发出请求时,开始执行的方法
}
@Override
public void onSucceed(int what, Response<String> response) {
//请求成功时执行的方法
}
@Override
public void onFailed(int what, Response<String> response) {
//请求失败时执行的方法
}
@Override
public void onFinish(int what) {
//请求结束时执行的方法
}
};
//将网络请求添加到请求队列中;第一个参数:请求的标识,标记是哪个请求;第二个参数:请求对象;第三个参数:回调对象
queue.add(0, request, callBack);
NoHttp的详细使用方法在github里介绍的更全面,我也就不过多累述。https://github.com/yanzhenjie/NoHttp
在实际项目中,我们会专门写一个NetUtils类来封装网络请求的代码。在请求服务器展示页面数据的时候,一般都会遇到“正在请求网络”、“无法链接到服务器”、“接受数据正常显示”、“接收到空数据”这4种网络状态。所以我就写一个StateView类,提供4种方法:showLoading()、 showError()、showEmpty()、showNormal(View view)分别显示这4种网络状态。
/*这个类会根据自己的需求写具体的代码,实现不同的功能。我只写了4个空方法。*/
public class StateView {
//正在请求网络
public void showLoading(){}
//无法链接到服务器
public void showError(){}
//接收到空数据
public void showEmpty(){}
//接受数据正常显示
public void showNormal(View view){}
}
这4个方法只有正常显示数据的方法会依据服务器返回的json字符串不同,展示不同的界面,其他三个方法展示的都是固定的内容。
public class NetUtils {
public static void callNet(String url, final StateView stateView){
final Request<String> request = NoHttp.createStringRequest(url, RequestMethod.GET);
RequestQueue queue = MyApplication.getmRequestQueue();
OnResponseListener<String> onResponseListener = new OnResponseListener<String>() {
@Override
public void onStart(int what) {
//请求开始,显示正在请求网络
stateView.showLoading();
}
@Override
public void onSucceed(int what, Response<String> response) {
//请求成功,对请求到的数据进行判断
String json = response.get();
if(TextUtils.isEmpty(json)){
//如果数据是空,显示接收到空数据
stateView.showEmpty();
}else{
//如果数据正常,我们需要将json串解析转换成View界面传给StateView的showNormal(View view);
//这时候我们就需要自己写一些方法来实现json到View的转换
stateView.showNormal(???);
}
}
@Override
public void onFailed(int what, Response<String> response) {
//请求失败,显示无法连接到服务器
stateView.showError();
}
@Override
public void onFinish(int what) {
//请求结束时什么都不显示
}
};
queue.add(0, request, onResponseListener);
}
}
不同的页面请求服务器返回的数据不同,展示的页面也不同。所以在请求成功以后执行的方法中,json转换成View的方法也不固定,需要在不同的页面写不同的方法。这时候我们可以自己定义一个CustomCallBack抽象类,让他实现OnResponseListener接口。
public abstract class CustomCallBack implements OnResponseListener<String> {
private StateView stateView;
public CustomCallBack(StateView stateView) {
this.stateView = stateView;
}
@Override
public void onStart(int what) {
stateView.showLoading();
}
@Override
public void onSucceed(int what, Response<String> response) {
String json = response.get();
if(TextUtils.isEmpty(json)){
stateView.showEmpty();
}else{
View view = getView(json);
stateView.showNormal(view);
}
}
@Override
public void onFailed(int what, Response<String> response) {
stateView.showError();
}
@Override
public void onFinish(int what) {
}
//服务器返回的json串转换成View的方法,可以在使用回调对象时自己实现这个方法
protected abstract View getView(String json);
}
现在只需要将我们自己写的回调作为NetUtils的callNet()方法的参数传进去就行了。
public class NetUtils {
public static void callNet(String url, CustomCallBack customCallBack){
Request<String> request = NoHttp.createStringRequest(url, RequestMethod.GET);
RequestQueue queue = MyApplication.getmRequestQueue();
queue.add(0, request, customCallBack);
}
}
最终在使用nohttp请求网络时就很简洁了。
String url = "http://www.baidu.com";
NetUtils.callNet(url, new CustomCallBack(new StateView()) {
@Override
protected View getView(String json) {
//这个方法根据自己的需要去重写
return null;
}
});
这个封装有一定的局限性,需要结合自己的需要加以修改,才能和自己的项目更好搭配。