MVP+RxJava+Retrofit2+Dagger2

1、深入浅出RxJava(一:基础篇) - 大头鬼Bruce - 博客频道 - CSDN.NET

2、RxJava教程

3、RxJava的Demo

4、Rxjava-Android资料汇总(里面有一些推荐的相关跳转网址,很有用的)

5、给 Android 开发者的 RxJava 详解(这个呢,是很多人推荐的,我是第一次看,没懂,看了别的后,回看,懂了一部分,再次回看,基本明白)

6、老罗的Android视频第二季里的其中一个,RxJava(百度搜一下,有地方下的,我那个网址链接找不到了,抱歉)

7、Retrofit官网(纯英文,当时我完全看不懂,也没足够的时间猜词,哈哈哈哈)

8、快速Android开发系列网络篇之Retrofit

9、Retrofit的使用教程(一)

10、android retrofit视频(Retrofit的视频蛮多的,比较好找,建议网上看视频学习学习基本的)

11、Android MVP 详解(上)

12、Android App的设计架构:MVC,MVP,MVVM与架构经验谈

13、ANDROID MVP 模式 简单易懂的介绍方式

14、详解Dagger2(注解框架)

15、聊聊 Android 中的依赖注入 - 安卓 - 伯乐在线

16、Dagger——Android上的依赖注入框架

17、Dagger2图文完全教程

18、最简单的Dagger2入门教程

19、Dagger2

20、Dagger2相关网址

21、Dagger2 这次入门就不用放弃了 - _王剑锋 - 博客频道 - CSDN.NET

22、Google官方架构MVP解析与实战 - OPEN 开发经验库

23、Google 官方架构 MVP+Dagger2 架构详解 - 掘金

24、Google官方MVP下载(包括+RxJava和+Dagger2de1)

25、Google官方MVP+Dagger2架构详解【从零开始搭建android框架系列(6)】(这位作者另一篇文章对MVP的理解写的也很棒,你可以找一下,系列里的其他几个)

好了,归于正题,我现在要开始讲了。我做的就是一个上拉加载,下拉刷新的recyclerview的加载数据和点击跳转详情页面的例子。


首先看一下文件目录。

xyrecyclerview包是直接import Module进来的,不用手写。

adapter包,就放了xyrecyclerview的adapter,加载器

api包是服务访问,里面是Retrofit2写的。

bean包是新闻信息的实例类,你在模仿时,直接copy就好了

shownewdetail包新闻细节显示页面(包括了Dagger2、MVP、RxJava的使用)

shownewslist包新闻列表显示页面(包括了Dagger2、MVP、RxJava的使用)

utils包一个功能包,就是webView的一些数据处理的,不用管,直接copy。

其他几个class文件后面一一讲解。



如下讲解,全是个人理解,错了别打我。


首先,要新建一个class,用来继承Application,我的是MyApplication。里面有ApplicationComponent applicationComponent。我讲解一下,代码的写的顺序。

[java]  view plain  copy
  1. package zjl.com.dagger_mvp_rxjava_demo2;  
  2.   
  3. import android.app.Application;  
  4. import android.content.Context;  
  5.   
  6. /** 
  7.  * Created by dell on 2016/8/31. 
  8.  */  
  9. public class MyApplication extends Application {  
  10.   
  11.     private ApplicationComponent applicationComponent;  
  12.   
  13.     public static MyApplication get(Context context){  
  14.         return (MyApplication) context.getApplicationContext();  
  15.     }  
  16.   
  17.     @Override  
  18.     public void onCreate() {  
  19.         super.onCreate();  
  20.         setGraph();  
  21.     }  
  22.   
  23.     private void setGraph() {  
  24.         applicationComponent = DaggerApplicationComponent.builder().applicationModule(new ApplicationModule(this)).build();  
  25.         applicationComponent.inject(this);//现在没有需要在MyApplication注入的对象,所以这句代码可写可不写  
  26.     }  
  27.   
  28.     public ApplicationComponent component(){return applicationComponent;}  
  29. }  
写的顺序是什么呢,先是继承Application,然后,我要重写onCreate()方法,自定义个方法,setGraph()。用来添加注入器。为什么我要写这个MyApplication呢。因为啊,我是需要某些变量啊、获取几个服务啊,等等的。这些我是在想通过Dagger2来实现简化的想法上,所准备添加的。(我试过,不写,也没关系)。

为了说明效果,我写了给注入器Component用的,注入类ApplicationModule,用来提供Context。

[java]  view plain  copy
  1. package zjl.com.dagger_mvp_rxjava_demo2;  
  2.   
  3. import android.content.Context;  
  4.   
  5. import dagger.Module;  
  6. import dagger.Provides;  
  7.   
  8. /** 
  9.  * Created by dell on 2016/8/31. 
  10.  */  
  11. @Module  
  12. public class ApplicationModule {  
  13.     private Context context;  
  14.     public ApplicationModule(Context context){  
  15.         this.context = context;  
  16.     }  
  17.   
  18.     @Provides  
  19.     public Context provideContext(){  
  20.         return context;  
  21.     }  
  22. }  
