说到MVP就不得不提到MVC,做过J2EE的猿友们肯定知道MVC是个什么东西。MVC即 Model、View、Controller, 那MVP就Model、View、Presenter。Model用于提供数据模型,View用于显示数据,当然Presenter也就用来处理业务逻辑并将数据显示数据到View上了,它是Model和View的桥梁。

题外话,其实在15年的时候,我们公司的项目就采用mvp,当时没时间写,最近看时间不紧,就分享下

我将整个项目分为三个Module,如下图

     

android 应用模式之mvp_ide

其实这种结构我是不太喜欢的,我喜欢在app的根目录下,新建一个liabary文件,这里放第三方的库工程;

一、数据处理模块domain(包含Model),这里的domain命名只是我喜欢这样把数据处理相关的东西都放在这里。

      

android 应用模式之mvp_android_02

      ServiceManager用于向外提供数据的入口(其他类代码在前面博文中已提及)


[java] 
​​view plain​​​
​​​copy​​




1. package com.micky.retrofitrxandroiddragger2.domain.service;
2.
3. import retrofit.GsonConverterFactory;
4. import retrofit.Retrofit;
5. import retrofit.RxJavaCallAdapterFactory;
6.
7.
8. public class ServiceManager {
9. private static final String ENDPOINT = "http://ip.taobao.com";
10.
11. private static class ServiceManagerHolder {
12. private static final ServiceManager INSTANCE = new ServiceManager();
13. }
14.
15. private ServiceManager() {}
16.
17. public static final ServiceManager getInstance() {
18. return ServiceManagerHolder.INSTANCE;
19. }
20.
21. private ApiService mApiService = null;
22.
23. public ApiService getApiService() {
24. if (mApiService == null) {
25. new Retrofit.Builder()
26. .baseUrl(ENDPOINT)
27. .addConverterFactory(GsonConverterFactory.create())
28. .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
29. .build();
30. class);
31. return mApiService;
32. }
33. return mApiService;
34. }
35. }

注:我们在这个manager里面主要做一些网络请求,业务处理,数据组装...


二、View和Presenter模块

      为了方便管理我将View和Presenter相关类都放在Presentation模块中


android 应用模式之mvp_android_03

 

View接口


[java] 
​​view plain​​​
​​​copy​​

1. public interface MainView {
2. void showProgress();
3. void hideProgress();
4. void setIpText(String text);
5. }
6.


Presenter接口


[java] 
​​view plain​​​
​​​copy​​

1. package com.micky.retrofitrxandroiddragger2.presenter;
2.
3.
4. public interface MainPresenter extends BasePresenter {
5. void getIpInfo(String ip);
6. }

Presenter实现类


[java] 
​​view plain​​​
​​​copy​​

1. package com.micky.retrofitrxandroiddragger2.presenter.impl;
2.
3. import android.text.TextUtils;
4. import android.util.Log;
5. import android.widget.Toast;
6.
7. import com.micky.retrofitrxandroiddragger2.BaseApplication;
8. import com.micky.retrofitrxandroiddragger2.R;
9. import com.micky.retrofitrxandroiddragger2.domain.service.ServiceManager;
10. import com.micky.retrofitrxandroiddragger2.domain.service.response.GetIpInfoResponse;
11. import com.micky.retrofitrxandroiddragger2.presenter.MainPresenter;
12. import com.micky.retrofitrxandroiddragger2.presenter.impl.BasePresenterImpl;
13. import com.micky.retrofitrxandroiddragger2.ui.view.MainView;
14.
15. import rx.Subscriber;
16. import rx.android.schedulers.AndroidSchedulers;
17. import rx.schedulers.Schedulers;
18.
19.
20. public class MainPresenterImpl extends BasePresenterImpl implements MainPresenter {
21. private static final String TAG = "TAG";
22. private MainView mMainView;
23.
24. public MainPresenterImpl(MainView mainView) {
25. mMainView = mainView;
26. }
27.
28. @Override
29. public void getIpInfo(String ip) {
30. if (TextUtils.isEmpty(ip)) {
31. Toast.makeText(BaseApplication.getContext(), R.string.input_tip_ip, Toast.LENGTH_SHORT).show();
32. return;
33. }
34. "");
35. mMainView.showProgress();
36. ServiceManager.getInstance().getApiService().getIpInfo(ip)
37. .subscribeOn(Schedulers.io())
38. .observeOn(AndroidSchedulers.mainThread())
39. new Subscriber<GetIpInfoResponse>() {
40. @Override
41. public void onCompleted() {
42. mMainView.hideProgress();
43. }
44.
45. @Override
46. public void onError(Throwable e) {
47. Log.e(TAG, e.getMessage(), e);
48. mMainView.hideProgress();
49. mMainView.setIpText(BaseApplication.getContext().getString(R.string.network_error));
50. }
51.
52. @Override
53. public void onNext(GetIpInfoResponse getIpInfoResponse) {
54. " " + getIpInfoResponse.data.area);
55. }
56. });
57. }
58. }
59. MainActivity



