簡單實用的mvp+retrofit+rxjava+dagger2
阿新 • • 發佈:2019-01-04
如今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<NewsEntity> getNewsData(@QueryMap Map<String, String> 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層的程式碼,這層就是提供類物件方法的容器
@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入門教學