[Android 知识点] MVP+RxJava+Dagger开发框架

来源:互联网 发布:数据日语怎么说 编辑:程序博客网 时间:2024/05/21 08:44

工程树:

  • TaskDetail

    • TaskDetailActivity [ V ]
    • TaskDetailFragment [ V ]
    • TaskDetailContract [ M < - P - >V ]
    • TaskDetailPresenter [ P ]
    • TaskDetailPresenterModule [ Module ]
    • TaskDetailComponent [ Component ]
    • App
    • AppModule
  • Data

    • Local 本地数据
    • Remote 网络数据
    • TasksDataSource 数据逻辑
    • TasksRepository 数据处理
    • TasksRepositoryModule [ Module ]
    • TasksRepositoryComponent [ Component ]

TaskDetailActivity TaskDetailFragment

主要工作:
1. 编辑Toolbar
2. 加载Fragment
3. 实例化Presenter

编辑Toolbar

  // Set up the toolbar.Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);setSupportActionBar(toolbar);ActionBar ab = getSupportActionBar();ab.setDisplayHomeAsUpEnabled(true);ab.setDisplayShowHomeEnabled(true);

加载Fragment

TaskDetailFragment mTaskDetailFragment = (TaskDetailFragment) getSupportFragmentManager().findFragmentById(R.id.contentFrame);        if (mTaskDetailFragment == null) {            mTaskDetailFragment = TaskDetailFragment.newInstance();            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();            transaction.add(R.id.contentFrame, mTaskDetailFragment);            transaction.commit();        }

实例化Presenter

1. 建立一个依赖提供类 TaskDetailPresenterModule
@Modulepublic class TaskDetailPresenterModule {    private TaskDetailContract.View mView;    public TaskDetailPresenterModule(TaskDetailContract.View mView) {        this.mView = mView;    }    @Provides    TaskDetailContract.View provideView() {        return mView;    }

在MVP模式中,所依赖的是的是View,所以 provideView() 作为专门提供依赖的方法

2. 在TaskDetailPresenter中进行注入,因为Presenter是主持人,由它调用view的方法
public class TaskDetailPresenter implements TaskDetailContract.Presenter {    TaskDetailContract.View mView;    @Inject    public TaskDetailPresenter(TaskDetailContract.View mView) {        this.mView = mView;    }}
3. 连接Inject和Moudle,构建注射器Comonpent
@Component(modules = TaskDetailPresenterModule.class)public interface TaskDetailComponent {    void inject(TaskDetailActivity mTaskDetailActivity);}
4. 注入,产生Presenter实例
@InjectTaskDetailPresenter mTaskDetailPresenter;DaggerTaskDetailComponent.builder()    .taskDetailPresenterModule(new TaskDetailPresenterModule(mTaskDetailFragment))    .build().inject(this);
5. 虽然已经产生了TaskDetailPresenter,但是 V - P 还没联系起来,下面开始搭建 V - P 的关系。

TaskDetailContract

1. 建立联系人
public class TaskDetailContract {    interface View {        void setPresenter(Presenter mPresenter);    }    interface Presenter {    }}
2. 实现接口,关联 V - P  
public class TaskDetailFragment extends Fragment implements TaskDetailContract.View{    private TaskDetailContract.Presenter mPresenter;    @Override    public void setPresenter(TaskDetailContract.Presenter mPresenter) {        this.mPresenter = mPresenter;    }}
3. 用@Inject注解injectPresenter()方法,生成的代码中会调用该方法,,该方法在TaskDetailFragment中实现,这样把 P -> V 联系起来了
public class TaskDetailPresenter implements TaskDetailContract.Presenter {    TaskDetailContract.View mView;    @Inject    public TaskDetailPresenter(TaskDetailContract.View mView) {        this.mView = mView;    }    @Inject    void injectPresenter() {        mView.setPresenter(this);    }}

TaskDetailComponent

最后一步就是建立注射器,把inject和moudle开动起来。

@Component(modules = TaskDetailPresenterModule.class)public interface TaskDetailComponent {    void inject(TaskDetailActivity mTaskDetailActivity);}

在Acticitu中,进行调用,其中taskDetailPresenterModule是带参数的

