初探Okhttp3+Retrofit2+RXJava
本人菜鸟一枚,涉及Android开发也只有区区两年的时间,联网操作从最初接触的httpClient到Xutils,因为后来Android6.0发布。使得联网操作有了很大的变化。Android 6.0发布之后,谷歌已经将所有旧版的HttpURLConnection,HttpClient,和一些和apache有关包的类和方法定义为过时方法,并且Android SDK 23之后不再内置旧版的类和接口,需要额外引用jar包,为了代码的健壮性也需要抛弃旧版Android的HTTP框架。
后来听说Okhttp3+Retrofit2+RXJava这个东西真的挺火的,所以找个时间,初步探索了一下这个框架,从网上找到了不少素材、资料、源码以及大神们的分享经验。不得不说,这个时代,网络真的很神奇,近乎无所不能。废话不多说,开始正经上代码。
Android studio 首先在gradle里添加引用,这里一共会添加7个包的引用
前两个包是rxjava所能够用到的,第三个是okhttp3的引用包,四五六这三个包是retrofit2的引用包,其中还包含了默认的gson解析,以方便使用,最后一个包是OKhttp3日志拦截引用包。
public abstract class RetrofitUtils {
//服务器路径
private static final String API_SERVER = Constants.URL.URL;
private static Retrofit mRetrofit;
private static OkHttpClient mOkHttpClient;
/**
* 获取Retrofit对象
*
* @return
*/
protected static Retrofit getRetrofit() {
if (null == mRetrofit) {
if (null == mOkHttpClient) {
mOkHttpClient = OkHttp3Utils.getOkHttpClient();
}
//Retrofit2后使用build设计模式
mRetrofit = new Retrofit.Builder()
//设置服务器路径
.baseUrl(API_SERVER + "/")
//添加转化库,默认是Gson
.addConverterFactory(GsonConverterFactory.create())
//添加回调库,采用RxJava
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//设置使用okhttp网络请求
.client(mOkHttpClient)
.build();
}
return mRetrofit;
}
}
从Retrofit升级到2.0之后,就使用了build设计模式(生产者模式),将一个复杂的构建与其表示相分离。
baseUrl(API_SERVER + “/”):设置服务器路径addConverterFactory(GsonConverterFactory.create()):添加转化库,默认是Gson
addCallAdapterFactory(RxJavaCallAdapterFactory.create()):添加回调库,采用RxJava
client(mOkHttpClient):设置使用okhttp网络请求
最后是设置okhttp为网络请求,okhttp是高性能的http库,拥有队列线程池,轻松解决并发,自动维护socket连接池,所以这里使用okhttp可谓是更上一层楼。
/**
* 获取OkHttpClient对象
*
* @return
*/
public static OkHttpClient getOkHttpClient() {
if (null == mOkHttpClient) {
//同样okhttp3后也使用build设计模式
mOkHttpClient = new OkHttpClient.Builder()
//设置一个自动管理cookies的管理器
.cookieJar(new CookiesManager())
//添加拦截器
//.addInterceptor(new MyIntercepter())
//添加网络连接器
//.addNetworkInterceptor(new CookiesInterceptor(MyApplication.getInstance().getApplicationContext()))
//设置请求读写的超时时间
.connectTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.cache(cache)
.build();
}
return mOkHttpClient;
}
同样升级到okhttp3后,也使用build设计模式。
cookieJar(new CookiesManager()): 设置一个自动管理cookies的管理器 addInterceptor(new MyIntercepter()):添加拦截器 addNetworkInterceptor(new CookiesInterceptor(MyApplication.getInstance().getApplicationContext())):添加网络连接器 connectTimeout(30, TimeUnit.SECONDS):请求超时时间 writeTimeout(30, TimeUnit.SECONDS):写入超时时间 readTimeout(30, TimeUnit.SECONDS):读取超时时间public interface NetService { /** * 常用的注解: * * @GET GET请求方式 * @POST POST请求方式 * @Query GET请求参数 * @Header 用来添加Header请求头 * @FormUrlEncoded post请求头标示 * <p> * 其他注解请求方式: * @PUT 表示这是一个PUT请求 * @DELETE 表示这是一个DELETE请求 * @HEAD 表示这是一个HEAD请求 * @OPTIONS 表示这是一个OPTION请求 * @PATCH 表示这是一个PAT请求 */ //设缓存有效期为1天 long CACHE_STALE_SEC = 60 * 60 * 24 * 1; //查询缓存的Cache-Control设置,使用缓存 String CACHE_CONTROL_CACHE = "only-if-cached, max-stale=" + CACHE_STALE_SEC; //查询网络的Cache-Control设置。不使用缓存 String CACHE_CONTROL_NETWORK = "max-age=0"; //POST请求 @FormUrlEncoded @POST("/a/login") Observable<Verification> getVerificationCodePost(@Field("__ajax") String __ajax, @Field("username") String username, @Field("password") String password, @Field("mobileLogin") String mobileLogin); //POST请求 @FormUrlEncoded @POST("/a/login") Observable<Verification> getVerificationCodePostMap(@FieldMap Map<String, String> map); //GET请求 @GET("/a/login") Observable<Verification> getVerificationGet(@Field("__ajax") String __ajax, @Field("username") String username, @Field("password") String password, @Field("mobileLogin") String mobileLogin); //GET请求,设置缓存 @Headers("Cache-Control: public," + CACHE_CONTROL_CACHE) @GET("/a/login") Observable<Verification> getVerificationGetCache(@Field("__ajax") String __ajax, @Field("username") String username, @Field("password") String password, @Field("mobileLogin") String mobileLogin); @Headers("Cache-Control: public," + CACHE_CONTROL_NETWORK) @GET("/a/login") Observable<MenuBean> getMainMenu(); }
将NetService写成一个单独的接口,里面包含的是各个不同联网接口的调用,post,get,put,head等等。这样可以方便后面调用工具类的调用。
public class NetWorks extends RetrofitUtils { private static final NetService service = getRetrofit().create(NetService.class); //POST请求 public static void verificationCodePost(String __ajax, String username, String password, String mobileLogin, Observer<Verification> observer) { setSubscribe(service.getVerificationCodePost(__ajax, username, password, mobileLogin), observer); } //POST请求参数以map传入 public static void verificationCodePostMap(Map<String, String> map, Observer<Verification> observer) { setSubscribe(service.getVerificationCodePostMap(map), observer); } //Get请求设置缓存 public static void verificationCodeGetCache(String __ajax, String username, String password, String mobileLogin, Observer<Verification> observer) { setSubscribe(service.getVerificationGetCache(__ajax, username, password, mobileLogin), observer); } //Get请求 public static void verificationCodeGet(String __ajax, String username, String password, String mobileLogin, Observer<Verification> observer) { setSubscribe(service.getVerificationGet(__ajax, username, password, mobileLogin), observer); } //Get请求 public static void verificationCodeGetsub(String __ajax, String username, String password, String mobileLogin, Observer<Verification> observer) { setSubscribe(service.getVerificationGet(__ajax, username, password, mobileLogin), observer); } //Get请求 public static void GetCache(Observer<MenuBean> observer) { setSubscribe(service.getMainMenu(), observer); } /** * 插入观察者 * * @param observable * @param observer * @param <T> */ private static <T> void setSubscribe(Observable<T> observable, Observer<T> observer) { observable.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.newThread())//子线程访问网络 .observeOn(AndroidSchedulers.mainThread())//回调到主线程 .subscribe(observer); } }
setSubscribe方法其实就是插入观察者。通过NetWorks来进行接口NetService的调用。下面就是最后一步了,一起来看看吧。
这样在Activity中引用也是很方便的,直接调用就可以了,只需要把参数还有观察者罗列一下或者是把map和观察者传递到方法里面就可以直接调用了。成功会返回你所需要的bean对象,如果是失败了,会返回对应的错误信息,像404,405,等有机会试一下403,本人公司项目经常会出现403的问题。public class MainActivity extends AppCompatActivity { private TextView mTv, mTv2, mTv3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTv = (TextView) findViewById(R.id.main_tv); mTv2 = (TextView) findViewById(R.id.main_tv2); mTv3 = (TextView) findViewById(R.id.main_tv3); NetWorks.verificationCodePost("true", "xinshuju01", "111111", "true", new Observer<Verification>() { @Override public void onCompleted() { //完成 } @Override public void onError(Throwable e) { //异常 mTv.setText(e.getLocalizedMessage()); Log.e("MAIN2", e.getLocalizedMessage() + "--" + e.getMessage()); } @Override public void onNext(Verification verification) { //成功 mTv.setText(verification.getUser().toString()); } }); Map<String, String> map = new HashMap<>(); map.put("__ajax", "true"); map.put("username", "xinshuju01"); map.put("password", "111111"); map.put("mobileLogin", "true"); NetWorks.verificationCodePostMap(map, new Observer<Verification>() { @Override public void onCompleted() { //完成 } @Override public void onError(Throwable e) { //异常 mTv2.setText(e.getLocalizedMessage()); Log.e("MAIN2", e.getLocalizedMessage() + "--" + e.getMessage()); } @Override public void onNext(Verification verification) { //成功 mTv2.setText(verification.getUser().toString()); } }); NetWorks.GetCache(new Observer<MenuBean>() { @Override public void onCompleted() { //完成 } @Override public void onError(Throwable e) { //异常 mTv3.setText(e.getLocalizedMessage()); Log.e("MAIN2", e.getLocalizedMessage() + "--" + e.getMessage()); } @Override public void onNext(MenuBean baseBean) { //成功 mTv3.setText(baseBean.toString()); } }); } }
主要还是感谢大神。参考博客:http://blog.csdn.net/wlt111111/article/details/51455524。
如果有什么好的意见,建议或者我有什么bug,欢迎评论联系。