谷歌官方MVP+Dagger2架构简析

来源:互联网 发布:伴奏降调软件中文版 编辑:程序博客网 时间:2024/06/11 03:23

一、概念



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

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

ApplicationMoudle

ToDoApplication
上面的这两个是获得全局的Context用的

TaskDetailComponent
TaskDetailPresenterMoudle
这两个是用来注入Presenter的时候使用的


二、全局Context注入


这里的主要作用就是对外提供Context,也就是要通过注入的方式来对外提供Application的Context

(1)ApplicationMoudle的创建
主要用来提供全局的Context
@Modulepublic final class ApplicationModule {  private final Context mContext;  ApplicationModule(Context context) {      mContext = context;  }  @Provides  Context provideContext() {      return mContext;  }}

(2)TasksRepositoryMoudle的创建
这是一个数据库的Moudle,用来对外提供数据的,一个是远程的数据,一个是本地的数据
@Modulepublic 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也是依赖他的

@Modulepublic 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



原创粉丝点击