[java]​​view plain​​​​copy​​
1. package com.micky.retrofitrxandroiddragger2.ui.activity;
2.
3. import android.os.Bundle;
4. import android.support.design.widget.FloatingActionButton;
5. import android.support.v7.app.AppCompatActivity;
6. import android.support.v7.widget.Toolbar;
7. import android.view.View;
8. import android.view.Menu;
9. import android.view.MenuItem;
10. import android.widget.EditText;
11. import android.widget.ProgressBar;
12. import android.widget.TextView;
13.
14. import com.micky.retrofitrxandroiddragger2.R;
15. import com.micky.retrofitrxandroiddragger2.presenter.MainPresenter;
16. import com.micky.retrofitrxandroiddragger2.presenter.impl.MainPresenterImpl;
17. import com.micky.retrofitrxandroiddragger2.ui.view.MainView;
18.
19.
20. public class MainActivity extends AppCompatActivity implements MainView {
21.
22. private EditText mEtIp;
23. private TextView mTvContent;
24. private ProgressBar mProgressBar;
25. private MainPresenter mMainPresenter;
26.
27. @Override
28. protected void onCreate(Bundle savedInstanceState) {
29. super.onCreate(savedInstanceState);
30. setContentView(R.layout.activity_main);
31. Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
32. setSupportActionBar(toolbar);
33.
34. mEtIp = (EditText) findViewById(R.id.et_ip);
35. mTvContent = (TextView) findViewById(R.id.tv_content);
36. mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
37. new MainPresenterImpl(this);
38.
39. FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
40. new View.OnClickListener() {
41. @Override
42. public void onClick(View view) {
43. mMainPresenter.getIpInfo(mEtIp.getText().toString());
44. }
45. });
46. }
47.
48. @Override
49. public boolean onCreateOptionsMenu(Menu menu) {
50. getMenuInflater().inflate(R.menu.menu_main, menu);
51. return true;
52. }
53.
54. @Override
55. public boolean onOptionsItemSelected(MenuItem item) {
56. int id = item.getItemId();
57. if (id == R.id.action_settings) {
58. return true;
59. }
60. return super.onOptionsItemSelected(item);
61. }
62.
63. @Override
64. public void showProgress() {
65. mProgressBar.setVisibility(View.VISIBLE);
66. }
67.
68. @Override
69. public void hideProgress() {
70. mProgressBar.setVisibility(View.GONE);
71. }
72.
73. @Override
74. public void setIpText(String text) {
75. mTvContent.setText(text);
76. }
77. }
  1. OK,代码基本完了,看了上述代码大家也许都会说以前就在一个类里面就搞定的功能,现在怎么多出这么多接口、实现类啊。别急我刚看到这个mvp的时候也这么想,几度写着写着都把它抛之脑后,这类都多得看不过来了。

    仔细研究下不难发现这M、V、P三者的关系还是挺清晰的。

好了就到这里,你也赶快试试吧