Android Dev@IT·互联网程序员

Android里常用的nohttp的简单封装

2017-04-10  本文已影响975人  helloworld走天下

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

这个封装有一定的局限性,需要结合自己的需要加以修改,才能和自己的项目更好搭配。

上一篇下一篇

猜你喜欢

热点阅读