@Module符号是给Component识别用的,让他找得到。我想提供一个Context对象用(最终目的是为了new 一个Context对象出来嘛),所以就是@Provides下面这段代码,return一个Context对象,这个对象值怎么来,ApplicationModule的构造方法里获取。@Provides是一个识别的符号,告诉别人,用下面的这个方法提供某类对象。

再写一个ApplicationComponent,即注入器。是一个工具。

[java]  view plain  copy
  1. package zjl.com.dagger_mvp_rxjava_demo2;  
  2.   
  3. import dagger.Component;  
  4.   
  5. /** 
  6.  * Created by dell on 2016/8/31. 
  7.  */  
  8. @Component(modules = {ApplicationModule.class})  
  9. public interface ApplicationComponent {  
  10.   
  11.     void inject(MyApplication myApplication);  
  12. }  
@Component(modules = {ApplicationModule.class})表示如在MyApplicationzhon中我需要一个Context对象时,可以通过ApplicationComponent的@Component里的某个class中,找到某个@Provides提供相应需要的对象。
[java]  view plain  copy
  1. void inject(MyApplication myApplication);  
是表示我要提供给谁。比如说:我买本书,Modules是书,Component是卖书的人,@Inject的对象是我。书通过卖书的人的手,到我的手上。回过去看MyApplication,通过DaggerApplicationComponent.builder().applicationModule(new ApplicationModule(this)).build()获取Component对象,并用inject(this)注入。如果以后需要用到某个类对象,就可以通过Application获得。component()方法,就是调用该ApplicationComponent对象。以后会说到,哪里被用到。

然后,是以MVP的框架来写的。那么写个BaseView、BasePresenter、BaseActivity作为基类,用于写具体的类里必定会调用的方法。

BaseView

[java]  view plain  copy
  1. <span style="font-size:10px;">package zjl.com.dagger_mvp_rxjava_demo2;  
  2.   
  3. /** 
  4.  * Created by dell on 2016/8/26. 
  5.  */  
  6. public interface BaseView {  
  7.   
  8.   
  9. }</span><span style="font-size:12px;font-weight: bold;">  
  10. </span>  

因为我的Demo没有需要的必定会用的方法,所以不用写。

BasePresenter

[java]  view plain  copy
  1. <span style="font-size:12px;">package zjl.com.dagger_mvp_rxjava_demo2;  
  2.   
  3. import android.support.annotation.NonNull;  
  4.   
  5. /** 
  6.  * Created by dell on 2016/8/26. 
  7.  */  
  8. public interface BasePresenter<T extends  BaseView> {  
  9.     //绑定view,这个方法将会在activity中调用  
  10.     void attachView(@NonNull T view);  
  11.     //解绑  
  12.     void detachView();  
  13. }<strong>  
  14. </strong></span>  
用于绑定的,防止内存泄漏哦。

BaseActivity

[java]  view plain  copy
  1. <span style="font-size:12px;">package zjl.com.dagger_mvp_rxjava_demo2;  
  2.   
  3.   
  4. import android.os.Bundle;  
  5. import android.support.annotation.Nullable;  
  6. import android.support.v7.app.AppCompatActivity;  
  7.   
  8. /** 
  9.  * Created by dell on 2016/8/26. 
  10.  */  
  11. public abstract class BaseActivity extends AppCompatActivity {  
  12.   
  13.     @Override  
  14.     protected void onCreate(@Nullable Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         setContentView(initContentView());  
  17.         setupComponent((ApplicationComponent) MyApplication.get(this).component());  
  18.         initUi();  
  19.         initDatas();  
  20.         initListener();  
  21.         onclick();  
  22.     }  
  23.   
  24.     protected abstract void initUi();  
  25.   
  26.     protected abstract void initDatas();  
  27.   
  28.     protected abstract void initListener();  
  29.   
  30.     protected abstract void onclick();  
  31.   
  32.     protected abstract void setupComponent(ApplicationComponent component);//Dagger2绑定  
  33.   
  34.     public abstract int initContentView();  
  35.   
  36. }</span><strong style="font-size:12px;">  
  37. </strong>  
写了一些抽象方法,系统一点。


下面开始重点区域部分。


api包,里就两个文件,ApiManagerService里用于写接口,ApiManager实现接口的调用。

来看代码:

先看ApiManagerService

[html]  view plain  copy
  1. package zjl.com.dagger_mvp_rxjava_demo2.api;  
  2.   
  3.   
  4.   
  5. /**  
  6.  * Created by dell on 2016/8/10.  
  7.  */  
  8.   
  9. import retrofit2.http.GET;  
  10. import retrofit2.http.Path;  
  11. import rx.Observable;  
  12. import zjl.com.dagger_mvp_rxjava_demo2.bean.NewsDetail;  
  13. import zjl.com.dagger_mvp_rxjava_demo2.bean.NewsList;  
  14.   
  15. /**  
  16.  * @className:ApiManagerService  
  17.  * Created by lidong on 2016/3/2.  
  18.  */  
  19. public interface ApiManagerService {  
  20.     @GET("stories/latest")  
  21.     Observable<NewsList> getLatestNews();  
  22.   
  23.     @GET("stories/before/{date}")  
  24.     Observable<NewsList> getBeforeNews(@Path("date") String date);  
  25.   
  26.     @GET("story/{id}")  
  27.     Observable<NewsDetail> getNewsDetail(@Path("id") int id);  
  28.   
  29. }  
