首先分别对RxJava和Retrofit做一个简单的讲解,让大家有一个初步的印象。
RxJava的最大作用就是异步操作,在很多时候我们需要在不同的线程中来进行操作,最明显的就是加载网络数据然后刷新界面。因为访问网络是耗时的操作,相信大家都回知道要放在子线程里面去做,刷新界面就肯定在主线程里面操作了,这个已经是简单到不能再简单的了。很多人可能会用AsyncTask和Handler和操作,这是完全没有问题的,只是用过的朋友都会知道它只能是一个程序块的执行,在AsyncTask执行完以后又要把块数据传递给handler再去处理,这样,当你过了一段时间再去看你的代码的时候你就会发现修改起来真的是麻烦至极而且是头疼。而ReJava的执行是链式的执行操作,它把任务的执行按照链式的模式来处理,使用的是观察者模式,待会下面再讲。不仅如此,它还可以按需的指定任务执行的线程,这个真的是屌屌的。想详细的对ReJava进行学习的同学可以去看看这位大神的文章:http://gank.io/post/560e15be2dca930e00da1083
ReJava采用的是观察者模式,看一个简单的例子:Button执行监听事件setOnclickListener(OnclickListener)后会执行onclick() 方法,ReJava模式中的观察者模式其实跟这个差不多,Observable是被观察者,Observer或者是Subscriber是观察者,他们通过subscrib()来进行订阅:Observable.subscrib(Subscriber)。Subscriber会处理Observable触发的事件。先看看ReJava的代码模式
Observable.create(new Observable.OnSubscribe<Drawable>() { @Override public void call(Subscriber<? super Drawable> subscriber) { Drawable drawable=getResources().getDrawable(drawableRes); subscriber.onNext(drawable); subscriber.onCompleted(); } }).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<Drawable>() { @Override public void onCompleted() { Intent intent = new Intent(TwoActivity.this, ThreeActivity.class); startActivity(intent); finish(); } @Override public void onError(Throwable e) { } @Override public void onNext(Drawable drawable) { img_view.setImageDrawable(drawable); } });
ReJava的使用这里我们选择是关联远程库的模式:
compile 'io.reactivex:rxjava:1.0.14' compile 'io.reactivex:rxandroid:1.0.1'
Retrofit其实就是一个网络数据加载的库,在这里附上github的地址,大家可以先去看看http://square.github.io/retrofit/
Retrofit的使用有两种方法,详细看下面的图片,图片来源Retrofit官网。
下面将以一个小例子的形式演示它们的使用。
第一步:我们先要把需要的技术点罗列出来。
A:实现不同activity和framgent之间通讯的框架,这里我们用Eventbus
B:ReJava的远程库》
compile 'io.reactivex:rxjava:1.0.14'
compile 'io.reactivex:rxandroid:1.0.1'C:Retrofit的关联远程库》compile 'com.squareup.retrofit2:retrofit:2.0.0'
D:因为Retrofit内部会自动转换为我们需要的bean,所以还需要转换gson库》compile 'com.squareup.retrofit2:converter-gson:2.0.0'
E:因为是ReJava和Retrofit配套使用,当网络请求完毕以Rejava的形式返回数据,没有这个的话会报错》compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0'
F:涉及到网络请求,http肯定就少不了了》compile 'com.squareup.okhttp3:okhttp:3.2.0'
G:图片的加载库》第二步:创建网络接口compile 'com.github.bumptech.glide:glide:3.7.0'
H:注解类》
compile 'com.jakewharton:butterknife:7.0.1'
compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'
/** * Created by AHuan 2016/8/12 0012. */ public interface LoginApi { /* //第一种方法 @POST("member/login") Call<LoginBean> loginIn(@Body RequestBody body);*/ //第二种方法 @POST("member/login") Observable<LoginBean> loginIn(@Body RequestBody body); }/** * Created by AHuan on 2016/8/15 0015. */ public interface HealthRecordApi { @GET("health") Observable<HealthRecordBean> getHealthRecord(@Query("member_id") String member_id,@Query("page") String page,@Query("number") String number); }第三步:创建网络请求第四步:创建Activity/** * Created by AHuan on 2016/8/12 0012. */ public class NetWork { private static LoginApi loginApi; private static HealthRecordApi healthRecordApi; private static OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor(new BaseParamsInterceptor()).build(); private static Converter.Factory gsonConverterFactory = GsonConverterFactory.create(); private static CallAdapter.Factory rxJavaCallAdapterFactory = RxJavaCallAdapterFactory.create(); public static LoginApi getLoginApi(){ if(loginApi==null){ Retrofit retrofit= new Retrofit.Builder() .client(okHttpClient) .baseUrl("http://120.24.65.96/api/") .addConverterFactory(gsonConverterFactory) .addCallAdapterFactory(rxJavaCallAdapterFactory)//这一行是RxJava的转换器,如果api回调的不是Observable<LoginBean>被观察者,那么这一行可以注释 .build(); loginApi=retrofit.create(LoginApi.class); } return loginApi; } public static HealthRecordApi getHealthRecordApi(){ if(healthRecordApi==null){ Retrofit retrofit= new Retrofit.Builder() .client(okHttpClient) .baseUrl("http://120.24.65.96/api/") .addConverterFactory(gsonConverterFactory) .addCallAdapterFactory(rxJavaCallAdapterFactory)//这一行是RxJava的转换器,如果api回调的不是Observable<LoginBean>被观察者,那么这一行可以注释 .build(); healthRecordApi=retrofit.create(HealthRecordApi.class); } return healthRecordApi; } /** * 创建拦截器*///这里用于在HTTP头部添加一些拦截信息,例如token和IMEI码之类的 public static class BaseParamsInterceptor implements Interceptor{ @Override public Response intercept(Chain chain) throws IOException { Request.Builder requestBuilder=chain.request().newBuilder(); Iterator iterator = UIUtil.getHeaderMap().entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = (Map.Entry) iterator.next(); requestBuilder.addHeader((String) entry.getKey(), (String) entry.getValue()); } return chain.proceed(requestBuilder.build()); } } }public class ThreeActivity extends ActionBarActivity { RequestBody body = null; @Bind(R.id.btn_login) Button btn_login; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_three); ButterKnife.bind(this); Map<String, String> mapValuse = new HashMap<>(); mapValuse.put("login_id", "150881"); mapValuse.put("password", "123456"); mapValuse.put("login_type", "mobile"); mapValuse.put("device_id", UIUtil.getIMEI(UIUtil.getContext())); mapValuse.put("oauth_from", ""); mapValuse.put("oauth_uid", ""); mapValuse.put("access_token", ""); body= RequestBodyUtil.getBody(mapValuse); } @OnClick(R.id.btn_login) void login(){ /* //第一种方法 Call<LoginBean> call=loginApi.loginIn(body); call.enqueue(new Callback<LoginBean>() { @Override public void onResponse(Call<LoginBean> call, Response<LoginBean> response) { Log.e("huan",response.body().options.city); } @Override public void onFailure(Call<LoginBean> call, Throwable t) { Log.e("huan",t.toString()); } });*/ //第二种方法 loginApi.loginIn(body).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<LoginBean>() { @Override public void onCompleted() { // Intent intent = new Intent(ThreeActivity.this, FourActivity.class); Intent intent = new Intent(ThreeActivity.this, FiveActivity.class); startActivity(intent); finish(); } @Override public void onError(Throwable e) { } @Override public void onNext(LoginBean loginBean) { BaseRequestUtil.saveToken(UIUtil.getContext(), loginBean.options.token); BaseRequestUtil.saveMemberId(UIUtil.getContext(), loginBean.options.username); } }); } }第五步:辅助类public class RequestBodyUtil { public static final MediaType mMEDIA_TYPE = MediaType.parse("application/json;charset=utf-8"); public static RequestBody getBody(Map<String, String> valueMap){ RequestBody body=null; String requestJson= UIUtil.convertRequest(valueMap); if(requestJson!=null){ body = RequestBody.create(mMEDIA_TYPE, requestJson); } return body; } }//将hashMap转为字符串 public static String convertRequest(Map<String, String> valueMap) { String jsonString; try { JSONObject json = new JSONObject(); for (String key : valueMap.keySet()) { json.put(key, valueMap.get(key)); } jsonString = json.toString().trim(); } catch (JSONException e) { e.printStackTrace(); jsonString = ""; } return jsonString; }//获取会话token和IMEI码 public static Map<String, String> getHeaderMap() { Map<String, String> headerMap = new HashMap<>(); String token = BaseRequestUtil.getToken(getContext()); headerMap.put(BaseRequestUtil.REQUEST_TOKEN_PARAMS, token); String imei = UIUtil.getIMEI(getContext()); headerMap.put(BaseRequestUtil.REQUEST_DEVICE_ID, imei); return headerMap; }/** * 获取imei */ public static String getIMEI(Context context) { TelephonyManager tm = (TelephonyManager) context.getSystemService(Context .TELEPHONY_SERVICE); return tm.getDeviceId(); }