谷歌官方MVP+Dagger2架构简析

Posted 劲火星空

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了谷歌官方MVP+Dagger2架构简析相关的知识,希望对你有一定的参考价值。

一、概念



首先看一下添加了Dagger2后的目录结构的变化

可以看到主要是增加的四个文件
ApplicationMoudle

ToDoApplication 上面的这两个是获得全局的Context用的
TaskDetailComponent TaskDetailPresenterMoudle 这两个是用来注入Presenter的时候使用的

二、全局Context注入

这里的主要作用就是对外提供Context,也就是要通过注入的方式来对外提供Application的Context
(1)ApplicationMoudle的创建 主要用来提供全局的Context
@Module
public final class ApplicationModule 

  private final Context mContext;

  ApplicationModule(Context context) 
      mContext = context;
  
  @Provides
  Context provideContext() 
      return mContext;
  


(2)TasksRepositoryMoudle的创建 这是一个数据库的Moudle,用来对外提供数据的,一个是远程的数据,一个是本地的数据
@Module
public class TasksRepositoryModule 

  @Singleton
  @Provides
  @Local
  TasksDataSource provideTasksLocalDataSource(Context context) 
      return new TasksLocalDataSource(context);
  

  @Singleton
  @Provides
  @Remote
  TasksDataSource provideTasksRemoteDataSource() 
      return new FakeTasksRemoteDataSource();
  

(3) TasksRepositoryComponent的创建,这是一个封装上面两个类的接口,通过这个接口就可以将两个类进行封装
@Singleton
@Component(modules = TasksRepositoryModule.class, ApplicationModule.class)
public interface TasksRepositoryComponent 

  TasksRepository getTasksRepository();
注意到这里还提供了一个单例的模式,也就是说这个Component是有范围的
都说Component就是一个注入器,也可以说是 @Inject @Module 的桥梁

(4)全局Context和TasksRepositoryComponent的获取 DaggerTasksRepositoryComponent 是由Dagger2生成的代码。我们通过它来初始化 TasksRepositoryComponent。并且可以看到的是 ApplicationModuleTasksRepositoryModule也在这里进行了一次性初始化。 TasksRepository需要说明的是整个数据model层的核心。
public class ToDoApplication extends Application 

    private TasksRepositoryComponent mRepositoryComponent;

    @Override
    public void onCreate() 
        super.onCreate();

        mRepositoryComponent = DaggerTasksRepositoryComponent.builder()
                .applicationModule(new ApplicationModule((getApplicationContext())))
                .tasksRepositoryModule(new TasksRepositoryModule()).build();
    

    public TasksRepositoryComponent getTasksRepositoryComponent() 
        return mRepositoryComponent;
    
上面的DaggerTasksRepositoryComponent是通过编译得到的,通过这个讲两个Moudle注入进来,最终得到的就可以得到全局Context和Presenter的对象了



三、Presenter注入

上面讲的是全局的注入,而接下来提到的是针对TasksDetail的注入了

(1)首先看TasksDetailComponent

@FragmentScoped
@Component(dependencies = TasksRepositoryComponent.class, modules = TaskDetailPresenterModule.class)
public interface TaskDetailComponent 

  void inject(TaskDetailActivity taskDetailActivity);
从注解中可以看到依赖于 TasksRepositoryComponent.class所以其中的 TaskRespository对于当前component是可用的。


(2)接下来是TaskDetailPresenterMoudle模块,因为上的Component也是依赖他的

@Module
public class TaskDetailPresenterModule 

  private final TaskDetailContract.View mView;

  private final String mTaskId;

  public TaskDetailPresenterModule(TaskDetailContract.View view, String taskId) 
      mView = view;
      mTaskId = taskId;
  

  @Provides
  TaskDetailContract.View provideTaskDetailContractView() 
      return mView;
  

  @Provides
  String provideTaskId() 
      return mTaskId;
  

主要是提供MVP中相应模块的View的返回,这在上面一节中提到过,所以可以看到返回类型是 TaskDetailContract.View 。也是在这里完成MVP模式中重要的一环,也就是Presenter和View的实例的获取,不然Presenter怎么告诉View怎么更新View呢!
(3)Presenter的创建

接下来看看Presenter的创建。在上一节中我们就知道了Presenter由 TaskDetailActivity进行创建。实际上的MVP中的View是TaskDetailFragment。因为这里是通过view.setPresenter方式完成presenter和view的链接。
public class TaskDetailActivity extends AppCompatActivity 
  @Inject TaskDetailPresenter mTaskDetailPresenter;

  @Override
  protected void onCreate(Bundle savedInstanceState) 
     ......

      if (taskDetailFragment == null) 
          taskDetailFragment = TaskDetailFragment.newInstance(taskId);

          ActivityUtils.addFragmentToActivity(getSupportFragmentManager(),
                  taskDetailFragment, R.id.contentFrame);
      

      // Create the presenter
      DaggerTaskDetailComponent.builder()
              .taskDetailPresenterModule(new TaskDetailPresenterModule(taskDetailFragment, taskId))
              .tasksRepositoryComponent(((ToDoApplication) getApplication())
              .getTasksRepositoryComponent()).build()
              .inject(this);
  
......
这里的Presenter也是通过注入的方式来进行的,Inject

(4)既然将Presenter注入进来了,那么我的Presenter是怎么创建的呢下面看一下
final class TaskDetailPresenter implements TaskDetailContract.Presenter 

    private TasksRepository mTasksRepository;//Model
    private TaskDetailContract.View mTaskDetailView;//View

    @Nullable String mTaskId;
    @Inject
    TaskDetailPresenter(@Nullable String taskId,
            TasksRepository tasksRepository,
            TaskDetailContract.View taskDetailView) 
        mTasksRepository = tasksRepository;
        mTaskDetailView = taskDetailView;
        mTaskId = taskId;
    

    @Inject
    void setupListeners() 
        mTaskDetailView.setPresenter(this);
    
...Presenter中的操作...
主要就是一个构造方法了,还有一个关键的就是mTasksDetailView.setPresenter(this) 通过这个语句就可以将Presenter传递到我们的View中,这样我们在View中就可以获得的Presenter的实例 然后通过这个实例对数据库进行操作



差不多就这些


尊重作者,尊重原创,参考文章:
http://www.jianshu.com/p/01d3c014b0b1



以上是关于谷歌官方MVP+Dagger2架构简析的主要内容,如果未能解决你的问题,请参考以下文章

一套整合主流HTTP网络图片加载MVP(RxJava2+Dagger2)架构的快速高效的开发框架RxEasyAndroid

一套整合主流HTTP网络图片加载MVP(RxJava2+Dagger2)架构的快速高效的开发框架RxEasyAndroid

mvp架构简析--高上

Android--带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava

当 Dagger2 应用在 MVP 框架中

MVP+Dagger2+Rxjava+Retrofit+GreenDao 开发的小应用,包括新闻图片视频3个大模块,代码封装良好