根据接口,获取服务,@GET注释,里面写接口的。注意,开头没有“/”的,看getNewsDetail,里,id的@GET为什么有{}呢?因为,他是会变,由参数@Path("id") int id的id值来决定的哦。

再看ApiManager

[javascript]  view plain  copy
  1. package zjl.com.dagger_mvp_rxjava_demo2.api;  
  2.   
  3. import retrofit2.Retrofit;  
  4. import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;  
  5. import retrofit2.converter.gson.GsonConverterFactory;  
  6. import rx.Observable;  
  7. import zjl.com.dagger_mvp_rxjava_demo2.bean.NewsDetail;  
  8. import zjl.com.dagger_mvp_rxjava_demo2.bean.NewsList;  
  9.   
  10. /** 
  11.  * Created by lidong on 2016/3/2. 
  12.  */  
  13. public class ApiManager {  
  14.   
  15.   
  16.   
  17.     private static final Retrofit sRetrofit = new Retrofit.Builder()  
  18.             .baseUrl("http://news-at.zhihu.com/api/4/")  
  19.             .addConverterFactory(GsonConverterFactory.create()) // Gson对json数据解析  
  20.             .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 使用RxJava作为回调适配器  
  21.             .build();  
  22.   
  23.     private static final ApiManagerService apiManager = sRetrofit.create(ApiManagerService.class);  
  24.   
  25.     public static Observable<NewsList> getLatestNews(){  
  26.         return apiManager.getLatestNews();  
  27.     }  
  28.   
  29.     public static Observable<NewsList> getBeforeNews(String date){  
  30.         return apiManager.getBeforeNews(date);  
  31.     }  
  32.   
  33.     public static Observable<NewsDetail> getNewsDetail(int id) {  
  34.         return apiManager.getNewsDetail(id);  
  35.     }  
  36.   
  37.   
  38.   
  39. }  
创建sRetrofit对象,以Gson对json数据解析,使用RxJava进行回调,baseUrl里写主要的不变的总接口地址(注意,结尾必须是"/"作为结尾的哦!!!)

通过Retrofit.create(ApiManagerService.class)获取服务(这都是套路啦)

自己写的静态方法,用户获取相应接口给的数据getLatestNews()、 getBeforeNews(String date)、 getNewsDetail(int id)。


这个比较基础的,如果要用的更复杂,可以加什么@header这些,那个要更深层的学习了。

然后是shownewslist包和shownewdetail包这两个包写法相同。我先按代码编写顺序讲,先是shownewslist包。

ShowNewsListActivity里调用ShowNewsListPresenter,与其关联。ShowNewsListActivity继承了ShowNewsListContract的View接口,ShowNewsListPresenter继承了ShowNewsListContract的Presenter接口。showNewsListModel从ApiManager中获取数据。并提供给ShowNewsListPresenter进行数据处理,再将对应的结果在用ShowNewsListActivity的方法进行显示。ShowNewsListPresenterComponent是ShowNewsListPresenter的注入器,ShowNewsListModule是注入类。

来看代码:

ShowNewsListActivity

