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

7 篇文章 0 订阅

工程树:

  • 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
@Module
public 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实例
@Inject
TaskDetailPresenter 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

@Singleton
public class TasksLocalDataSource implements TasksDataSource {

    private Context mContext;

    @Inject
    public TasksLocalDataSource(Context mContext) {
        this.mContext = mContext;
    }
}

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

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

context由AppMoudle提供

@Module
public class AppModule {
    private final Context mContext;

    public AppModule(Context mContext) {
        this.mContext = mContext;
    }

    @Provides
    Context provideContext() {
        return mContext;
    }
}

TasksRemoteDataSource

@Singleton
public 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的方法

@Singleton
public 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络产生,所以

@Module
public 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

@Module
public 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);    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值