 DaggerTaskDetailComponent.builder()    .taskDetailPresenterModule(new TaskDetailPresenterModule(mTaskDetailFragment))    .build().inject(this);  

Data

数据源分为 本地 和 网络

TasksLocalDataSource

@Singletonpublic class TasksLocalDataSource implements TasksDataSource {    private Context mContext;    @Inject    public TasksLocalDataSource(Context mContext) {        this.mContext = mContext;    }}

@Singleton表示单例模式,因为我们始终操作的都是同一个数据源对象

而context常常被本地数据用到,所以建立一个依赖

context由AppMoudle提供

@Modulepublic class AppModule {    private final Context mContext;    public AppModule(Context mContext) {        this.mContext = mContext;    }    @Provides    Context provideContext() {        return mContext;    }}

TasksRemoteDataSource

@Singletonpublic class TasksRemoteDataSource implements TasksDataSource {    @Inject    public TasksRemoteDataSource() {    }}

TasksDataSource

无论本地还是网络数据的行为,统一实现TasksDataSource接口

public interface TasksDataSource {}

Local && Remote

当依赖为可选多个的时候,适用@Qualifier命名各自的作用域

@Qualifier@Documented@Retention(RetentionPolicy.RUNTIME)public @interface Local {}
@Qualifier@Documented@Retention(RetentionPolicy.RUNTIME)public @interface Remote {}

TasksDataRepository

在TasksDataRepository中,实现TasksDataSource的方法

@Singletonpublic class TasksDataRepository implements TasksDataSource{    private final TasksDataSource mTasksRemoteDataSource;    private final TasksDataSource mTasksLocalDataSource;    @Inject    public TasksDataRepository(@Remote TasksDataSource mTasksRemoteDataSource, @Local TasksDataSource mTasksLocalDataSource) {        this.mTasksRemoteDataSource = mTasksRemoteDataSource;        this.mTasksLocalDataSource = mTasksLocalDataSource;    }}

TasksRepositoryModule

提供数据依赖,由于TasksDataSource由TasksLocalDataSource和TasksRemoteDataSource络产生,所以

@Modulepublic class TasksRepositoryModule { @LocalScoped    @Singleton    @Provides    TasksDataSource provideLocalData(Context mContext) {        return new TasksLocalDataSource(mContext);    }    @RemoteScoped    @Singleton    @Provides    TasksDataSource provideRemoteData() {        return new TasksRemoteDataSource();    }}

TasksRepositoryComponent

构建注射器

@Singleton@Component(modules = {TasksRepositoryModule.class, AppModule.class})public interface TasksRepositoryComponent {    TasksDataRepository getTasksDataRepository();}

这样一个TasksRepositoryComponent就准备好了

最后一步:注入

我们选择在App主要类中进行构建

public class App extends Application {    private TasksRepositoryComponent mTasksRepositoryComponent;    @Override    public void onCreate() {        super.onCreate();        mTasksRepositoryComponent = DaggerTasksRepositoryComponent.builder()                .appModule(new AppModule(getApplicationContext()))                .build();    }    public TasksRepositoryComponent getTasksRepositoryComponent() {        return mTasksRepositoryComponent;    }}

这样就可以到一个TasksRepositoryComponent实例

至此,我们MVP中的M就构建好了

TaskDetailActivity

M-V-P都已经准备完毕,之后就把三者联系起来

public class TaskDetailActivity extends AppCompatActivity {    @Inject    TaskDetailPresenter mTaskDetailPresenter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_task_detail);        . . .        DaggerTaskDetailComponent.builder()                .taskDetailPresenterModule(new TaskDetailPresenterModule(mTaskDetailFragment))                .tasksRepositoryComponent(((App) getApplication()).getTasksRepositoryComponent())                .build().inject(this);    }}

App

public class App extends Application {    private DataComponent mDataComponent;    @Override    public void onCreate() {        super.onCreate();        mDataComponent = DaggerDataComponent.builder()                .appModule(new AppModule(getApplicationContext()))                .build();    }    public DataComponent getDataComponent() {        return mDataComponent;    }}

AppModule

@Modulepublic class AppModule {    private final Context mContext;    public AppModule(Context mContext) {        this.mContext = mContext;    }    @Provides    public Context provideContext() {        return mContext;    }}

RxJava

主要用在数据请求上

在TasksDataSource中,定义一个观察者

Observable<Task> getTask(@NonNull String taskId);

在TasksRepository中,实现逻辑

    Observable<Task> getTask(@NonNull String taskId) {        return mTasksLocalDataSource.getTask(taskId);    }

在TasksLocalDataSource创建观察者

  @Override    public Observable<Task> getTask(@NonNull String taskId) {        String[] projection = {                TaskEntry.COLUMN_NAME_ENTRY_ID,                TaskEntry.COLUMN_NAME_TITLE,                TaskEntry.COLUMN_NAME_DESCRIPTION,                TaskEntry.COLUMN_NAME_COMPLETED        };        String sql = String.format("SELECT %s FROM %s WHERE %s LIKE ?",                TextUtils.join(",", projection), TaskEntry.TABLE_NAME, TaskEntry.COLUMN_NAME_ENTRY_ID);        return mDatabaseHelper.createQuery(TaskEntry.TABLE_NAME, sql, taskId)                .mapToOneOrDefault(mTaskMapperFunction, null);    }

在TaskDetailContract中创建订阅和取消订阅

public class TaskDetailContract {    interface View {        void setPresenter(Presenter mPresenter);    }    interface Presenter {        void subscribe();        void unsubscribe();    }}

在View中调用方法

  @Override    public void onResume() {        super.onResume();        mPresenter.subscribe();    }    @Override    public void onPause() {        super.onPause();        mPresenter.unsubscribe();    }

在TaskDetailPresenter中实现

@Override    public void subscribe() {    }    @Override    public void unsubscribe() {        mCompositeDisposable.clear();    }

值得一提的是,在RxJava中,对于订阅者的管理,我们需要用到CompositeDisposable

CompositeDisposable mCompositeDisposable= new CompositeDisposable();mCompositeDisposable.add(mSubscribe);    
0 0
原创粉丝点击