[java]  view plain  copy
  1. package zjl.com.dagger_mvp_rxjava_demo2.shownewslist;  
  2.   
  3.   
  4. import android.os.Handler;  
  5. import android.support.v7.widget.LinearLayoutManager;  
  6.   
  7. import com.jcodecraeer.xrecyclerview.ProgressStyle;  
  8. import com.jcodecraeer.xrecyclerview.XRecyclerView;  
  9.   
  10. import java.util.ArrayList;  
  11. import java.util.List;  
  12.   
  13. import javax.inject.Inject;  
  14.   
  15. import butterknife.Bind;  
  16. import butterknife.ButterKnife;  
  17. import zjl.com.dagger_mvp_rxjava_demo2.ApplicationComponent;  
  18. import zjl.com.dagger_mvp_rxjava_demo2.BaseActivity;  
  19. import zjl.com.dagger_mvp_rxjava_demo2.R;  
  20. import zjl.com.dagger_mvp_rxjava_demo2.adapter.NewsListAdapter;  
  21. import zjl.com.dagger_mvp_rxjava_demo2.bean.News;  
  22.   
  23. /** 
  24.  * Created by dell on 2016/8/26. 
  25.  */  
  26. public class ShowNewsListActivity extends BaseActivity implements ShowNewsListContract.View {  
  27.   
  28.     @Bind(R.id.recyclerview)  
  29.     XRecyclerView mxRecyclerView;  
  30.   
  31.     private NewsListAdapter newsListAdapter;  
  32.     private List<News> listData = new ArrayList<>();  
  33.   
  34.     @Inject  
  35.     ShowNewsListPresenter showNewsListPresenter;  
  36.   
  37.   
  38.     @Override  
  39.     protected void initUi() {  
  40.         ButterKnife.bind(this);  
  41.   
  42.         LinearLayoutManager layoutManager = new LinearLayoutManager(this);  
  43.         layoutManager.setOrientation(LinearLayoutManager.VERTICAL);  
  44.         mxRecyclerView.setLayoutManager(layoutManager);  
  45.   
  46.         mxRecyclerView.setRefreshProgressStyle(ProgressStyle.BallSpinFadeLoader);//设置刷新类型  
  47.         mxRecyclerView.setLoadingMoreProgressStyle(ProgressStyle.Pacman);//设置加载类型  
  48.         //  mRecyclerView.setArrowImageView(R.drawable.iconfont_downgrey);//设置下拉箭头  
  49.         mxRecyclerView.setRefreshing(true);  
  50.     }  
  51.   
  52.     @Override  
  53.     protected void initDatas() {  
  54.         newsListAdapter = new NewsListAdapter(this, listData);  
  55.         mxRecyclerView.setAdapter(newsListAdapter);  
  56.   
  57.         showNewsListPresenter.attachView(this);  
  58. showNewsListPresenter.getNewsListData();  
  59.     }  
  60.   
  61.     @Override  
  62.     protected void initListener() {  
  63.         mxRecyclerView.setLoadingListener(new XRecyclerView.LoadingListener() {  
  64.             @Override  
  65.             public void onRefresh() {  
  66.                 new Handler().postDelayed(new Runnable() {  
  67.                     @Override  
  68.                     public void run() {  
  69. showNewsListPresenter.getRefreshNewsListData();  
  70.                         mxRecyclerView.refreshComplete();  
  71.                     }  
  72.                 }, 1000);  
  73.             }  
  74.   
  75.             @Override  
  76.             public void onLoadMore() {  
  77.                 new Handler().postDelayed(new Runnable() {  
  78.                     @Override  
  79.                     public void run() {  
  80.                         showNewsListPresenter.getBeforeNewsListData("20160811");  
  81.                         mxRecyclerView.loadMoreComplete();  
  82.   
  83.                     }  
  84.                 }, 1000);  
  85.             }  
  86.         });  
  87.     }  
  88.   
  89.     @Override  
  90.     protected void onclick() {  
  91.   
  92.     }  
  93.   
  94.   
  95.     @Override  
  96.     public void load(ArrayList<News> list) {  
  97.         for (int z = 0; z < list.size(); z++) {  
  98.             listData.add(list.get(z));  
  99.         }  
  100.         newsListAdapter.notifyDataSetChanged();  
  101.   
  102.     }  
  103.   
  104.     @Override  
  105.     public void refresh(ArrayList<News> list) {  
  106.         listData.clear();  
  107.         for (int z = 0; z < list.size(); z++) {  
  108.             listData.add(list.get(z));  
  109.         }  
  110.         newsListAdapter.notifyDataSetChanged();  
  111.   
  112.     }  
  113.   
  114.     @Override  
  115.     protected void setupComponent(ApplicationComponent component) {  
  116.         DaggerShowNewsListPresenterComponent.builder().applicationComponent(component).showNewsListModule(new ShowNewsListModule(this)).build().inject(this);  
  117.     }  
  118.   
  119.     @Override  
  120.     public int initContentView() {  
  121.         return R.layout.activity_main;  
  122.     }  
  123.   
  124.     @Override  
  125.     protected void onDestroy() {  
  126.         super.onDestroy();  
  127.         showNewsListPresenter.detachView();  
  128.     }  
  129. }  
按顺序来吧。

initContentView()绑定xml,R.layout.activity_main。

我要创建ShowNewsListPresenter对象,并与其关联。通过Dagger2简化、实现解耦。setupComponent(ApplicationComponent component)方法。

当然,注入对象,就要写Component,要不要写Module呢?这个要看情况的,当提供的对象是第三方库的,要,不是的话,你可以选择用@Inject哦。我这里都有在代码里涉及。

从已写好的代码结果来返回去看,比较好理解。

先看四块代码,了解。

这里,我讲解的顺序有些不同,希望能看懂。一开始,我是一MVP的写法写,那必须要写Presenter,即ShowNewsListPresenter。我们先不看注入,

先看MVP。ShowNewsListPresenter是对数据进行处理,ShowNewsListModel是或取需要的数据,我这里写的是或取接口返回的数据的方法。为了不使系统发生可能的异常,采用异步的方式即RxJava,ShowNewsListModel里的方法,传的值的类型是Observable<T>。


ShowNewsListPresenter

