├── .idea
└── vcs.xml
└── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
├── androidTest
└── java
│ └── com
│ └── test
│ └── mvp
│ └── mvpdemo
│ └── ExampleInstrumentedTest.java
├── main
├── AndroidManifest.xml
├── java
│ └── com
│ │ └── test
│ │ └── mvp
│ │ └── mvpdemo
│ │ ├── mvc
│ │ └── MainActivity.java
│ │ └── mvp
│ │ ├── v1
│ │ ├── MainContract.java
│ │ ├── model
│ │ │ └── DataModel.java
│ │ ├── presenter
│ │ │ └── MainPresenter.java
│ │ └── view
│ │ │ └── MainActivity.java
│ │ ├── v2
│ │ ├── MainContract.java
│ │ ├── basemvp
│ │ │ ├── BaseActivity.java
│ │ │ ├── BasePresenter.java
│ │ │ ├── IBasePresenter.java
│ │ │ └── IBaseView.java
│ │ ├── model
│ │ │ └── DataModel.java
│ │ ├── presenter
│ │ │ └── MainPresenter.java
│ │ └── view
│ │ │ └── MainActivity.java
│ │ ├── v3
│ │ ├── MainContract.java
│ │ ├── basemvp
│ │ │ ├── BaseActivity.java
│ │ │ ├── BasePresenter.java
│ │ │ ├── IBasePresenter.java
│ │ │ └── IBaseView.java
│ │ ├── model
│ │ │ └── DataModel.java
│ │ ├── presenter
│ │ │ └── MainPresenter.java
│ │ └── view
│ │ │ └── MainActivity.java
│ │ ├── v4
│ │ ├── MainContract.java
│ │ ├── basemvp
│ │ │ ├── BaseActivity.java
│ │ │ ├── BaseModel.java
│ │ │ ├── BasePresenter.java
│ │ │ ├── IBasePresenter.java
│ │ │ └── IBaseView.java
│ │ ├── model
│ │ │ └── DataModel.java
│ │ ├── presenter
│ │ │ └── MainPresenter.java
│ │ └── view
│ │ │ └── MainActivity.java
│ │ ├── v5
│ │ ├── MainContract.java
│ │ ├── basemvp
│ │ │ ├── BaseActivity.java
│ │ │ ├── BaseModel.java
│ │ │ ├── BasePresenter.java
│ │ │ ├── IBasePresenter.java
│ │ │ └── IBaseView.java
│ │ ├── inject
│ │ │ └── InjectPresenter.java
│ │ ├── model
│ │ │ └── DataModel.java
│ │ ├── presenter
│ │ │ └── MainPresenter.java
│ │ └── view
│ │ │ └── MainActivity.java
│ │ ├── v6
│ │ ├── MainContract.java
│ │ ├── SecondContract.java
│ │ ├── basemvp
│ │ │ ├── BaseActivity.java
│ │ │ ├── BaseFragment.java
│ │ │ ├── BaseModel.java
│ │ │ ├── BasePresenter.java
│ │ │ ├── IBasePresenter.java
│ │ │ └── IBaseView.java
│ │ ├── inject
│ │ │ └── InjectPresenter.java
│ │ ├── model
│ │ │ ├── DataModel.java
│ │ │ └── SecondModel.java
│ │ ├── presenter
│ │ │ ├── MainPresenter.java
│ │ │ └── SecondPresenter.java
│ │ └── view
│ │ │ ├── MainActivity.java
│ │ │ ├── SecondActivity.java
│ │ │ └── SecondFragment.java
│ │ └── v7
│ │ ├── MainContract.java
│ │ ├── SecondContract.java
│ │ ├── basemvp
│ │ ├── BaseActivity.java
│ │ ├── BaseFragment.java
│ │ ├── BaseModel.java
│ │ ├── BasePresenter.java
│ │ ├── IBasePresenter.java
│ │ └── IBaseView.java
│ │ ├── inject
│ │ └── InjectPresenter.java
│ │ ├── model
│ │ ├── DataModel.java
│ │ └── SecondModel.java
│ │ ├── presenter
│ │ ├── MainPresenter.java
│ │ └── SecondPresenter.java
│ │ ├── proxy
│ │ ├── IProxy.java
│ │ ├── ProxyActivity.java
│ │ ├── ProxyFragment.java
│ │ └── ProxyImpl.java
│ │ └── view
│ │ ├── MainActivity.java
│ │ ├── SecondActivity.java
│ │ └── SecondFragment.java
└── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable
│ ├── caomei.jpg
│ ├── cheng.jpg
│ ├── huolongguo.jpg
│ ├── ic_launcher_background.xml
│ ├── juzi.jpg
│ ├── lanmei.jpg
│ ├── pingguo.jpg
│ └── xigua.jpg
│ ├── layout
│ ├── activity_main.xml
│ ├── activity_second.xml
│ └── fragment_second.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
└── test
└── java
└── com
└── test
└── mvp
└── mvpdemo
└── ExampleUnitTest.java
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 | defaultConfig {
6 | applicationId "com.test.mvp.mvpdemo"
7 | minSdkVersion 21
8 | targetSdkVersion 28
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | buildToolsVersion '28.0.3'
20 | compileOptions {
21 | sourceCompatibility JavaVersion.VERSION_1_8
22 | targetCompatibility JavaVersion.VERSION_1_8
23 | }
24 | }
25 |
26 | dependencies {
27 | implementation fileTree(include: ['*.jar'], dir: 'libs')
28 | implementation 'com.android.support:appcompat-v7:28.+'
29 | implementation 'com.android.support:design:28.0.0'
30 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
31 | testImplementation 'junit:junit:4.12'
32 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
33 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
34 | implementation("com.squareup.okhttp3:okhttp:4.0.0")
35 | }
36 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/test/mvp/mvpdemo/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.test.mvp.mvpdemo", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvc/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvc;
2 |
3 | import android.app.ProgressDialog;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.widget.TextView;
8 | import android.widget.Toast;
9 |
10 | import com.test.mvp.mvpdemo.R;
11 |
12 | import java.io.IOException;
13 |
14 | import okhttp3.Call;
15 | import okhttp3.Callback;
16 | import okhttp3.OkHttpClient;
17 | import okhttp3.Request;
18 | import okhttp3.Response;
19 |
20 | /**
21 | * 一般 MVC 的写法
22 | *
23 | * @author 神探丶威威猫
24 | * @blog https://blog.csdn.net/smile_running
25 | * @warning 点个赞哦,评个论哦
26 | */
27 | public class MainActivity extends AppCompatActivity {
28 |
29 | private TextView tv;
30 | private static final String TAG = "MainActivity";
31 |
32 | @Override
33 | protected void onCreate(Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 | setContentView(R.layout.activity_main);
36 |
37 | initViews();
38 |
39 | request();
40 | showDialog();
41 | }
42 |
43 | private void initViews() {
44 | tv = findViewById(R.id.tv);
45 | }
46 |
47 | private void showDialog() {
48 | ProgressDialog dialog = new ProgressDialog(this);
49 | dialog.show();
50 | new Handler().postDelayed(new Runnable() {
51 | @Override
52 | public void run() {
53 | dialog.dismiss();
54 | }
55 | }, 1500);
56 | }
57 |
58 | private void request() {
59 | OkHttpClient client = new OkHttpClient();
60 | Request request = new Request.Builder()
61 | .url("https://www.baidu.com/")
62 | .build();
63 | client.newCall(request).enqueue(new Callback() {
64 | @Override
65 | public void onFailure(Call call, IOException e) {
66 | }
67 |
68 | @Override
69 | public void onResponse(Call call, Response response) throws IOException {
70 | String resp = response.body().string();
71 | toast(resp);
72 | }
73 | });
74 | }
75 |
76 | private void toast(String resp) {
77 | runOnUiThread(new Runnable() {
78 | @Override
79 | public void run() {
80 | Toast.makeText(MainActivity.this, "" + resp, Toast.LENGTH_SHORT).show();
81 | tv.setText(resp);
82 | }
83 | });
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v1/MainContract.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v1;
2 |
3 | import okhttp3.Callback;
4 |
5 | /**
6 | * 契约接口,可以很直观的看到 M、V、P 层接口中提供的方法
7 | */
8 | public interface MainContract {
9 | interface IMainModel {
10 | void requestBaidu(Callback callback);
11 | }
12 |
13 | interface IMainView {
14 | void showDialog();
15 |
16 | void succes(String content);
17 | }
18 |
19 | interface IMainPresenter {
20 | void handlerData();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v1/model/DataModel.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v1.model;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v1.MainContract;
4 |
5 | import okhttp3.Callback;
6 | import okhttp3.OkHttpClient;
7 | import okhttp3.Request;
8 |
9 | /**
10 | * model 层,请求网络或数据库,提供数据源(原始数据)
11 | */
12 | public class DataModel implements MainContract.IMainModel {
13 |
14 | @Override
15 | public void requestBaidu(Callback callback) {
16 | OkHttpClient client = new OkHttpClient();
17 | Request request = new Request.Builder()
18 | .url("https://www.baidu.com/")
19 | .build();
20 | client.newCall(request).enqueue(callback);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v1/presenter/MainPresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v1.presenter;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v1.MainContract;
4 | import com.test.mvp.mvpdemo.mvp.v1.model.DataModel;
5 |
6 | import java.io.IOException;
7 |
8 | import okhttp3.Call;
9 | import okhttp3.Callback;
10 | import okhttp3.Response;
11 |
12 | /**
13 | * presenter 层,承担业务逻辑处理,数据源处理等
14 | */
15 | public class MainPresenter implements MainContract.IMainPresenter {
16 |
17 | private MainContract.IMainModel mModel;
18 | private MainContract.IMainView mView;
19 |
20 | public MainPresenter(MainContract.IMainView view) {
21 | this.mView = view;
22 | mModel = new DataModel();
23 | }
24 |
25 | @Override
26 | public void handlerData() {
27 | if (mView != null) {
28 | mView.showDialog();
29 | }
30 | /**
31 | * 发起请求,获得回调数据
32 | */
33 | mModel.requestBaidu(new Callback() {
34 | @Override
35 | public void onFailure(Call call, IOException e) {
36 | }
37 |
38 | @Override
39 | public void onResponse(Call call, Response response) throws IOException {
40 | String content = response.body().string();
41 | if (mView != null) {
42 | mView.succes(content);
43 | }
44 | }
45 | });
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v1/view/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v1.view;
2 |
3 | import android.app.ProgressDialog;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.widget.TextView;
8 | import android.widget.Toast;
9 |
10 | import com.test.mvp.mvpdemo.R;
11 | import com.test.mvp.mvpdemo.mvp.v1.MainContract;
12 | import com.test.mvp.mvpdemo.mvp.v1.presenter.MainPresenter;
13 |
14 | /**
15 | * MVP 的写法,Version 1: 基础写法
16 | *
17 | * @author 神探丶威威猫
18 | * @blog https://blog.csdn.net/smile_running
19 | * @warning 点个赞哦,评个论哦
20 | */
21 | public class MainActivity extends AppCompatActivity implements MainContract.IMainView {
22 |
23 | private TextView tv;
24 |
25 | private MainPresenter mPresenter;
26 |
27 | @Override
28 | protected void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_main);
31 |
32 | initViews();
33 |
34 | mPresenter = new MainPresenter(this);
35 | mPresenter.handlerData();
36 | }
37 |
38 | private void initViews() {
39 | tv = findViewById(R.id.tv);
40 | }
41 |
42 | @Override
43 | public void showDialog() {
44 | ProgressDialog dialog = new ProgressDialog(this);
45 | dialog.show();
46 | new Handler().postDelayed(new Runnable() {
47 | @Override
48 | public void run() {
49 | dialog.dismiss();
50 | }
51 | }, 1500);
52 | }
53 |
54 | @Override
55 | public void succes(String content) {
56 | runOnUiThread(new Runnable() {
57 | @Override
58 | public void run() {
59 | Toast.makeText(MainActivity.this, "" + content, Toast.LENGTH_SHORT).show();
60 | tv.setText(content);
61 | }
62 | });
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v2/MainContract.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v2;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v2.basemvp.IBasePresenter;
4 | import com.test.mvp.mvpdemo.mvp.v2.basemvp.IBaseView;
5 |
6 | import okhttp3.Callback;
7 |
8 | /**
9 | * 契约接口,可以很直观的看到 M、V、P 层接口中提供的方法
10 | */
11 | public interface MainContract {
12 | interface IMainModel {
13 | void requestBaidu(Callback callback);
14 | }
15 |
16 | interface IMainView extends IBaseView{
17 | void showDialog();
18 |
19 | void succes(String content);
20 | }
21 |
22 | interface IMainPresenter extends IBasePresenter {
23 | void handlerData();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v2/basemvp/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v2.basemvp;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.support.annotation.IdRes;
6 | import android.support.annotation.Nullable;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.view.View;
9 |
10 | public abstract class BaseActivity
extends AppCompatActivity implements IBaseView {
11 |
12 | protected P mPresenter;
13 |
14 | protected abstract void initLayout(@Nullable Bundle savedInstanceState);
15 |
16 | protected abstract void initViews();
17 |
18 | protected abstract void initData();
19 |
20 | protected abstract P setPresenter();
21 |
22 | protected T $(@IdRes int viewId) {
23 | return findViewById(viewId);
24 | }
25 |
26 | @SuppressWarnings("unchecked")
27 | @Override
28 | protected void onCreate(@Nullable Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 |
31 | initLayout(savedInstanceState);
32 |
33 | /**
34 | * 实例化和绑定 P 层
35 | */
36 | mPresenter = setPresenter();
37 | mPresenter.attech(this);
38 |
39 | initViews();
40 | initData();
41 | }
42 |
43 | @Override
44 | protected void onDestroy() {
45 | super.onDestroy();
46 | /**
47 | * 解绑,避免内存泄漏
48 | */
49 | mPresenter.detech();
50 | mPresenter = null;
51 | }
52 |
53 | @Override
54 | public Context getContext() {
55 | return this;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v2/basemvp/BasePresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v2.basemvp;
2 |
3 | public abstract class BasePresenter implements IBasePresenter {
4 | protected V mView;
5 |
6 | @SuppressWarnings("unchecked")
7 | @Override
8 | public void attech(IBaseView view) {
9 | mView = (V) view;
10 | }
11 |
12 | @Override
13 | public void detech() {
14 | mView = null;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v2/basemvp/IBasePresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v2.basemvp;
2 |
3 | public interface IBasePresenter {
4 |
5 | void attech(V view);
6 |
7 | void detech();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v2/basemvp/IBaseView.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v2.basemvp;
2 |
3 | import android.content.Context;
4 |
5 | public interface IBaseView {
6 |
7 | Context getContext();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v2/model/DataModel.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v2.model;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v2.MainContract;
4 |
5 | import okhttp3.Callback;
6 | import okhttp3.OkHttpClient;
7 | import okhttp3.Request;
8 |
9 | /**
10 | * model 层,请求网络或数据库,提供数据源(原始数据)
11 | */
12 | public class DataModel implements MainContract.IMainModel {
13 |
14 | @Override
15 | public void requestBaidu(Callback callback) {
16 | OkHttpClient client = new OkHttpClient();
17 | Request request = new Request.Builder()
18 | .url("https://www.baidu.com/")
19 | .build();
20 | client.newCall(request).enqueue(callback);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v2/presenter/MainPresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v2.presenter;
2 |
3 | import android.util.Log;
4 |
5 | import com.test.mvp.mvpdemo.mvp.v2.MainContract;
6 | import com.test.mvp.mvpdemo.mvp.v2.basemvp.BasePresenter;
7 | import com.test.mvp.mvpdemo.mvp.v2.basemvp.IBaseView;
8 | import com.test.mvp.mvpdemo.mvp.v2.model.DataModel;
9 |
10 | import java.io.IOException;
11 |
12 | import okhttp3.Call;
13 | import okhttp3.Callback;
14 | import okhttp3.Response;
15 |
16 | /**
17 | * presenter 层,承担业务逻辑处理,数据源处理等
18 | */
19 | public class MainPresenter extends BasePresenter implements MainContract.IMainPresenter {
20 |
21 | private MainContract.IMainModel mModel;
22 |
23 | @Override
24 | public void attech(IBaseView view) {
25 | super.attech(view);
26 | mModel = new DataModel();
27 | }
28 |
29 | @Override
30 | public void handlerData() {
31 | if (mView != null) {
32 | mView.showDialog();
33 | }
34 | /**
35 | * 发起请求,获得回调数据
36 | */
37 | mModel.requestBaidu(new Callback() {
38 | @Override
39 | public void onFailure(Call call, IOException e) {
40 | }
41 |
42 | @Override
43 | public void onResponse(Call call, Response response) throws IOException {
44 | String content = response.body().string();
45 | if (mView != null) {
46 | mView.succes(content);
47 | }
48 | }
49 | });
50 | }
51 |
52 | @Override
53 | public void detech() {
54 | super.detech();
55 | /**
56 | * 释放内存、关闭网络请求、关闭线程等操作
57 | */
58 | Log.d("==========", "detech: 解除绑定,释放内存");
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v2/view/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v2.view;
2 |
3 | import android.app.Activity;
4 | import android.app.ProgressDialog;
5 | import android.content.Context;
6 | import android.os.Bundle;
7 | import android.os.Handler;
8 | import android.support.annotation.Nullable;
9 | import android.widget.TextView;
10 | import android.widget.Toast;
11 |
12 | import com.test.mvp.mvpdemo.R;
13 | import com.test.mvp.mvpdemo.mvp.v2.MainContract;
14 | import com.test.mvp.mvpdemo.mvp.v2.basemvp.BaseActivity;
15 | import com.test.mvp.mvpdemo.mvp.v2.presenter.MainPresenter;
16 |
17 | /**
18 | * MVP 的写法,Version 2: 使用模板方法模式 + 泛型 封装 mvp 基类
19 | *
20 | * @author 神探丶威威猫
21 | * @blog https://blog.csdn.net/smile_running
22 | * @warning 点个赞哦,评个论哦
23 | */
24 | public class MainActivity extends BaseActivity implements MainContract.IMainView {
25 |
26 | private TextView tv;
27 |
28 | @Override
29 | protected void initLayout(@Nullable Bundle savedInstanceState) {
30 | setContentView(R.layout.activity_main);
31 | }
32 |
33 | @Override
34 | protected void initViews() {
35 | tv = $(R.id.tv);
36 | }
37 |
38 | @Override
39 | protected void initData() {
40 | mPresenter.handlerData();
41 | }
42 |
43 | @Override
44 | protected MainContract.IMainPresenter setPresenter() {
45 | return new MainPresenter();
46 | }
47 |
48 | @Override
49 | public void showDialog() {
50 | ProgressDialog dialog = new ProgressDialog(getContext());
51 | dialog.show();
52 | new Handler().postDelayed(new Runnable() {
53 | @Override
54 | public void run() {
55 | dialog.dismiss();
56 | }
57 | }, 1500);
58 | }
59 |
60 | @Override
61 | public void succes(String content) {
62 | runOnUiThread(new Runnable() {
63 | @Override
64 | public void run() {
65 | Toast.makeText(getContext(), "" + content, Toast.LENGTH_SHORT).show();
66 | tv.setText(content);
67 | }
68 | });
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v3/MainContract.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v3;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v3.basemvp.IBasePresenter;
4 | import com.test.mvp.mvpdemo.mvp.v3.basemvp.IBaseView;
5 |
6 | import okhttp3.Callback;
7 |
8 | /**
9 | * 契约接口,可以很直观的看到 M、V、P 层接口中提供的方法
10 | */
11 | public interface MainContract {
12 | interface IMainModel {
13 | void requestBaidu(Callback callback);
14 | }
15 |
16 | interface IMainView extends IBaseView {
17 | void showDialog();
18 |
19 | void succes(String content);
20 | }
21 |
22 | interface IMainPresenter extends IBasePresenter {
23 | void handlerData();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v3/basemvp/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v3.basemvp;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.support.annotation.IdRes;
6 | import android.support.annotation.Nullable;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.view.View;
9 |
10 | public abstract class BaseActivity extends AppCompatActivity implements IBaseView {
11 |
12 | private P mPresenter;
13 |
14 | protected abstract void initLayout(@Nullable Bundle savedInstanceState);
15 |
16 | protected abstract P setPresenter();
17 |
18 | protected abstract void initViews();
19 |
20 | protected abstract void initData();
21 |
22 |
23 | @SuppressWarnings("SameParameterValue")
24 | protected T $(@IdRes int viewId) {
25 | return findViewById(viewId);
26 | }
27 |
28 | @SuppressWarnings("unchecked")
29 | @Override
30 | protected void onCreate(@Nullable Bundle savedInstanceState) {
31 | super.onCreate(savedInstanceState);
32 |
33 | initLayout(savedInstanceState);
34 |
35 | /**
36 | * 实例化和绑定 P 层
37 | */
38 | this.mPresenter = setPresenter();
39 | this.mPresenter.attech(this);
40 |
41 | initViews();
42 | initData();
43 | }
44 |
45 | @Override
46 | protected void onDestroy() {
47 | super.onDestroy();
48 | /**
49 | * 解绑,避免内存泄漏
50 | */
51 | this.mPresenter.detech();
52 | this.mPresenter = null;
53 | }
54 |
55 | @Override
56 | public Context getContext() {
57 | return this;
58 | }
59 |
60 | public P getPresenter() {
61 | return mPresenter;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v3/basemvp/BasePresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v3.basemvp;
2 |
3 | import java.lang.ref.SoftReference;
4 | import java.lang.reflect.InvocationHandler;
5 | import java.lang.reflect.Method;
6 | import java.lang.reflect.Proxy;
7 |
8 | public abstract class BasePresenter implements IBasePresenter {
9 | private SoftReference mReferenceView;
10 | private V mProxyView;
11 |
12 | @SuppressWarnings("unchecked")
13 | @Override
14 | public void attech(IBaseView view) {
15 | mReferenceView = new SoftReference<>(view);
16 | mProxyView = (V) Proxy.newProxyInstance(view.getClass().getClassLoader(), view.getClass().getInterfaces(), new InvocationHandler() {
17 | @Override
18 | public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
19 | if (mReferenceView == null || mReferenceView.get() == null) {
20 | return null;
21 | }
22 | return method.invoke(mReferenceView.get(), objects);
23 | }
24 | });
25 | }
26 |
27 | @SuppressWarnings("unchecked")
28 | public V getView() {
29 | return mProxyView;
30 | }
31 |
32 | @Override
33 | public void detech() {
34 | mReferenceView.clear();
35 | mReferenceView = null;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v3/basemvp/IBasePresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v3.basemvp;
2 |
3 | public interface IBasePresenter {
4 |
5 | void attech(IBaseView view);
6 |
7 | void detech();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v3/basemvp/IBaseView.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v3.basemvp;
2 |
3 | import android.content.Context;
4 |
5 | public interface IBaseView {
6 |
7 | Context getContext();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v3/model/DataModel.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v3.model;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v3.MainContract;
4 |
5 | import okhttp3.Callback;
6 | import okhttp3.OkHttpClient;
7 | import okhttp3.Request;
8 |
9 | /**
10 | * model 层,请求网络或数据库,提供数据源(原始数据)
11 | */
12 | public class DataModel implements MainContract.IMainModel {
13 |
14 | @Override
15 | public void requestBaidu(Callback callback) {
16 | OkHttpClient client = new OkHttpClient();
17 | Request request = new Request.Builder()
18 | .url("https://www.baidu.com/")
19 | .build();
20 | client.newCall(request).enqueue(callback);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v3/presenter/MainPresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v3.presenter;
2 |
3 | import android.util.Log;
4 |
5 | import com.test.mvp.mvpdemo.mvp.v3.MainContract;
6 | import com.test.mvp.mvpdemo.mvp.v3.basemvp.BasePresenter;
7 | import com.test.mvp.mvpdemo.mvp.v3.basemvp.IBaseView;
8 | import com.test.mvp.mvpdemo.mvp.v3.model.DataModel;
9 |
10 | import java.io.IOException;
11 |
12 | import okhttp3.Call;
13 | import okhttp3.Callback;
14 | import okhttp3.Response;
15 |
16 | /**
17 | * presenter 层,承担业务逻辑处理,数据源处理等
18 | */
19 | public class MainPresenter extends BasePresenter implements MainContract.IMainPresenter {
20 |
21 | private MainContract.IMainModel mModel;
22 |
23 | @Override
24 | public void attech(IBaseView view) {
25 | super.attech(view);
26 | mModel = new DataModel();
27 | }
28 |
29 | @Override
30 | public void handlerData() {
31 | getView().showDialog();
32 |
33 | mModel.requestBaidu(new Callback() {
34 | @Override
35 | public void onFailure(Call call, IOException e) {
36 | }
37 |
38 | @Override
39 | public void onResponse(Call call, Response response) throws IOException {
40 | String content = response.body().string();
41 | getView().succes(content);
42 | }
43 | });
44 | }
45 |
46 | @Override
47 | public void detech() {
48 | super.detech();
49 | /**
50 | * 释放内存、关闭网络请求、关闭线程等操作
51 | */
52 | Log.d("==========", "detech: 解除绑定,释放内存");
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v3/view/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v3.view;
2 |
3 | import android.app.ProgressDialog;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.support.annotation.Nullable;
7 | import android.widget.TextView;
8 | import android.widget.Toast;
9 |
10 | import com.test.mvp.mvpdemo.R;
11 | import com.test.mvp.mvpdemo.mvp.v3.MainContract;
12 | import com.test.mvp.mvpdemo.mvp.v3.basemvp.BaseActivity;
13 | import com.test.mvp.mvpdemo.mvp.v3.presenter.MainPresenter;
14 |
15 | /**
16 | * MVP 的写法,Version 3: 使用软引用 + 动态代理
17 | *
18 | * @author 神探丶威威猫
19 | * @blog https://blog.csdn.net/smile_running
20 | * @warning 点个赞哦,评个论哦
21 | */
22 | public class MainActivity extends BaseActivity implements MainContract.IMainView {
23 |
24 | private TextView tv;
25 |
26 | @Override
27 | protected void initLayout(@Nullable Bundle savedInstanceState) {
28 | setContentView(R.layout.activity_main);
29 | }
30 |
31 | @Override
32 | protected void initViews() {
33 | tv = $(R.id.tv);
34 | }
35 |
36 | @Override
37 | protected void initData() {
38 | getPresenter().handlerData();
39 | }
40 |
41 | @Override
42 | protected MainContract.IMainPresenter setPresenter() {
43 | return new MainPresenter();
44 | }
45 |
46 | @Override
47 | public void showDialog() {
48 | ProgressDialog dialog = new ProgressDialog(getContext());
49 | dialog.show();
50 | new Handler().postDelayed(new Runnable() {
51 | @Override
52 | public void run() {
53 | dialog.dismiss();
54 | }
55 | }, 1500);
56 | }
57 |
58 | @Override
59 | public void succes(String content) {
60 | runOnUiThread(new Runnable() {
61 | @Override
62 | public void run() {
63 | Toast.makeText(getContext(), "" + content, Toast.LENGTH_SHORT).show();
64 | tv.setText(content);
65 | }
66 | });
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v4/MainContract.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v4;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v4.basemvp.IBasePresenter;
4 | import com.test.mvp.mvpdemo.mvp.v4.basemvp.IBaseView;
5 |
6 | import okhttp3.Callback;
7 |
8 | /**
9 | * 契约接口,可以很直观的看到 M、V、P 层接口中提供的方法
10 | */
11 | public interface MainContract {
12 | interface IMainModel {
13 | void requestBaidu(Callback callback);
14 | }
15 |
16 | interface IMainView extends IBaseView {
17 | void showDialog();
18 |
19 | void succes(String content);
20 | }
21 |
22 | interface IMainPresenter extends IBasePresenter {
23 | void handlerData();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v4/basemvp/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v4.basemvp;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.support.annotation.IdRes;
6 | import android.support.annotation.Nullable;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.view.View;
9 |
10 | public abstract class BaseActivity extends AppCompatActivity implements IBaseView {
11 |
12 | private P mPresenter;
13 |
14 | protected abstract void initLayout(@Nullable Bundle savedInstanceState);
15 |
16 | protected abstract P setPresenter();
17 |
18 | protected abstract void initViews();
19 |
20 | protected abstract void initData();
21 |
22 |
23 | @SuppressWarnings("SameParameterValue")
24 | protected T $(@IdRes int viewId) {
25 | return findViewById(viewId);
26 | }
27 |
28 | @SuppressWarnings("unchecked")
29 | @Override
30 | protected void onCreate(@Nullable Bundle savedInstanceState) {
31 | super.onCreate(savedInstanceState);
32 |
33 | initLayout(savedInstanceState);
34 |
35 | /**
36 | * 实例化和绑定 P 层
37 | */
38 | this.mPresenter = setPresenter();
39 | this.mPresenter.attach(this);
40 |
41 | initViews();
42 | initData();
43 | }
44 |
45 | @Override
46 | protected void onDestroy() {
47 | super.onDestroy();
48 | /**
49 | * 解绑,避免内存泄漏
50 | */
51 | this.mPresenter.detach();
52 | this.mPresenter = null;
53 | }
54 |
55 | @Override
56 | public Context getContext() {
57 | return this;
58 | }
59 |
60 | public P getPresenter() {
61 | return mPresenter;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v4/basemvp/BaseModel.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v4.basemvp;
2 |
3 | public abstract class BaseModel {
4 | }
5 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v4/basemvp/BasePresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v4.basemvp;
2 |
3 | import android.util.Log;
4 |
5 | import java.lang.ref.SoftReference;
6 | import java.lang.reflect.InvocationHandler;
7 | import java.lang.reflect.Method;
8 | import java.lang.reflect.ParameterizedType;
9 | import java.lang.reflect.Proxy;
10 | import java.lang.reflect.Type;
11 |
12 | public abstract class BasePresenter implements IBasePresenter {
13 | private SoftReference mReferenceView;
14 | private V mProxyView;
15 | private M mModel;
16 |
17 | @SuppressWarnings({"unchecked", "TryWithIdenticalCatches"})
18 | @Override
19 | public void attach(IBaseView view) {
20 | //使用软引用创建对象
21 | mReferenceView = new SoftReference<>(view);
22 | //使用动态代理做统一的逻辑判断 aop 思想
23 | mProxyView = (V) Proxy.newProxyInstance(view.getClass().getClassLoader(), view.getClass().getInterfaces(), new InvocationHandler() {
24 | @Override
25 | public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
26 | if (mReferenceView == null || mReferenceView.get() == null) {
27 | return null;
28 | }
29 | return method.invoke(mReferenceView.get(), objects);
30 | }
31 | });
32 |
33 | //通过获得泛型类的父类,拿到泛型的接口类实例,通过反射来实例化 model
34 | ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
35 |
36 | Log.d("===========", "attach: "+this.getClass().getSimpleName());
37 | if (type != null) {
38 | Type[] types = type.getActualTypeArguments();
39 | try {
40 | mModel = (M) ((Class>) types[1]).newInstance();
41 | } catch (IllegalAccessException e) {
42 | e.printStackTrace();
43 | } catch (InstantiationException e) {
44 | e.printStackTrace();
45 | }
46 | }
47 |
48 | }
49 |
50 | @SuppressWarnings("unchecked")
51 | public V getView() {
52 | return mProxyView;
53 | }
54 |
55 | protected M getModel() {
56 | return mModel;
57 | }
58 |
59 | @Override
60 | public void detach() {
61 | mReferenceView.clear();
62 | mReferenceView = null;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v4/basemvp/IBasePresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v4.basemvp;
2 |
3 | public interface IBasePresenter {
4 |
5 | void attach(IBaseView view);
6 |
7 | void detach();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v4/basemvp/IBaseView.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v4.basemvp;
2 |
3 | import android.content.Context;
4 |
5 | public interface IBaseView {
6 |
7 | Context getContext();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v4/model/DataModel.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v4.model;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v4.MainContract;
4 | import com.test.mvp.mvpdemo.mvp.v4.basemvp.BaseModel;
5 |
6 | import okhttp3.Callback;
7 | import okhttp3.OkHttpClient;
8 | import okhttp3.Request;
9 |
10 | /**
11 | * model 层,请求网络或数据库,提供数据源(原始数据)
12 | */
13 | public class DataModel extends BaseModel implements MainContract.IMainModel {
14 |
15 | @Override
16 | public void requestBaidu(Callback callback) {
17 | OkHttpClient client = new OkHttpClient();
18 | Request request = new Request.Builder()
19 | .url("https://www.baidu.com/")
20 | .build();
21 | client.newCall(request).enqueue(callback);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v4/presenter/MainPresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v4.presenter;
2 |
3 | import android.util.Log;
4 |
5 | import com.test.mvp.mvpdemo.mvp.v4.MainContract;
6 | import com.test.mvp.mvpdemo.mvp.v4.basemvp.BaseModel;
7 | import com.test.mvp.mvpdemo.mvp.v4.basemvp.BasePresenter;
8 | import com.test.mvp.mvpdemo.mvp.v4.basemvp.IBaseView;
9 | import com.test.mvp.mvpdemo.mvp.v4.model.DataModel;
10 |
11 | import java.io.IOException;
12 |
13 | import okhttp3.Call;
14 | import okhttp3.Callback;
15 | import okhttp3.Response;
16 |
17 | /**
18 | * presenter 层,承担业务逻辑处理,数据源处理等
19 | */
20 | public class MainPresenter extends BasePresenter implements MainContract.IMainPresenter {
21 |
22 | @Override
23 | public void handlerData() {
24 | getView().showDialog();
25 |
26 | getModel().requestBaidu(new Callback() {
27 | @Override
28 | public void onFailure(Call call, IOException e) {
29 | }
30 |
31 | @Override
32 | public void onResponse(Call call, Response response) throws IOException {
33 | String content = response.body().string();
34 | getView().succes(content);
35 | }
36 | });
37 | }
38 |
39 | @Override
40 | public void detach() {
41 | super.detach();
42 | /**
43 | * 释放内存、关闭网络请求、关闭线程等操作
44 | */
45 | Log.d("==========", "detech: 解除绑定,释放内存");
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v4/view/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v4.view;
2 |
3 | import android.app.ProgressDialog;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.support.annotation.Nullable;
7 | import android.widget.TextView;
8 | import android.widget.Toast;
9 |
10 | import com.test.mvp.mvpdemo.R;
11 | import com.test.mvp.mvpdemo.mvp.v4.MainContract;
12 | import com.test.mvp.mvpdemo.mvp.v4.basemvp.BaseActivity;
13 | import com.test.mvp.mvpdemo.mvp.v4.presenter.MainPresenter;
14 |
15 | /**
16 | * MVP 的写法,Version 4: 动态创建 Model
17 | *
18 | * @author 神探丶威威猫
19 | * @blog https://blog.csdn.net/smile_running
20 | * @warning 点个赞哦,评个论哦
21 | */
22 | public class MainActivity extends BaseActivity implements MainContract.IMainView {
23 |
24 | private TextView tv;
25 |
26 | @Override
27 | protected void initLayout(@Nullable Bundle savedInstanceState) {
28 | setContentView(R.layout.activity_main);
29 | }
30 |
31 | @Override
32 | protected void initViews() {
33 | tv = $(R.id.tv);
34 | }
35 |
36 | @Override
37 | protected void initData() {
38 | getPresenter().handlerData();
39 | }
40 |
41 | @Override
42 | protected MainContract.IMainPresenter setPresenter() {
43 | return new MainPresenter();
44 | }
45 |
46 | @Override
47 | public void showDialog() {
48 | ProgressDialog dialog = new ProgressDialog(getContext());
49 | dialog.show();
50 | new Handler().postDelayed(new Runnable() {
51 | @Override
52 | public void run() {
53 | dialog.dismiss();
54 | }
55 | }, 1500);
56 | }
57 |
58 | @Override
59 | public void succes(String content) {
60 | runOnUiThread(new Runnable() {
61 | @Override
62 | public void run() {
63 | Toast.makeText(getContext(), "" + content, Toast.LENGTH_SHORT).show();
64 | tv.setText(content);
65 | }
66 | });
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v5/MainContract.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v5;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v5.basemvp.IBasePresenter;
4 | import com.test.mvp.mvpdemo.mvp.v5.basemvp.IBaseView;
5 |
6 | import okhttp3.Callback;
7 |
8 | /**
9 | * 契约接口,可以很直观的看到 M、V、P 层接口中提供的方法
10 | */
11 | public interface MainContract {
12 | interface IMainModel {
13 | void requestBaidu(Callback callback);
14 | }
15 |
16 | interface IMainView extends IBaseView {
17 | void showDialog();
18 |
19 | void succes(String content);
20 | }
21 |
22 | interface IMainPresenter extends IBasePresenter {
23 | void handlerData();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v5/basemvp/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v5.basemvp;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.support.annotation.IdRes;
6 | import android.support.annotation.Nullable;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.view.View;
9 |
10 | import com.test.mvp.mvpdemo.mvp.v5.inject.InjectPresenter;
11 |
12 | import java.lang.reflect.Field;
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | public abstract class BaseActivity extends AppCompatActivity implements IBaseView {
17 |
18 | private P mPresenter;
19 |
20 | /**
21 | * 保存使用注解的 Presenter ,用于解绑
22 | */
23 | private List mInjectPresenters;
24 |
25 | protected abstract void initLayout(@Nullable Bundle savedInstanceState);
26 |
27 | protected abstract P setPresenter();
28 |
29 | protected abstract void initViews();
30 |
31 | protected abstract void initData();
32 |
33 |
34 | @SuppressWarnings("SameParameterValue")
35 | protected T $(@IdRes int viewId) {
36 | return findViewById(viewId);
37 | }
38 |
39 | @SuppressWarnings({"unchecked", "TryWithIdenticalCatches"})
40 | @Override
41 | protected void onCreate(@Nullable Bundle savedInstanceState) {
42 | super.onCreate(savedInstanceState);
43 |
44 | initLayout(savedInstanceState);
45 |
46 | /**
47 | * 实例化和绑定 P 层
48 | */
49 | this.mPresenter = setPresenter();
50 | if (mPresenter != null) {
51 | this.mPresenter.attach(this);
52 | }
53 |
54 | mInjectPresenters = new ArrayList<>();
55 |
56 | //获得已经申明的变量,包括私有的
57 | Field[] fields = this.getClass().getDeclaredFields();
58 | for (Field field : fields) {
59 | //获取变量上面的注解类型
60 | InjectPresenter injectPresenter = field.getAnnotation(InjectPresenter.class);
61 | if (injectPresenter != null) {
62 | try {
63 | Class extends BasePresenter> type = (Class extends BasePresenter>) field.getType();
64 | BasePresenter mInjectPresenter = type.newInstance();
65 | mInjectPresenter.attach(this);
66 | field.setAccessible(true);
67 | field.set(this, mInjectPresenter);
68 | mInjectPresenters.add(mInjectPresenter);
69 | } catch (IllegalAccessException e) {
70 | e.printStackTrace();
71 | } catch (InstantiationException e) {
72 | e.printStackTrace();
73 | }catch (ClassCastException e){
74 | e.printStackTrace();
75 | throw new RuntimeException("SubClass must extends Class:BasePresenter");
76 | }
77 | }
78 | }
79 |
80 | initViews();
81 | initData();
82 | }
83 |
84 | @Override
85 | protected void onDestroy() {
86 | super.onDestroy();
87 | /**
88 | * 解绑,避免内存泄漏
89 | */
90 | this.mPresenter.detach();
91 | this.mPresenter = null;
92 | for (BasePresenter presenter : mInjectPresenters) {
93 | presenter.detach();
94 | }
95 | mInjectPresenters.clear();
96 | mInjectPresenters = null;
97 | }
98 |
99 | @Override
100 | public Context getContext() {
101 | return this;
102 | }
103 |
104 | public P getPresenter() {
105 | return mPresenter;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v5/basemvp/BaseModel.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v5.basemvp;
2 |
3 | public abstract class BaseModel {
4 | }
5 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v5/basemvp/BasePresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v5.basemvp;
2 |
3 | import java.lang.ref.SoftReference;
4 | import java.lang.reflect.InvocationHandler;
5 | import java.lang.reflect.Method;
6 | import java.lang.reflect.ParameterizedType;
7 | import java.lang.reflect.Proxy;
8 | import java.lang.reflect.Type;
9 |
10 | public abstract class BasePresenter implements IBasePresenter {
11 | private SoftReference mReferenceView;
12 | private V mProxyView;
13 | private M mModel;
14 |
15 | @SuppressWarnings({"unchecked", "TryWithIdenticalCatches"})
16 | @Override
17 | public void attach(IBaseView view) {
18 | //使用软引用创建对象
19 | mReferenceView = new SoftReference<>(view);
20 | //使用动态代理做统一的逻辑判断 aop 思想
21 | mProxyView = (V) Proxy.newProxyInstance(view.getClass().getClassLoader(), view.getClass().getInterfaces(), new InvocationHandler() {
22 | @Override
23 | public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
24 | if (mReferenceView == null || mReferenceView.get() == null) {
25 | return null;
26 | }
27 | return method.invoke(mReferenceView.get(), objects);
28 | }
29 | });
30 |
31 | //通过获得泛型类的父类,拿到泛型的接口类实例,通过反射来实例化 model
32 | ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
33 | if (type != null) {
34 | Type[] types = type.getActualTypeArguments();
35 | try {
36 | mModel = (M) ((Class>) types[1]).newInstance();
37 | } catch (IllegalAccessException e) {
38 | e.printStackTrace();
39 | } catch (InstantiationException e) {
40 | e.printStackTrace();
41 | }
42 | }
43 |
44 | }
45 |
46 | @SuppressWarnings("unchecked")
47 | public V getView() {
48 | return mProxyView;
49 | }
50 |
51 | protected M getModel() {
52 | return mModel;
53 | }
54 |
55 | @Override
56 | public void detach() {
57 | mReferenceView.clear();
58 | mReferenceView = null;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v5/basemvp/IBasePresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v5.basemvp;
2 |
3 | public interface IBasePresenter {
4 |
5 | void attach(IBaseView view);
6 |
7 | void detach();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v5/basemvp/IBaseView.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v5.basemvp;
2 |
3 | import android.content.Context;
4 |
5 | public interface IBaseView {
6 |
7 | Context getContext();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v5/inject/InjectPresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v5.inject;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | @Retention(RetentionPolicy.RUNTIME)
9 | @Target(ElementType.FIELD)
10 | public @interface InjectPresenter {
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v5/model/DataModel.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v5.model;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v5.MainContract;
4 | import com.test.mvp.mvpdemo.mvp.v5.basemvp.BaseModel;
5 |
6 | import okhttp3.Callback;
7 | import okhttp3.OkHttpClient;
8 | import okhttp3.Request;
9 |
10 | /**
11 | * model 层,请求网络或数据库,提供数据源(原始数据)
12 | */
13 | public class DataModel extends BaseModel implements MainContract.IMainModel {
14 |
15 | @Override
16 | public void requestBaidu(Callback callback) {
17 | OkHttpClient client = new OkHttpClient();
18 | Request request = new Request.Builder()
19 | .url("https://www.baidu.com/")
20 | .build();
21 | client.newCall(request).enqueue(callback);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v5/presenter/MainPresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v5.presenter;
2 |
3 | import android.util.Log;
4 |
5 | import com.test.mvp.mvpdemo.mvp.v5.MainContract;
6 | import com.test.mvp.mvpdemo.mvp.v5.basemvp.BasePresenter;
7 | import com.test.mvp.mvpdemo.mvp.v5.model.DataModel;
8 |
9 | import java.io.IOException;
10 |
11 | import okhttp3.Call;
12 | import okhttp3.Callback;
13 | import okhttp3.Response;
14 |
15 | /**
16 | * presenter 层,承担业务逻辑处理,数据源处理等
17 | */
18 | public class MainPresenter extends BasePresenter implements MainContract.IMainPresenter {
19 |
20 | @Override
21 | public void handlerData() {
22 | getView().showDialog();
23 |
24 | getModel().requestBaidu(new Callback() {
25 | @Override
26 | public void onFailure(Call call, IOException e) {
27 | }
28 |
29 | @Override
30 | public void onResponse(Call call, Response response) throws IOException {
31 | String content = response.body().string();
32 | getView().succes(content);
33 | }
34 | });
35 | }
36 |
37 | @Override
38 | public void detach() {
39 | super.detach();
40 | /**
41 | * 释放内存、关闭网络请求、关闭线程等操作
42 | */
43 | Log.d("==========", "detech: 解除绑定,释放内存");
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v5/view/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v5.view;
2 |
3 | import android.app.ProgressDialog;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.support.annotation.Nullable;
7 | import android.widget.TextView;
8 | import android.widget.Toast;
9 |
10 | import com.test.mvp.mvpdemo.R;
11 | import com.test.mvp.mvpdemo.mvp.v5.MainContract;
12 | import com.test.mvp.mvpdemo.mvp.v5.basemvp.BaseActivity;
13 | import com.test.mvp.mvpdemo.mvp.v5.inject.InjectPresenter;
14 | import com.test.mvp.mvpdemo.mvp.v5.presenter.MainPresenter;
15 |
16 | /**
17 | * MVP 的写法,Version 5: 依赖注入,解决多个 Presenter 的问题
18 | *
19 | * @author 神探丶威威猫
20 | * @blog https://blog.csdn.net/smile_running
21 | * @warning 点个赞哦,评个论哦
22 | */
23 | public class MainActivity extends BaseActivity implements MainContract.IMainView {
24 |
25 | private TextView tv;
26 |
27 | @InjectPresenter
28 | private MainPresenter mPresenter;
29 |
30 | @Override
31 | protected void initLayout(@Nullable Bundle savedInstanceState) {
32 | setContentView(R.layout.activity_main);
33 | }
34 |
35 | @Override
36 | protected void initViews() {
37 | tv = $(R.id.tv);
38 | }
39 |
40 | @Override
41 | protected void initData() {
42 | // getPresenter().handlerData();
43 | mPresenter.handlerData();
44 | }
45 |
46 | @Override
47 | protected MainContract.IMainPresenter setPresenter() {
48 | return null;
49 | }
50 |
51 | @Override
52 | public void showDialog() {
53 | ProgressDialog dialog = new ProgressDialog(getContext());
54 | dialog.show();
55 | new Handler().postDelayed(new Runnable() {
56 | @Override
57 | public void run() {
58 | dialog.dismiss();
59 | }
60 | }, 1500);
61 | }
62 |
63 | @Override
64 | public void succes(String content) {
65 | runOnUiThread(new Runnable() {
66 | @Override
67 | public void run() {
68 | Toast.makeText(getContext(), "" + content, Toast.LENGTH_SHORT).show();
69 | tv.setText(content);
70 | }
71 | });
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v6/MainContract.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v6;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v6.basemvp.IBasePresenter;
4 | import com.test.mvp.mvpdemo.mvp.v6.basemvp.IBaseView;
5 |
6 | import okhttp3.Callback;
7 |
8 | /**
9 | * 契约接口,可以很直观的看到 M、V、P 层接口中提供的方法
10 | */
11 | public interface MainContract {
12 | interface IMainModel {
13 | void requestBaidu(Callback callback);
14 | }
15 |
16 | interface IMainView extends IBaseView {
17 | void showDialog();
18 |
19 | void succes(String content);
20 | }
21 |
22 | interface IMainPresenter extends IBasePresenter {
23 | void handlerData();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v6/SecondContract.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v6;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v6.basemvp.IBasePresenter;
4 | import com.test.mvp.mvpdemo.mvp.v6.basemvp.IBaseView;
5 |
6 | import okhttp3.Callback;
7 |
8 | public interface SecondContract {
9 | interface ISecondModel {
10 | void requestBaidu(Callback callback);
11 | }
12 |
13 | interface ISecondView extends IBaseView {
14 | void showDialog();
15 |
16 | void succes(String content);
17 | }
18 |
19 | interface ISecondPresenter extends IBasePresenter {
20 | void handlerData();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v6/basemvp/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v6.basemvp;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.support.annotation.IdRes;
6 | import android.support.annotation.Nullable;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.util.Log;
9 | import android.view.View;
10 |
11 | import com.test.mvp.mvpdemo.mvp.v6.inject.InjectPresenter;
12 |
13 | import java.lang.reflect.Field;
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | public abstract class BaseActivity extends AppCompatActivity implements IBaseView {
18 |
19 | /**
20 | * 保存使用注解的 Presenter ,用于解绑
21 | */
22 | private List mInjectPresenters;
23 |
24 | protected abstract void initLayout(@Nullable Bundle savedInstanceState);
25 |
26 | protected abstract void initViews();
27 |
28 | protected abstract void initData();
29 |
30 |
31 | @SuppressWarnings("SameParameterValue")
32 | protected T $(@IdRes int viewId) {
33 | return findViewById(viewId);
34 | }
35 |
36 | @SuppressWarnings({"unchecked", "TryWithIdenticalCatches"})
37 | @Override
38 | protected void onCreate(@Nullable Bundle savedInstanceState) {
39 | super.onCreate(savedInstanceState);
40 |
41 | initLayout(savedInstanceState);
42 |
43 | mInjectPresenters = new ArrayList<>();
44 |
45 | //获得已经申明的变量,包括私有的
46 | Field[] fields = this.getClass().getDeclaredFields();
47 | Log.d("============", "bindPresenter: " + this.getClass().getName());
48 | for (Field field : fields) {
49 | //获取变量上面的注解类型
50 | InjectPresenter injectPresenter = field.getAnnotation(InjectPresenter.class);
51 | if (injectPresenter != null) {
52 | try {
53 | Class extends BasePresenter> type = (Class extends BasePresenter>) field.getType();
54 | BasePresenter mInjectPresenter = type.newInstance();
55 | mInjectPresenter.attach(this);
56 | field.setAccessible(true);
57 | field.set(this, mInjectPresenter);
58 | mInjectPresenters.add(mInjectPresenter);
59 | } catch (IllegalAccessException e) {
60 | e.printStackTrace();
61 | } catch (InstantiationException e) {
62 | e.printStackTrace();
63 | }catch (ClassCastException e){
64 | e.printStackTrace();
65 | throw new RuntimeException("SubClass must extends Class:BasePresenter");
66 | }
67 | }
68 | }
69 |
70 | initViews();
71 | initData();
72 | }
73 |
74 | @Override
75 | protected void onDestroy() {
76 | super.onDestroy();
77 | /**
78 | * 解绑,避免内存泄漏
79 | */
80 | for (BasePresenter presenter : mInjectPresenters) {
81 | presenter.detach();
82 | }
83 | mInjectPresenters.clear();
84 | mInjectPresenters = null;
85 | }
86 |
87 | @Override
88 | public Context getContext() {
89 | return this;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v6/basemvp/BaseFragment.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v6.basemvp;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.IdRes;
5 | import android.support.annotation.LayoutRes;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 | import android.support.v4.app.Fragment;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import com.test.mvp.mvpdemo.mvp.v6.inject.InjectPresenter;
13 | import java.lang.reflect.Field;
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | public abstract class BaseFragment extends Fragment implements IBaseView {
18 |
19 | private List mInjectPresenters;
20 |
21 | private View mLayoutView;
22 |
23 | protected abstract @LayoutRes int setLayout();
24 |
25 | protected abstract void initViews(@Nullable Bundle savedInstanceState);
26 |
27 | protected abstract void initData();
28 |
29 | @SuppressWarnings("ConstantConditions")
30 | protected T $(@IdRes int viewId) {
31 | return this.getView().findViewById(viewId);
32 | }
33 |
34 | @SuppressWarnings({"unchecked", "TryWithIdenticalCatches"})
35 | @Nullable
36 | @Override
37 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
38 | View view = inflater.inflate(setLayout(), container, false);
39 |
40 | mInjectPresenters = new ArrayList<>();
41 |
42 | //获得已经申明的变量,包括私有的
43 | Field[] fields = this.getClass().getDeclaredFields();
44 | for (Field field : fields) {
45 | //获取变量上面的注解类型
46 | InjectPresenter injectPresenter = field.getAnnotation(InjectPresenter.class);
47 | if (injectPresenter != null) {
48 | try {
49 | Class extends BasePresenter> type = (Class extends BasePresenter>) field.getType();
50 | BasePresenter mInjectPresenter = type.newInstance();
51 | //绑定
52 | mInjectPresenter.attach(this);
53 | field.setAccessible(true);
54 | field.set(this, mInjectPresenter);
55 | mInjectPresenters.add(mInjectPresenter);
56 | } catch (IllegalAccessException e) {
57 | e.printStackTrace();
58 | } catch (java.lang.InstantiationException e) {
59 | e.printStackTrace();
60 | } catch (ClassCastException e) {
61 | e.printStackTrace();
62 | throw new RuntimeException("SubClass must extends Class:BasePresenter");
63 | }
64 | }
65 | }
66 | return view;
67 | }
68 |
69 | @Override
70 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
71 | super.onViewCreated(view, savedInstanceState);
72 |
73 | initViews(savedInstanceState);
74 | initData();
75 | }
76 |
77 | @Override
78 | public void onDestroy() {
79 | super.onDestroy();
80 | for (BasePresenter presenter : mInjectPresenters) {
81 | presenter.detach();
82 | }
83 | mInjectPresenters.clear();
84 | mInjectPresenters = null;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v6/basemvp/BaseModel.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v6.basemvp;
2 |
3 | public abstract class BaseModel {
4 | }
5 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v6/basemvp/BasePresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v6.basemvp;
2 |
3 | import android.util.Log;
4 |
5 | import java.lang.ref.SoftReference;
6 | import java.lang.reflect.InvocationHandler;
7 | import java.lang.reflect.Method;
8 | import java.lang.reflect.ParameterizedType;
9 | import java.lang.reflect.Proxy;
10 | import java.lang.reflect.Type;
11 |
12 | public abstract class BasePresenter implements IBasePresenter {
13 |
14 | private SoftReference mReferenceView;
15 | private V mProxyView;
16 | private M mModel;
17 |
18 | @SuppressWarnings({"unchecked", "TryWithIdenticalCatches"})
19 | @Override
20 | public void attach(IBaseView view) {
21 | //使用软引用创建对象
22 | Log.d("============view", "bindPresenter: " + view.getClass().getName());
23 | mReferenceView = new SoftReference<>(view);
24 |
25 | //使用动态代理做统一的逻辑判断 aop 思想
26 | mProxyView = (V) Proxy.newProxyInstance(view.getClass().getClassLoader(), view.getClass().getInterfaces(), new InvocationHandler() {
27 | @Override
28 | public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
29 | if (mReferenceView == null || mReferenceView.get() == null) {
30 | return null;
31 | }
32 | return method.invoke(mReferenceView.get(), objects);
33 | }
34 | });
35 |
36 | //通过获得泛型类的父类,拿到泛型的接口类实例,通过反射来实例化 model
37 | ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
38 | if (type != null) {
39 | Type[] types = type.getActualTypeArguments();
40 | try {
41 | mModel = (M) ((Class>) types[1]).newInstance();
42 | } catch (IllegalAccessException e) {
43 | e.printStackTrace();
44 | } catch (InstantiationException e) {
45 | e.printStackTrace();
46 | }
47 | }
48 |
49 | }
50 |
51 | @SuppressWarnings("unchecked")
52 | public V getView() {
53 | return mProxyView;
54 | }
55 |
56 | protected M getModel() {
57 | return mModel;
58 | }
59 |
60 | @Override
61 | public void detach() {
62 | mReferenceView.clear();
63 | mReferenceView = null;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v6/basemvp/IBasePresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v6.basemvp;
2 |
3 | public interface IBasePresenter {
4 |
5 | void attach(IBaseView view);
6 |
7 | void detach();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v6/basemvp/IBaseView.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v6.basemvp;
2 |
3 | import android.content.Context;
4 |
5 | public interface IBaseView {
6 |
7 | Context getContext();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v6/inject/InjectPresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v6.inject;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | @Retention(RetentionPolicy.RUNTIME)
9 | @Target(ElementType.FIELD)
10 | public @interface InjectPresenter {
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v6/model/DataModel.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v6.model;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v6.MainContract;
4 | import com.test.mvp.mvpdemo.mvp.v6.basemvp.BaseModel;
5 |
6 | import okhttp3.Callback;
7 | import okhttp3.OkHttpClient;
8 | import okhttp3.Request;
9 |
10 | /**
11 | * model 层,请求网络或数据库,提供数据源(原始数据)
12 | */
13 | public class DataModel extends BaseModel implements MainContract.IMainModel {
14 |
15 | @Override
16 | public void requestBaidu(Callback callback) {
17 | OkHttpClient client = new OkHttpClient();
18 | Request request = new Request.Builder()
19 | .url("https://www.baidu.com/")
20 | .build();
21 | client.newCall(request).enqueue(callback);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v6/model/SecondModel.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v6.model;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v6.SecondContract;
4 | import com.test.mvp.mvpdemo.mvp.v6.basemvp.BaseModel;
5 | import okhttp3.Callback;
6 | import okhttp3.OkHttpClient;
7 | import okhttp3.Request;
8 |
9 | public class SecondModel extends BaseModel implements SecondContract.ISecondModel {
10 | @Override
11 | public void requestBaidu(Callback callback) {
12 | OkHttpClient client = new OkHttpClient();
13 | Request request = new Request.Builder()
14 | .url("https://blog.csdn.net/smile_running")
15 | .build();
16 | client.newCall(request).enqueue(callback);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v6/presenter/MainPresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v6.presenter;
2 |
3 | import android.util.Log;
4 |
5 | import com.test.mvp.mvpdemo.mvp.v6.MainContract;
6 | import com.test.mvp.mvpdemo.mvp.v6.basemvp.BasePresenter;
7 | import com.test.mvp.mvpdemo.mvp.v6.model.DataModel;
8 |
9 | import java.io.IOException;
10 |
11 | import okhttp3.Call;
12 | import okhttp3.Callback;
13 | import okhttp3.Response;
14 |
15 | /**
16 | * presenter 层,承担业务逻辑处理,数据源处理等
17 | */
18 | public class MainPresenter extends BasePresenter implements MainContract.IMainPresenter {
19 |
20 | @Override
21 | public void handlerData() {
22 | getView().showDialog();
23 |
24 | getModel().requestBaidu(new Callback() {
25 | @Override
26 | public void onFailure(Call call, IOException e) {
27 | }
28 |
29 | @Override
30 | public void onResponse(Call call, Response response) throws IOException {
31 | String content = response.body().string();
32 | getView().succes(content);
33 | }
34 | });
35 | }
36 |
37 | @Override
38 | public void detach() {
39 | super.detach();
40 | /**
41 | * 释放内存、关闭网络请求、关闭线程等操作
42 | */
43 | Log.d("==========", "detech: 解除绑定,释放内存");
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v6/presenter/SecondPresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v6.presenter;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v6.SecondContract;
4 | import com.test.mvp.mvpdemo.mvp.v6.basemvp.BasePresenter;
5 | import com.test.mvp.mvpdemo.mvp.v6.model.SecondModel;
6 | import java.io.IOException;
7 | import okhttp3.Call;
8 | import okhttp3.Callback;
9 | import okhttp3.Response;
10 |
11 | public class SecondPresenter extends BasePresenter implements SecondContract.ISecondPresenter {
12 |
13 | @Override
14 | public void handlerData() {
15 | getView().showDialog();
16 |
17 | getModel().requestBaidu(new Callback() {
18 | @Override
19 | public void onFailure(Call call, IOException e) {
20 | }
21 |
22 | @Override
23 | public void onResponse(Call call, Response response) throws IOException {
24 | String content = response.body().string();
25 | getView().succes(content);
26 | }
27 | });
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v6/view/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v6.view;
2 |
3 | import android.app.ProgressDialog;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.os.Handler;
7 | import android.support.annotation.Nullable;
8 | import android.view.View;
9 | import android.widget.TextView;
10 | import android.widget.Toast;
11 |
12 | import com.test.mvp.mvpdemo.R;
13 | import com.test.mvp.mvpdemo.mvp.v6.MainContract;
14 | import com.test.mvp.mvpdemo.mvp.v6.basemvp.BaseActivity;
15 | import com.test.mvp.mvpdemo.mvp.v6.inject.InjectPresenter;
16 | import com.test.mvp.mvpdemo.mvp.v6.presenter.MainPresenter;
17 |
18 | /**
19 | * MVP 的写法,Version 6: 封装 BaseFragment
20 | *
21 | * @author 神探丶威威猫
22 | * @blog https://blog.csdn.net/smile_running
23 | * @warning 点个赞哦,评个论哦
24 | */
25 | public class MainActivity extends BaseActivity implements MainContract.IMainView {
26 |
27 | private TextView tv;
28 |
29 | @InjectPresenter
30 | private MainPresenter mPresenter;
31 |
32 | @Override
33 | protected void initLayout(@Nullable Bundle savedInstanceState) {
34 | setContentView(R.layout.activity_main);
35 | }
36 |
37 | @Override
38 | protected void initViews() {
39 | tv = $(R.id.tv);
40 |
41 | tv.setOnClickListener(new View.OnClickListener() {
42 | @Override
43 | public void onClick(View view) {
44 | startActivity(new Intent(getContext(), SecondActivity.class));
45 | }
46 | });
47 | }
48 |
49 | @Override
50 | protected void initData() {
51 | mPresenter.handlerData();
52 | }
53 |
54 | @Override
55 | public void showDialog() {
56 | ProgressDialog dialog = new ProgressDialog(getContext());
57 | dialog.show();
58 | new Handler().postDelayed(new Runnable() {
59 | @Override
60 | public void run() {
61 | dialog.dismiss();
62 | }
63 | }, 1500);
64 | }
65 |
66 | @Override
67 | public void succes(String content) {
68 | runOnUiThread(new Runnable() {
69 | @Override
70 | public void run() {
71 | Toast.makeText(getContext(), "" + content, Toast.LENGTH_SHORT).show();
72 | tv.setText(content);
73 | }
74 | });
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v6/view/SecondActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v6.view;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v7.app.AppCompatActivity;
6 |
7 | import com.test.mvp.mvpdemo.R;
8 |
9 | public class SecondActivity extends AppCompatActivity {
10 |
11 | @Override
12 | protected void onCreate(@Nullable Bundle savedInstanceState) {
13 | super.onCreate(savedInstanceState);
14 | setContentView(R.layout.activity_second);
15 | /**
16 | * 开启一个 fragment
17 | */
18 | getSupportFragmentManager().beginTransaction().replace(R.id.second_container, new SecondFragment()).commit();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v6/view/SecondFragment.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v6.view;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.widget.TextView;
6 | import android.widget.Toast;
7 |
8 | import com.test.mvp.mvpdemo.R;
9 | import com.test.mvp.mvpdemo.mvp.v6.SecondContract;
10 | import com.test.mvp.mvpdemo.mvp.v6.basemvp.BaseFragment;
11 | import com.test.mvp.mvpdemo.mvp.v6.inject.InjectPresenter;
12 | import com.test.mvp.mvpdemo.mvp.v6.presenter.SecondPresenter;
13 |
14 | public class SecondFragment extends BaseFragment implements SecondContract.ISecondView {
15 |
16 | private TextView tvFragment;
17 |
18 | @InjectPresenter
19 | private SecondPresenter mPresenter;
20 |
21 | @Override
22 | protected int setLayout() {
23 | return R.layout.fragment_second;
24 | }
25 |
26 | @Override
27 | protected void initViews(@Nullable Bundle savedInstanceState) {
28 | tvFragment = $(R.id.tv_fragment);
29 | }
30 |
31 | @Override
32 | protected void initData() {
33 | mPresenter.handlerData();
34 | }
35 |
36 | @Override
37 | public void showDialog() {
38 | // Toast.makeText(getContext(), "this is Fragment", Toast.LENGTH_SHORT).show();
39 | }
40 |
41 | @SuppressWarnings("ConstantConditions")
42 | @Override
43 | public void succes(String content) {
44 | getActivity().runOnUiThread(new Runnable() {
45 | @Override
46 | public void run() {
47 | Toast.makeText(getContext(), "" + content, Toast.LENGTH_SHORT).show();
48 | tvFragment.setText(content);
49 | }
50 | });
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/MainContract.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v7.basemvp.IBasePresenter;
4 | import com.test.mvp.mvpdemo.mvp.v7.basemvp.IBaseView;
5 |
6 | import okhttp3.Callback;
7 |
8 | /**
9 | * 契约接口,可以很直观的看到 M、V、P 层接口中提供的方法
10 | */
11 | public interface MainContract {
12 | interface IMainModel {
13 | void requestBaidu(Callback callback);
14 | }
15 |
16 | interface IMainView extends IBaseView {
17 | void showDialog();
18 |
19 | void succes(String content);
20 | }
21 |
22 | interface IMainPresenter extends IBasePresenter {
23 | void handlerData();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/SecondContract.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v7.basemvp.IBasePresenter;
4 | import com.test.mvp.mvpdemo.mvp.v7.basemvp.IBaseView;
5 |
6 | import okhttp3.Callback;
7 |
8 | public interface SecondContract {
9 | interface ISecondModel {
10 | void requestBaidu(Callback callback);
11 | }
12 |
13 | interface ISecondView extends IBaseView {
14 | void showDialog();
15 |
16 | void succes(String content);
17 | }
18 |
19 | interface ISecondPresenter extends IBasePresenter {
20 | void handlerData();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/basemvp/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.basemvp;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.support.annotation.IdRes;
6 | import android.support.annotation.Nullable;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.view.View;
9 |
10 | import com.test.mvp.mvpdemo.mvp.v7.proxy.ProxyActivity;
11 |
12 | public abstract class BaseActivity extends AppCompatActivity implements IBaseView {
13 |
14 | private ProxyActivity mProxyActivity;
15 |
16 | protected abstract void initLayout(@Nullable Bundle savedInstanceState);
17 |
18 | protected abstract void initViews();
19 |
20 | protected abstract void initData();
21 |
22 |
23 | @SuppressWarnings("SameParameterValue")
24 | protected T $(@IdRes int viewId) {
25 | return findViewById(viewId);
26 | }
27 |
28 | @SuppressWarnings({"unchecked", "TryWithIdenticalCatches"})
29 | @Override
30 | protected void onCreate(@Nullable Bundle savedInstanceState) {
31 | super.onCreate(savedInstanceState);
32 |
33 | initLayout(savedInstanceState);
34 |
35 | mProxyActivity = createProxyActivity();
36 | mProxyActivity.bindPresenter();
37 |
38 | initViews();
39 | initData();
40 | }
41 |
42 | @SuppressWarnings("unchecked")
43 | private ProxyActivity createProxyActivity() {
44 | if (mProxyActivity == null) {
45 | return new ProxyActivity(this);
46 | }
47 | return mProxyActivity;
48 | }
49 |
50 | @Override
51 | protected void onDestroy() {
52 | super.onDestroy();
53 | mProxyActivity.unbindPresenter();
54 | }
55 |
56 | @Override
57 | public Context getContext() {
58 | return this;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/basemvp/BaseFragment.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.basemvp;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.IdRes;
5 | import android.support.annotation.LayoutRes;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 | import android.support.v4.app.Fragment;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 |
13 | import com.test.mvp.mvpdemo.mvp.v7.proxy.ProxyFragment;
14 |
15 | public abstract class BaseFragment extends Fragment implements IBaseView {
16 |
17 | private ProxyFragment mProxyFragment;
18 |
19 | protected abstract @LayoutRes
20 | int setLayout();
21 |
22 | protected abstract void initViews(@Nullable Bundle savedInstanceState);
23 |
24 | protected abstract void initData();
25 |
26 | @SuppressWarnings("ConstantConditions")
27 | protected T $(@IdRes int viewId) {
28 | return this.getView().findViewById(viewId);
29 | }
30 |
31 | @SuppressWarnings({"unchecked", "TryWithIdenticalCatches"})
32 | @Nullable
33 | @Override
34 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
35 | View view = inflater.inflate(setLayout(), container, false);
36 |
37 | mProxyFragment = createProxyFragment();
38 | mProxyFragment.bindPresenter();
39 |
40 | return view;
41 | }
42 |
43 | @Override
44 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
45 | super.onViewCreated(view, savedInstanceState);
46 |
47 | initViews(savedInstanceState);
48 | initData();
49 | }
50 |
51 | @SuppressWarnings("unchecked")
52 | private ProxyFragment createProxyFragment() {
53 | if (mProxyFragment == null) {
54 | return new ProxyFragment<>(this);
55 | }
56 | return mProxyFragment;
57 | }
58 |
59 | @Override
60 | public void onDestroy() {
61 | super.onDestroy();
62 | mProxyFragment.unbindPresenter();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/basemvp/BaseModel.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.basemvp;
2 |
3 | public abstract class BaseModel {
4 | }
5 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/basemvp/BasePresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.basemvp;
2 |
3 | import android.util.Log;
4 |
5 | import java.lang.ref.SoftReference;
6 | import java.lang.reflect.InvocationHandler;
7 | import java.lang.reflect.Method;
8 | import java.lang.reflect.ParameterizedType;
9 | import java.lang.reflect.Proxy;
10 | import java.lang.reflect.Type;
11 |
12 | public abstract class BasePresenter implements IBasePresenter {
13 |
14 | private SoftReference mReferenceView;
15 | private V mProxyView;
16 | private M mModel;
17 |
18 | @SuppressWarnings({"unchecked", "TryWithIdenticalCatches"})
19 | @Override
20 | public void attach(IBaseView view) {
21 | //使用软引用创建对象
22 | mReferenceView = new SoftReference<>(view);
23 |
24 | //使用动态代理做统一的逻辑判断 aop 思想
25 | mProxyView = (V) Proxy.newProxyInstance(view.getClass().getClassLoader(), view.getClass().getInterfaces(), new InvocationHandler() {
26 | @Override
27 | public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
28 | if (mReferenceView == null || mReferenceView.get() == null) {
29 | return null;
30 | }
31 | return method.invoke(mReferenceView.get(), objects);
32 | }
33 | });
34 |
35 | //通过获得泛型类的父类,拿到泛型的接口类实例,通过反射来实例化 model
36 | ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
37 | if (type != null) {
38 | Type[] types = type.getActualTypeArguments();
39 | try {
40 | mModel = (M) ((Class>) types[1]).newInstance();
41 | } catch (IllegalAccessException e) {
42 | e.printStackTrace();
43 | } catch (InstantiationException e) {
44 | e.printStackTrace();
45 | }
46 | }
47 |
48 | }
49 |
50 | @SuppressWarnings("unchecked")
51 | public V getView() {
52 | return mProxyView;
53 | }
54 |
55 | protected M getModel() {
56 | return mModel;
57 | }
58 |
59 | @Override
60 | public void detach() {
61 | mReferenceView.clear();
62 | mReferenceView = null;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/basemvp/IBasePresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.basemvp;
2 |
3 | public interface IBasePresenter {
4 |
5 | void attach(IBaseView view);
6 |
7 | void detach();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/basemvp/IBaseView.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.basemvp;
2 |
3 | import android.content.Context;
4 |
5 | public interface IBaseView {
6 |
7 | Context getContext();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/inject/InjectPresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.inject;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | @Retention(RetentionPolicy.RUNTIME)
9 | @Target(ElementType.FIELD)
10 | public @interface InjectPresenter {
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/model/DataModel.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.model;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v7.MainContract;
4 | import com.test.mvp.mvpdemo.mvp.v7.basemvp.BaseModel;
5 |
6 | import okhttp3.Callback;
7 | import okhttp3.OkHttpClient;
8 | import okhttp3.Request;
9 |
10 | /**
11 | * model 层,请求网络或数据库,提供数据源(原始数据)
12 | */
13 | public class DataModel extends BaseModel implements MainContract.IMainModel {
14 |
15 | @Override
16 | public void requestBaidu(Callback callback) {
17 | OkHttpClient client = new OkHttpClient();
18 | Request request = new Request.Builder()
19 | .url("https://www.baidu.com/")
20 | .build();
21 | client.newCall(request).enqueue(callback);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/model/SecondModel.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.model;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v7.SecondContract;
4 | import com.test.mvp.mvpdemo.mvp.v7.basemvp.BaseModel;
5 |
6 | import okhttp3.Callback;
7 | import okhttp3.OkHttpClient;
8 | import okhttp3.Request;
9 |
10 | public class SecondModel extends BaseModel implements SecondContract.ISecondModel {
11 | @Override
12 | public void requestBaidu(Callback callback) {
13 | OkHttpClient client = new OkHttpClient();
14 | Request request = new Request.Builder()
15 | .url("https://blog.csdn.net/smile_running")
16 | .build();
17 | client.newCall(request).enqueue(callback);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/presenter/MainPresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.presenter;
2 |
3 | import android.util.Log;
4 |
5 | import com.test.mvp.mvpdemo.mvp.v7.MainContract;
6 | import com.test.mvp.mvpdemo.mvp.v7.basemvp.BasePresenter;
7 | import com.test.mvp.mvpdemo.mvp.v7.model.DataModel;
8 |
9 | import java.io.IOException;
10 |
11 | import okhttp3.Call;
12 | import okhttp3.Callback;
13 | import okhttp3.Response;
14 |
15 | /**
16 | * presenter 层,承担业务逻辑处理,数据源处理等
17 | */
18 | public class MainPresenter extends BasePresenter implements MainContract.IMainPresenter {
19 |
20 | @Override
21 | public void handlerData() {
22 | getView().showDialog();
23 |
24 | getModel().requestBaidu(new Callback() {
25 | @Override
26 | public void onFailure(Call call, IOException e) {
27 | }
28 |
29 | @Override
30 | public void onResponse(Call call, Response response) throws IOException {
31 | String content = response.body().string();
32 | getView().succes(content);
33 | }
34 | });
35 | }
36 |
37 | @Override
38 | public void detach() {
39 | super.detach();
40 | /**
41 | * 释放内存、关闭网络请求、关闭线程等操作
42 | */
43 | Log.d("==========", "detech: 解除绑定,释放内存");
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/presenter/SecondPresenter.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.presenter;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v7.SecondContract;
4 | import com.test.mvp.mvpdemo.mvp.v7.basemvp.BasePresenter;
5 | import com.test.mvp.mvpdemo.mvp.v7.model.SecondModel;
6 |
7 | import java.io.IOException;
8 |
9 | import okhttp3.Call;
10 | import okhttp3.Callback;
11 | import okhttp3.Response;
12 |
13 | public class SecondPresenter extends BasePresenter implements SecondContract.ISecondPresenter {
14 |
15 | @Override
16 | public void handlerData() {
17 | getView().showDialog();
18 |
19 | getModel().requestBaidu(new Callback() {
20 | @Override
21 | public void onFailure(Call call, IOException e) {
22 | }
23 |
24 | @Override
25 | public void onResponse(Call call, Response response) throws IOException {
26 | String content = response.body().string();
27 | getView().succes(content);
28 | }
29 | });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/proxy/IProxy.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.proxy;
2 |
3 | public interface IProxy {
4 | void bindPresenter();
5 |
6 | void unbindPresenter();
7 | }
8 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/proxy/ProxyActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.proxy;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v7.basemvp.IBaseView;
4 |
5 | public class ProxyActivity extends ProxyImpl {
6 | public ProxyActivity(V view) {
7 | super(view);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/proxy/ProxyFragment.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.proxy;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v7.basemvp.IBaseView;
4 |
5 | public class ProxyFragment extends ProxyImpl {
6 | public ProxyFragment(V view) {
7 | super(view);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/proxy/ProxyImpl.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.proxy;
2 |
3 | import com.test.mvp.mvpdemo.mvp.v7.basemvp.BasePresenter;
4 | import com.test.mvp.mvpdemo.mvp.v7.basemvp.IBaseView;
5 | import com.test.mvp.mvpdemo.mvp.v7.inject.InjectPresenter;
6 | import java.lang.reflect.Field;
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | public class ProxyImpl implements IProxy {
11 |
12 | private IBaseView mView;
13 | private List mInjectPresenters;
14 |
15 | public ProxyImpl(IBaseView view) {
16 | this.mView = view;
17 | mInjectPresenters = new ArrayList<>();
18 | }
19 |
20 | @SuppressWarnings({"unchecked", "TryWithIdenticalCatches"})
21 | @Override
22 | public void bindPresenter() {
23 | //获得已经申明的变量,包括私有的
24 | Field[] fields = mView.getClass().getDeclaredFields();
25 | for (Field field : fields) {
26 | //获取变量上面的注解类型
27 | InjectPresenter injectPresenter = field.getAnnotation(InjectPresenter.class);
28 | if (injectPresenter != null) {
29 | try {
30 | Class extends BasePresenter> type = (Class extends BasePresenter>) field.getType();
31 | BasePresenter mInjectPresenter = type.newInstance();
32 | mInjectPresenter.attach(mView);
33 | field.setAccessible(true);
34 | field.set(mView, mInjectPresenter);
35 | mInjectPresenters.add(mInjectPresenter);
36 | } catch (IllegalAccessException e) {
37 | e.printStackTrace();
38 | } catch (InstantiationException e) {
39 | e.printStackTrace();
40 | } catch (ClassCastException e) {
41 | e.printStackTrace();
42 | throw new RuntimeException("SubClass must extends Class:BasePresenter");
43 | }
44 | }
45 | }
46 | }
47 |
48 | @Override
49 | public void unbindPresenter() {
50 | /**
51 | * 解绑,避免内存泄漏
52 | */
53 | for (BasePresenter presenter : mInjectPresenters) {
54 | presenter.detach();
55 | }
56 | mInjectPresenters.clear();
57 | mInjectPresenters = null;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/view/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.view;
2 |
3 | import android.app.ProgressDialog;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.os.Handler;
7 | import android.support.annotation.Nullable;
8 | import android.view.View;
9 | import android.widget.TextView;
10 | import android.widget.Toast;
11 |
12 | import com.test.mvp.mvpdemo.R;
13 | import com.test.mvp.mvpdemo.mvp.v7.MainContract;
14 | import com.test.mvp.mvpdemo.mvp.v7.basemvp.BaseActivity;
15 | import com.test.mvp.mvpdemo.mvp.v7.inject.InjectPresenter;
16 | import com.test.mvp.mvpdemo.mvp.v7.presenter.MainPresenter;
17 |
18 | /**
19 | * MVP 的写法,Version 6: 静态代理,消除重复代码
20 | *
21 | * @author 神探丶威威猫
22 | * @blog https://blog.csdn.net/smile_running
23 | * @warning 点个赞哦,评个论哦
24 | */
25 | public class MainActivity extends BaseActivity implements MainContract.IMainView {
26 |
27 | private TextView tv;
28 |
29 | @InjectPresenter
30 | private MainPresenter mPresenter;
31 |
32 | @Override
33 | protected void initLayout(@Nullable Bundle savedInstanceState) {
34 | setContentView(R.layout.activity_main);
35 | }
36 |
37 | @Override
38 | protected void initViews() {
39 | tv = $(R.id.tv);
40 |
41 | tv.setOnClickListener(new View.OnClickListener() {
42 | @Override
43 | public void onClick(View view) {
44 | startActivity(new Intent(getContext(), SecondActivity.class));
45 | }
46 | });
47 | }
48 |
49 | @Override
50 | protected void initData() {
51 | mPresenter.handlerData();
52 | }
53 |
54 | @Override
55 | public void showDialog() {
56 | ProgressDialog dialog = new ProgressDialog(getContext());
57 | dialog.show();
58 | new Handler().postDelayed(new Runnable() {
59 | @Override
60 | public void run() {
61 | dialog.dismiss();
62 | }
63 | }, 1500);
64 | }
65 |
66 | @Override
67 | public void succes(String content) {
68 | runOnUiThread(new Runnable() {
69 | @Override
70 | public void run() {
71 | Toast.makeText(getContext(), "" + content, Toast.LENGTH_SHORT).show();
72 | tv.setText(content);
73 | }
74 | });
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/view/SecondActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.view;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v7.app.AppCompatActivity;
6 |
7 | import com.test.mvp.mvpdemo.R;
8 |
9 | public class SecondActivity extends AppCompatActivity {
10 |
11 | @Override
12 | protected void onCreate(@Nullable Bundle savedInstanceState) {
13 | super.onCreate(savedInstanceState);
14 | setContentView(R.layout.activity_second);
15 | /**
16 | * 开启一个 fragment
17 | */
18 | getSupportFragmentManager().beginTransaction().replace(R.id.second_container, new SecondFragment()).commit();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/test/mvp/mvpdemo/mvp/v7/view/SecondFragment.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo.mvp.v7.view;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.widget.TextView;
6 | import android.widget.Toast;
7 |
8 | import com.test.mvp.mvpdemo.R;
9 | import com.test.mvp.mvpdemo.mvp.v7.SecondContract;
10 | import com.test.mvp.mvpdemo.mvp.v7.basemvp.BaseFragment;
11 | import com.test.mvp.mvpdemo.mvp.v7.inject.InjectPresenter;
12 | import com.test.mvp.mvpdemo.mvp.v7.presenter.SecondPresenter;
13 |
14 | public class SecondFragment extends BaseFragment implements SecondContract.ISecondView {
15 |
16 | private TextView tvFragment;
17 |
18 | @InjectPresenter
19 | private SecondPresenter mPresenter;
20 |
21 | @Override
22 | protected int setLayout() {
23 | return R.layout.fragment_second;
24 | }
25 |
26 | @Override
27 | protected void initViews(@Nullable Bundle savedInstanceState) {
28 | tvFragment = $(R.id.tv_fragment);
29 | }
30 |
31 | @Override
32 | protected void initData() {
33 | mPresenter.handlerData();
34 | }
35 |
36 | @Override
37 | public void showDialog() {
38 | // Toast.makeText(getContext(), "this is Fragment", Toast.LENGTH_SHORT).show();
39 | }
40 |
41 | @SuppressWarnings("ConstantConditions")
42 | @Override
43 | public void succes(String content) {
44 | getActivity().runOnUiThread(new Runnable() {
45 | @Override
46 | public void run() {
47 | Toast.makeText(getContext(), "" + content, Toast.LENGTH_SHORT).show();
48 | tvFragment.setText(content);
49 | }
50 | });
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/caomei.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/drawable/caomei.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/cheng.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/drawable/cheng.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/huolongguo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/drawable/huolongguo.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/juzi.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/drawable/juzi.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/lanmei.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/drawable/lanmei.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/pingguo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/drawable/pingguo.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/xigua.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/drawable/xigua.jpg
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_second.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_second.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xww0826/AndroidMVP_Demo/bd3ec2e32e258224ef1424703f7f6fb4122208ba/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MVPDemo-smile_Running
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/test/mvp/mvpdemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.test.mvp.mvpdemo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------