我在前面的博文介绍了Retrofit,这里我拿我在公司独立开发应用使用okhttp封装与retrofit做下比较,你立马就会明白Retrofit的优势了,所以这里不会对okhttp做大篇幅介绍
okhttp基本使用post get请求,okhttp也是有异步和同步请求 ,这里要注意了,okhttp的异步请求和volley不一样,volley的请求成功回调是直接运行在主线程中的,所以我在okhttp中要将返回运行在主线程中,其次成功失败的回调都要运行在主线程,所以要定义接口回调来实现!
我的封装如下 ,以后建议大家都开始使用Retrofit,下面代码已经精简删掉异常捕获等代码,力求简单易懂
定义网络请求基类BaseHttp 定义一个回调接口 ,如果我们做get请求,封装如下,我就直接上代码了,因为返回数据的bean是不一样的所以我使用泛型
public void getRequest(String param,final CallBackData calldata) throws HttpException { //判断是否有网路,有网络才去进行请求,无网络就要跑出自定义异常 if(BaseApplication.getInstance().isNetConnected) { this.calldata = calldata; String url = httpInterface()+param;//完整请求链接 Log.e("URL",url); OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url(url).build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { if (calldata != null) { Message obtain = Message.obtain(); obtain.what = ERROR; obtain.obj=e; handler.sendMessage(obtain); } } @Override public void onResponse(Call call, Response response) throws IOException { //如果访问成功 if (response.isSuccessful()) { String string = null; try { string = response.body().string(); Log.e("data",string); } catch (IOException e) { e.printStackTrace(); Message obtain = Message.obtain(); obtain.what = ERROR; obtain.obj=e; handler.sendMessage(obtain); } T t = parseJson(string); if (calldata != null) { Message obtain = Message.obtain(); obtain.what = SUCCESS; obtain.obj = t; handler.sendMessage(obtain); } } } }); }else { throw new HttpException("暂无网络"); } }
handler中的处理
Handler handler=new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case SUCCESS: calldata.onResponse((T) msg.obj); break; case ERROR: calldata.onError((Exception) msg.obj); // Log.e("网络异常",((Exception) msg.obj).getMessage()); break; } } };
可以发现 路径地址 和 解析后的bean类型是由方法代替,这两个是我定义的抽象方法,是为了让子类实现
子类复写httpInterface() 返回请求的url地址
子类复写parseJson()对请求回来额Gson数据解析返回bean,为了通用使用了泛型
post请求与上面的方法类似 ,定义一个post请求方法里面由okhttp进行post请求,这里不做多介绍
使用方法
1 可以直接new匿名内部类BaseHttp的子类然后调用 getRequest请求方法,传入地址参数以及一个接口,接口的实现就做你要做的操作(这些操作已经被我用handler放到主线程了)
2 上面的方法1写起来不美观而且代码臃肿,我是用的方法是创建一个子类继承BaseHttp直接复写两个方法,然后直接new子类对象调用getRequest进行请求,如下
public class GetAllDefectType extends BaseHttp<ArrayList<DefectTypeInfo>>{//使用泛型 @Override public String httpInterface() { return HttpUrlConstant.GET_DAMAGE_TYPE;//此方法用来返回请求地址 } @Override//此方法对Gson数据进行解析,返回bean public ArrayList<DefectTypeInfo> parseJson(String data) {//使用了泛型更加通用 return new Gson().fromJson(data,new TypeToken<ArrayList<DefectTypeInfo>>(){}.getType()); } }使用时只需要如下即可是不是看起来很简单,跟前面的Retrofit差不多,Retrofit只要静态调用一个方法传入参数即可在回调中处理事件了!
而我封装的okhttp只要创建子类对象调用方法传入参数也可以在回调中处理事件了?
GetAllDefectType getAllDefectType=new GetAllDefectType(); getAllDefectType.getRequest("", new BaseHttp.CallBackData<ArrayList<DefectTypeInfo>>() { @Override public void onError(Exception e) { Toast.makeText(mContext,"网络异常,请退出",Toast.LENGTH_SHORT).show(); } @Override public void onResponse(ArrayList<DefectTypeInfo> defectTypeInfos) { //在这里做数据返回你想操作的事 }); }
二者使用上好像并无不同,各位肯定会怀疑的问我,你已经封装的这么好了,为什么还说Retrofit好?
我现在为大家比较异同点,大家看好了
1 我上面只是使用了get请求,如果是post请求 上传文件等操作,就必须在写几个方法到基类中去,而Retrofit只需要根据注解的不同就可以进行不同的请求@get @post
2 我每次进行请求都必须创建一个类,在这个类中定义了请求地址,返回类型,调用的方法决定了请求方式,而Retrofit只需要在接口中定义这么一句话
@GET("android/{version}")
Call<VersionBean> loadVersionInfo(@Path("version") String version);
这句话直接就定义了请求方式 数据返回类型 请求路径,一个请求一个方法就表达的完美了,而我需要去新建一个类去表达,而在安卓性能优化中是不建议定义大量的类(性能优化内存优化我以后会说)
3 Retrofit帮我们封装好了,我们简单的做一次包装就可以使用(详见前面博文),okhttp我们要做大量封装接口回调handler调用等等
现在明白Retrofit的优势了吧,Retrofit除此之外还可以将回调对象传入rxjava,让rxjava去处理结果,是不是超赞?