[java]  view plain  copy
  1. package zjl.com.dagger_mvp_rxjava_demo2.shownewslist;  
  2.   
  3.   
  4. import android.support.annotation.NonNull;  
  5.   
  6. import java.util.ArrayList;  
  7.   
  8. import javax.inject.Inject;  
  9.   
  10. import rx.Subscription;  
  11. import rx.android.schedulers.AndroidSchedulers;  
  12. import rx.functions.Action1;  
  13. import rx.schedulers.Schedulers;  
  14. import zjl.com.dagger_mvp_rxjava_demo2.BaseView;  
  15. import zjl.com.dagger_mvp_rxjava_demo2.api.ApiManager;  
  16. import zjl.com.dagger_mvp_rxjava_demo2.bean.News;  
  17. import zjl.com.dagger_mvp_rxjava_demo2.bean.NewsList;  
  18.   
  19. /** 
  20.  * Created by dell on 2016/8/26. 
  21.  */  
  22. public class ShowNewsListPresenter implements ShowNewsListContract.Presenter {  
  23.   
  24.     private ShowNewsListContract.View view;  
  25.     private Subscription mSubscription;  
  26.     private ArrayList<News> listdata = new ArrayList<>();  
  27.     @Inject  
  28.     ShowNewsListModel showNewsListModel;  
  29.     @Inject  
  30.     public ShowNewsListPresenter() {  
  31.   
  32.     }  
  33.   
  34.   
  35.     @Override  
  36.     public void getBeforeNewsListData(String date) {  
  37.         mSubscription = showNewsListModel.getBeforeNews(date)  
  38.                 .subscribeOn(Schedulers.io())  
  39.                 .observeOn(AndroidSchedulers.mainThread())  
  40.                 .subscribe(new Action1<NewsList>() {  
  41.                     @Override  
  42.                     public void call(NewsList newsList) {  
  43.                         for (int z = 0; z < newsList.getStories().size(); z++) {  
  44.                             listdata.add(newsList.getStories().get(z));  
  45.                         }  
  46.                         view.load(listdata);  
  47.                     }  
  48.                 }, new Action1<Throwable>() {  
  49.                     @Override  
  50.                     public void call(Throwable throwable) {  
  51.                         System.out.println("-------onFailure" + throwable.getMessage());  
  52.                     }  
  53.                 });  
  54.     }  
  55.   
  56.     @Override  
  57.     public void getNewsListData() {  
  58.         mSubscription =showNewsListModel.getLatestNews()  
  59.                 .subscribeOn(Schedulers.io())  
  60.                 .observeOn(AndroidSchedulers.mainThread())  
  61.                 .subscribe(new Action1<NewsList>() {  
  62.                     @Override  
  63.                     public void call(NewsList newsList) {  
  64.                         listdata.clear();  
  65.                         for (int z = 0; z < newsList.getStories().size(); z++) {  
  66.                             listdata.add(newsList.getStories().get(z));  
  67.                         }  
  68.                         view.refresh(listdata);  
  69.                     }  
  70.                 }, new Action1<Throwable>() {  
  71.                     @Override  
  72.                     public void call(Throwable throwable) {  
  73.                         System.out.println("-------onFailure" + throwable.getMessage());  
  74.                     }  
  75.                 });  
  76.     }  
  77.   
  78.     @Override  
  79.     public void getRefreshNewsListData() {  
  80.         mSubscription = showNewsListModel.getLatestNews()  
  81.                 .subscribeOn(Schedulers.io())  
  82.                 .observeOn(AndroidSchedulers.mainThread())  
  83.                 .subscribe(new Action1<NewsList>() {  
  84.                     @Override  
  85.                     public void call(NewsList newsList) {  
  86.                         listdata.clear();  
  87.                         for (int z = 0; z < newsList.getStories().size(); z++) {  
  88.                             listdata.add(newsList.getStories().get(z));  
  89.                         }  
  90.                         view.refresh(listdata);  
  91.                     }  
  92.                 }, new Action1<Throwable>() {  
  93.                     @Override  
  94.                     public void call(Throwable throwable) {  
  95.                         System.out.println("-------onFailure" + throwable.getMessage());  
  96.                     }  
  97.                 });  
  98.     }  
  99.   
  100.     @Override  
  101.     public void attachView(@NonNull ShowNewsListContract.View view) {  
  102.         this.view = view;  
  103.     }  
  104.   
  105.     @Override  
  106.     public void detachView() {  
  107.   
  108.         if (mSubscription != null && !mSubscription.isUnsubscribed()) {  
  109.             mSubscription.unsubscribe();  
  110.         }  
  111.         view = null;  
  112.     }  
  113.   
  114. }  
ShowNewsListPresenter里哪里用到了RxJava呢?对RxJava有所了解的,很清楚的看出是在getBeforeNewsListData(String date) ,getNewsListData() ,getRefreshNewsListData()里。以getBeforeNewsListData(String date) 方法,为例。一句句说明干什么用。

mSubscription是什么?

[java]  view plain  copy
  1. private Subscription mSubscription;  
