一、概念
首先看一下添加了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是有范围的
@Component(modules = {TasksRepositoryModule.class, ApplicationModule.class})
public interface TasksRepositoryComponent {
TasksRepository getTasksRepository();
}
都说Component就是一个注入器,也可以说是
@Inject
和@Module
的桥梁(4)全局Context和TasksRepositoryComponent的获取
DaggerTasksRepositoryComponent
是由Dagger2生成的代码。我们通过它来初始化TasksRepositoryComponent
。并且可以看到的是ApplicationModule
和TasksRepositoryModule
也在这里进行了一次性初始化。TasksRepository
需要说明的是整个数据model层的核心。
public class ToDoApplication extends Application {上面的DaggerTasksRepositoryComponent是通过编译得到的,通过这个讲两个Moudle注入进来,最终得到的就可以得到全局Context和Presenter的对象了
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;
}
}
上面讲的是全局的注入,而接下来提到的是针对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主要是提供MVP中相应模块的View的返回,这在上面一节中提到过,所以可以看到返回类型是
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;
}
}
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 {这里的Presenter也是通过注入的方式来进行的,Inject
@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);
}
......
}
(4)既然将Presenter注入进来了,那么我的Presenter是怎么创建的呢下面看一下
final class TaskDetailPresenter implements TaskDetailContract.Presenter {主要就是一个构造方法了,还有一个关键的就是mTasksDetailView.setPresenter(this) 通过这个语句就可以将Presenter传递到我们的View中,这样我们在View中就可以获得的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中的操作...
}
差不多就这些
尊重作者,尊重原创,参考文章:
http://www.jianshu.com/p/01d3c014b0b1