如今android最为流行的网络请求框架莫过于retrofit+rxjava,网上也是诞生了大量mvp+retrofit+rxjava的相关技术文章,但他们的要么太过于复杂要么针对性太强,让很多人用到一半就放弃了,本人也是初学者,参考了很多技术牛人写的例子,大家一起交流学习,下面是一个模拟获取新闻数据的例子,不多bb。
项目结构图
dagger2的包和mvp的包
RequestObservable类中单例接口容器和自定义okhttp
/**
* 自定义okhttpclient
*/
private static OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.build();
// .addInterceptor(interceptor)
// .cache(cache).build();
public static Converter.Factory gsonConverterFactory = GsonConverterFactory.create();
public static CallAdapter.Factory rxJavaCallAdapterFactory = RxJavaCallAdapterFactory.create();
/**
* 获得接口的容器 注意baseUrl要以“/”结尾
* @param
* @return
*/
public static Api getApi() {
if (retrofit == null) {
synchronized (Retrofit.class) {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.client(okHttpClient)
.baseUrl("http://apis.guokr.com/handpick/")
.addConverterFactory(gsonConverterFactory)
.addCallAdapterFactory(rxJavaCallAdapterFactory)
.build();
}
}
}
api = retrofit.create(Api.class);
return api;
}
统一请求地址存放的接口
public interface Api {
//http://apis.guokr.com/handpick/article.json?retrieve_type=by_since&category=all&limit=3&ad=1
@GET("article.json")
Observable getNewsData(@QueryMap Map map);
}
网络请求的公共方法,自己做了接口回调,retrofit+rxjava的回调用着很不习惯:
package com.dianzhi.bookdemo.http;
import rx.Observable;
import rx.Observer;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
/**
* Created by CK on 2017/2/17.
*/
public class Network {
/**
* get请求
*
* @param observable
* @param backListener
*/
public static Subscription get(Observable observable, CallBackListener backListener) {
return observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getObserve(backListener));
}
/**
* 构造observer
*
* @param backListener
* @return
*/
private static Observer getObserve(final CallBackListener backListener) {
Observer observer = new Observer() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
if (backListener != null) {
backListener.onError(e.getMessage());
backListener.onFinish();
}
}
@Override
public void onNext(Object o) {
if (backListener != null) {
backListener.onSuccess(o);
backListener.onFinish();
}
}
};
return observer;
}
}
mvp的代码就不贴了,到时放出地址,再来看看dagger2的简单运用,代码里注释非常详细:
Component层的代码
@Component(modules = NewsModule.class)
public interface NewsCompoent {
//定义注入的目标"地点"
void inject(MainActivity activity);
}
再来看MainActivity界面里做了什么,结合上面的代码可以看出@Inject这个的目的是在在MainActivity获取NewsPresenter类的实例,拿到实例后就可以做各种事务操作了。
public class MainActivity extends BaseActivity implements NewsContract.View{
@Inject
NewsPresenter newsPresenter;//dagger2注解获取newspresenter的对象,怎么获取呢?上面的@Component里提到的NewsModule去看看
@BindView(R.id.title)
TextView tv;
@BindView(R.id.iv)
ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main,true);
ButterKnife.bind(this);
setInjectotor();
}
@OnClick(R.id.btn)
public void get(View view) {
newsPresenter.refreshData();
}
private void setInjectotor() {
//固定写法表示要注入的是当前的MainActivity,与NewsModule相关联
DaggerNewsCompoent.builder().newsModule(new NewsModule(this)).build().inject(this);
} }
@Module
public class NewsModule {
private NewsContract.View view;
public NewsModule(NewsContract.View view) {
this.view = view;
}
@Provides
NewsContract.View provide() {
return this.view;
}
//前面提到MainActivity需要一个NewsPresenter的对象,dagger2会先在NewsModule里找有没有一个可以提供NewsPresenter对象的方法,
// 结果下面这个方法返回的是NewsContract.Presenter并不是,这个是NewsPresenter
的契约父类(注意参数和返回值不能一样不然会进入死循环,自己找自己引起),但是该方法参数传了NewsPresenter对象过来,直接去找NewsPresenter的构造方法
@Provides
NewsContract.Presenter provideNewsPresenter(NewsPresenter newsPresenter) {
return newsPresenter;
}
}
NewsPresenter层代码
public class NewsPresenter implements NewsContract.Presenter{
private NewsContract.View view;
//@Inject表示构造方法会提供NewsPresenter对象,但是需要一个view,上面的NewsModule容器里的provide()方法已经提供,这时p层和v层就关联在一起
@Inject
public NewsPresenter(NewsContract.View view) {
this.view=view;
}}
如果对dagger2不适合很了解可以看下这边文章最简单的Dagger2入门教学
最后是整个地址mvp+retrofit+rxjava+dagger2