RxJava中有个叫做Subscription的接口,可以用来取消订阅.只需要调用unsubscribe就可以取消订阅,那么如何得到一个Subscription对象呢?
其实很简单:
Observable.subscribe()方法可以返回一个Subscription的对象,即我们每次订阅都会返回.
感觉Subscription就像一个订单,你下单了就会生成一个订单,而你也可以用这个订单取消订单。

[java]  view plain  copy
  1. showNewsListModel.getLatestNews()  
调用showNewsListModel的getLatestNews()方法向接口获取数据。

[java]  view plain  copy
  1. .subscribeOn(Schedulers.io())  
获取数据这一步是开启新线程,在新线程里执行。

[java]  view plain  copy
  1. .observeOn(AndroidSchedulers.mainThread())  
对接口返回的数据的处理,是在主线程执行。

[java]  view plain  copy
  1. .subscribe(new Action1<NewsList>() {  
  2.                     @Override  
  3.                     public void call(NewsList newsList) {  
  4.                         for (int z = 0; z < newsList.getStories().size(); z++) {  
  5.                             listdata.add(newsList.getStories().get(z));  
  6.                         }  
  7.                         view.load(listdata);  
  8.                     }  
  9.                 }, new Action1<Throwable>() {  
  10.                     @Override  
  11.                     public void call(Throwable throwable) {  
  12.                         System.out.println("-------onFailure" + throwable.getMessage());  
  13.                     }  
  14.                 });  
  15.     }  
对接口返回的数据的处理,在subscribe()方法中写,Action1<NewsList>方法里重写call(),这个是简化了写法,替代了,onNext()、onError()、onComplete()方法。

重写call()方法,代码里用for循环遍历list,是为了处理数据,再通过

[java]  view plain  copy
  1. view.load(listdata);  
方法,调用ShowNewsListActivity里的load(ArrayList<News> list)方法,对V进行UI对应更改。

然后是attachView(@NonNull ShowNewsListContract.View view)、detachView()方法,这两个方法是什么用的呢?是为了防止内存泄漏的哦。当Activity结束时,要同时结束Presenter,防止,重新使用Activity时,上个Presenter还未结束。所以要将Presenter绑定到Activity,随着Activity销毁,OnDestory()而结束。

ShowNewsListModel

 
 
[java] view plain copy
  1. package zjl.com.dagger_mvp_rxjava_demo2.shownewslist;  
  2.   
  3.   
  4. import javax.inject.Inject;  
  5.   
  6. import rx.Observable;  
  7. import zjl.com.dagger_mvp_rxjava_demo2.api.ApiManager;  
  8. import zjl.com.dagger_mvp_rxjava_demo2.bean.NewsList;  
  9.   
  10. /** 
  11.  * Created by dell on 2016/8/26. 
  12.  */  
  13.   
  14. public class ShowNewsListModel {  
  15.   
  16.     @Inject  
  17.     public ShowNewsListModel(){}  
  18.   
  19.     Observable<NewsList> getLatestNews(){  
  20.         return ApiManager.getLatestNews();  
  21.     }  
  22.   
  23.    Observable<NewsList> getBeforeNews(String date){  
  24.         return ApiManager.getBeforeNews(date);  
  25.     }  
  26. }  
对MVP有了解的,知道。V接收用户的指令,调用P,P有必要时,就向M获取数据,M将获取的数据再给P,P处理后,反馈给V中去显示。(这是我理解的MVP)。我们回看ShowNewsListActivity,看看哪里调用了P。
在initDatas()方法中,初始化数据。
 
 
[java] view plain copy
  1. @Override  
  2.    protected void initDatas() {  
  3.        newsListAdapter = new NewsListAdapter(this, listData);  
  4.        mxRecyclerView.setAdapter(newsListAdapter);  
  5.   
  6.        showNewsListPresenter.attachView(this);  
  7.        showNewsListPresenter.getNewsListData();  
  8.    }  
在这里就执行了
[java] view plain copy
  1. showNewsListPresenter.attachView(this);  
将Presenter绑定Activity,
 
 
[java] view plain copy
  1. showNewsListPresenter.getNewsListData();  
这句话,就调用了P,让ShowNewsListPresenter调用相应的方法去获取新闻数据。
这样MVP的使用应该能理解吗?(我第一次写,不是很会讲,没看懂,真是对不起了。)
接下来我讲Dagger2的使用。
ShowNewsListActivity要让ShowNewsListPresenter调用方法,就需要对ShowNewsListPresenter实例化。为了解耦,避免ShowNewsListPresenter有改动,导致ShowNewsListActivity也要随之改动,所以,用Dagger2实现注入。
既然要实现注入,Component必不可少。所以就有了ShowNewsListPresenterComponent。
看代码:

ShowNewsListPresenterComponent

[java] view plain copy
  1. package zjl.com.dagger_mvp_rxjava_demo2.shownewslist;  
  2.   
  3.   
  4. import dagger.Component;  
  5. import zjl.com.dagger_mvp_rxjava_demo2.ApplicationComponent;  
  6.   
  7. /** 
  8.  * Created by dell on 2016/9/1. 
  9.  */  
  10. @Component(dependencies = ApplicationComponent.class,modules = ShowNewsListModule.class)  
  11. public interface ShowNewsListPresenterComponent {  
  12.     void inject(ShowNewsListActivity showNewsListActivity);  
  13. }  
