为了进一步了解Retrofit,Rxjava。之前的简单学习了Retrofit,Rxjava简单使用
请教了一下坐在 右边的国华前辈
他介绍了rxjava,retrofit封装这篇博文给我,我就依葫芦画瓢的对今天写的代码进行一个简单封装(其实中间还是有很多不懂,不过我还是先把东西跑起来)
之所以叫乞丐封装。。因为是这篇博文的低配版本,因为主要目的是为了加强自己的理解很多东西都省略了
首先定义一个ServiceFactory
先上源代码点击打开链接
package com.example.zhaoyulu_sx_test.test; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import java.io.File; import java.lang.reflect.Field; import java.util.concurrent.TimeUnit; import okhttp3.Cache; import okhttp3.OkHttpClient; import retrofit2.Retrofit; import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; /** * Created by zhaoyulu_sx on 2017/7/28. */ public class ServiceFactory { private final Gson mGsonDateFormat; private ServiceFactory() { mGsonDateFormat = new GsonBuilder() .setDateFormat("yyyy-MM-dd hh:mm:ss") .create(); } private static class SingletonHolder { private static final ServiceFactory INSTANCE = new ServiceFactory(); } public static ServiceFactory getInstance() { return SingletonHolder.INSTANCE; } /** * create a service * * @param serviceClass * @param <S> * @return */ public <S> S createService(Class<S> serviceClass) { String baseUrl = ""; try { Field field1 = serviceClass.getField("BASE_URL"); baseUrl = (String) field1.get(serviceClass); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.getMessage(); e.printStackTrace(); } Retrofit retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .addConverterFactory(GsonConverterFactory.create(mGsonDateFormat)) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); return retrofit.create(serviceClass); } }
createService这个方法主要用到了反射的方法获得BASE_URL。。好吧对于反射,这是我第一次写到代码里。对其理解还十分模糊,不过历史的车轮不能停在这里
上面代码中的Field field1 = serviceClass.getField("BASE_URL");这句话中,serviceClass里需要增加一个BASE_URL
String BASE_URL = "https://api.douban.com/v2/"; @GET("book/search") Observable<Book> getSearchBook(@Query("q") String name, @Query("tag") String tag, @Query("start") int start, @Query("count") int count);这样之后本来需要
retrofit = new Retrofit.Builder() .baseUrl("https://api.douban.com/v2/") .addConverterFactory(GsonConverterFactory.create(new GsonBuilder().create())) .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//支持RxJava .build(); service = retrofit.create(RetrofitService.class);这么写的,先走就变成了
service = ServiceFactory.getInstance() .createService(RetrofitService.class)惊不惊喜意不意外。。好吧其实其中原理我也不是十分懂,反正先这么写着
另外原来代码中的
Observable<Book> observable = service.getSearchBook("金瓶梅", null, 0, 1); observable.subscribeOn(Schedulers.io()). observeOn(AndroidSchedulers.mainThread()). subscribe(new Observer<Book>() { @Override public void onCompleted () { } @Override public void onError (Throwable e){ } @Override public void onNext (Book book){ text_tv.setText(book.getCount() + ""); } });
这个部分重复率也十分高,比如那个onError处理就没有必要每次都写相同的部分,可以将他封装起来,首先定义一个抽象类HttpResultSubscriber
package com.example.zhaoyulu_sx_test.test; import rx.Subscriber; /** * Created by zhaoyulu_sx on 2017/7/28. */ public abstract class HttpResultSubscriber<T> extends Subscriber<T> { @Override public void onCompleted() { } @Override public void onNext(T t) { onSuccess(t); } public abstract void onSuccess(T t); }
经过上面两轮的准备,先走的网络请求就可以精简在其一
ServiceFactory.getInstance() .createService(RetrofitService.class) .getSearchBook("金瓶梅", null, 0, 1) .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .subscribe(new HttpResultSubscriber<Book>() { @Override public void onSuccess(Book book) { text_tv.setText(book.getCount()+""); } @Override public void onError(Throwable e) { text_tv.setText(e.toString()); } });上面这一句话,就可以实现原先代码的网络请求了
此外对于Subscriber<T>中的T还可以兴建 一个泛型,例如
public class HttpResult<T> { public int count; public int start; public int total; public T books; }来处理公共部分