我这里void inject(ShowNewsListActivity showNewsListActivity);是表明要注入到ShowNewsListActivity中。看代码里有一句
 
 
[java] view plain copy
  1. @Component(dependencies = ApplicationComponent.class,modules = ShowNewsListModule.class)  
依赖上层的Component,实例化ShowNewsPresenter时需要Module,ShowNewsListModule中提供的某些对象。而其实,我这里并未用到ShowNewsListModule.class,只是演示一下Module怎么写。在NewDetailPresenterComponent中我特意写成需要用到的,到时候看一下。

ShowNewsListModule
[java]  view plain  copy
  1. package zjl.com.dagger_mvp_rxjava_demo2.shownewslist;  
  2.   
  3. import dagger.Module;  
  4. import dagger.Provides;  
  5.   
  6. /** 
  7.  * Created by dell on 2016/8/30. 
  8.  */  
  9. @Module  
  10. public class ShowNewsListModule {  
  11.   
  12.     private final ShowNewsListContract.View view;  
  13.     public ShowNewsListModule(ShowNewsListContract.View view){  
  14.         this.view = view;  
  15.     }  
  16. }  

看ShowNewsListPresenter中有

[java]  view plain  copy
  1. @Inject  
  2.    public ShowNewsListPresenter() {  
  3.   
  4.    }  
 @Inject是识别的,ShowNewsListActivity中需要一个ShowNewsListPresenter对象,通过Component去找哪里有对应的对象生成,发现,ShowNewsListPresenter的构造方法上有一个 @Inject符号,就找到这个对象,自动实例化,其中还需要一个ShowNewsListModel对象,同样用@Inject注入,ShowNewsListPresenterComponent会自动去查找哪里有提供对象,会在ShowNewsListModel的构造方法中,找到,最终生成了ShowNewsListPresenter对象。

回来再看,ShowNewsListActivity,需要实例化Component,进一步注入对象,这个时候,就要重写setupComponent(ApplicationComponent component)方法。

[java]  view plain  copy
  1. @Override  
  2.     protected void setupComponent(ApplicationComponent component) {  
  3.         DaggerShowNewsListPresenterComponent.builder().applicationComponent(component).showNewsListModule(new ShowNewsListModule(this)).build().inject(this);  
  4.     }  
首先在ShowNewsListPresenterComponent和ShowNewsListModule写好后,需要rebuild一下项目,自动生成DaggerShowNewsListPresenterComponent文件,在进一步实例化,依赖的Component和Module,最后注入进Activity。

OK,ShowNewsListPresenter注入成功。

那Module怎么使用呢,我的ShowNewsListModule没有被使用,所以我特地写了个会被使用的。请看shownewdetail包,MVP的写法相同,我就不写了,我讲一下Dagger2注入。

NewDetailPresenterComponent写法相同。

[java]  view plain  copy
  1. package zjl.com.dagger_mvp_rxjava_demo2.shownewdetial;  
  2.   
  3.   
  4. import dagger.Component;  
  5. import zjl.com.dagger_mvp_rxjava_demo2.ApplicationComponent;  
  6.   
  7. /** 
  8.  * Created by dell on 2016/9/1. 
  9.  */  
  10. @Component(dependencies = ApplicationComponent.class,  
  11.         modules = NewDetailModule.class)  
  12. public interface NewDetailPresenterComponent {  
  13.     void inject(NewDetailActivity newDetailActivity);  
  14. }  
NewDetailPresenter的构造方法和ShowNewsListPresenter的有些不同,有参数。

[java]  view plain  copy
  1. package zjl.com.dagger_mvp_rxjava_demo2.shownewslist;  
  2.   
  3.   
  4. import android.support.annotation.NonNull;  
  5.   
  6. import java.util.ArrayList;  
  7.   
  8. import javax.inject.Inject;  
  9.   
  10. import rx.Subscription;  
  11. import rx.android.schedulers.AndroidSchedulers;  
  12. import rx.functions.Action1;  
  13. import rx.schedulers.Schedulers;  
  14. import zjl.com.dagger_mvp_rxjava_demo2.BaseView;  
  15. import zjl.com.dagger_mvp_rxjava_demo2.api.ApiManager;  
  16. import zjl.com.dagger_mvp_rxjava_demo2.bean.News;  
  17. import zjl.com.dagger_mvp_rxjava_demo2.bean.NewsList;  
  18.   
  19. /** 
  20.  * Created by dell on 2016/8/26. 
  21.  */  
  22. public class ShowNewsListPresenter implements ShowNewsListContract.Presenter {  
  23.   
  24.     private ShowNewsListContract.View view;  
  25.     private Subscription mSubscription;  
  26.     private ArrayList<News> listdata = new ArrayList<>();  
  27.     @Inject  
  28.     ShowNewsListModel showNewsListModel;  
  29.     @Inject  
  30.     public ShowNewsListPresenter() {  
  31.   
  32.     }  
  33.   
  34.   
  35.     @Override  
  36.     public void getBeforeNewsListData(String date) {  
  37.         mSubscription = showNewsListModel.getBeforeNews(date)  
  38.                 .subscribeOn(Schedulers.io())  
  39.                 .observeOn(AndroidSchedulers.mainThread())  
  40.                 .subscribe(new Action1<NewsList>() {  
  41.                     @Override  
  42.                     public void call(NewsList newsList) {  
  43.                         for (int z = 0; z < newsList.getStories().size(); z++) {  
  44.                             listdata.add(newsList.getStories().get(z));  
  45.                         }  
  46.                         view.load(listdata);  
  47.                     }  
  48.                 }, new Action1<Throwable>() {  
  49.                     @Override  
  50.                     public void call(Throwable throwable) {  
  51.                         System.out.println("-------onFailure" + throwable.getMessage());  
  52.                     }  
  53.                 });  
  54.     }  
  55.   
  56.     @Override  
  57.     public void getNewsListData() {  
  58.         mSubscription =showNewsListModel.getLatestNews()  
  59.                 .subscribeOn(Schedulers.io())  
  60.                 .observeOn(AndroidSchedulers.mainThread())  
  61.                 .subscribe(new Action1<NewsList>() {  
  62.                     @Override  
  63.                     public void call(NewsList newsList) {  
  64.                         listdata.clear();  
  65.                         for (int z = 0; z < newsList.getStories().size(); z++) {  
  66.                             listdata.add(newsList.getStories().get(z));  
  67.                         }  
  68.                         view.refresh(listdata);  
  69.                     }  
  70.                 }, new Action1<Throwable>() {  
  71.                     @Override  
  72.                     public void call(Throwable throwable) {  
  73.                         System.out.println("-------onFailure" + throwable.getMessage());  
  74.                     }  
  75.                 });  
  76.     }  
  77.   
  78.     @Override  
  79.     public void getRefreshNewsListData() {  
  80.         mSubscription = showNewsListModel.getLatestNews()  
  81.                 .subscribeOn(Schedulers.io())  
  82.                 .observeOn(AndroidSchedulers.mainThread())  
  83.                 .subscribe(new Action1<NewsList>() {  
  84.                     @Override  
  85.                     public void call(NewsList newsList) {  
  86.                         listdata.clear();  
  87.                         for (int z = 0; z < newsList.getStories().size(); z++) {  
  88.                             listdata.add(newsList.getStories().get(z));  
  89.                         }  
  90.                         view.refresh(listdata);  
  91.                     }  
  92.                 }, new Action1<Throwable>() {  
  93.                     @Override  
  94.                     public void call(Throwable throwable) {  
  95.                         System.out.println("-------onFailure" + throwable.getMessage());  
  96.                     }  
  97.                 });  
  98.     }  
  99.   
  100.     @Override  
  101.     public void attachView(@NonNull ShowNewsListContract.View view) {  
  102.         this.view = view;  
  103.     }  
  104.   
  105.     @Override  
  106.     public void detachView() {  
  107.   
  108.         if (mSubscription != null && !mSubscription.isUnsubscribed()) {  
  109.             mSubscription.unsubscribe();  
  110.         }  
  111.         view = null;  
  112.     }  
  113.   
  114. }  

NewDetailPresenterComponent会自动去找提供对象的方法,找到了NewDetailModule。

[java]  view plain  copy
  1. package zjl.com.dagger_mvp_rxjava_demo2.shownewdetial;  
  2.   
  3. import dagger.Module;  
  4. import dagger.Provides;  
  5. import zjl.com.dagger_mvp_rxjava_demo2.shownewslist.ShowNewsListContract;  
  6.   
  7. /** 
  8.  * Created by dell on 2016/8/31. 
  9.  */  
  10. @Module  
  11. public class NewDetailModule {  
  12.     private final NewDetailContract.View view;  
  13.     private int id;  
  14.     public NewDetailModule(NewDetailContract.View view,int id){  
  15.         this.view = view;  
  16.         this.id = id;  
  17.     }  
  18.   
  19.     @Provides  
  20.     public int provideid(){  
  21.         return id;  
  22.     }  
  23. }  

provideid()方法,提供了参数int id。

在NewDetailActivity里setupComponent(ApplicationComponent component)方法中,对NewDetailModule的实例化时,需要传递进一个int型参数,就是用于实例化NewDetailPresenter的。

[java]  view plain  copy
  1. @Override  
  2.     protected void setupComponent(ApplicationComponent component) {  
  3.         DaggerNewDetailPresenterComponent.builder().applicationComponent(component).newDetailModule(new NewDetailModule(this, getIntent().getIntExtra("new"0))).build().inject(this);  
  4.     }  


综上,例子就写完了。希望对大家能有一丢丢的帮助。首次写博客,写的不好请见谅。

项目地址
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值