├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── cn │ │ └── sun │ │ └── pxandroidtest │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── cn │ │ │ └── sun │ │ │ └── pxandroidtest │ │ │ ├── MainActivity.java │ │ │ ├── TestUtil.java │ │ │ ├── collection │ │ │ ├── IPlayerStateDispatcher.java │ │ │ ├── PlayerManager.java │ │ │ ├── PlayerStateDispatcher.java │ │ │ ├── PlayerStateDispatcher2.java │ │ │ └── PlayerStateListener.java │ │ │ ├── invoke │ │ │ ├── InvokeTest.java │ │ │ ├── TestInterface.java │ │ │ └── TestProxy.java │ │ │ └── mvp │ │ │ ├── IModel.java │ │ │ ├── IPresenter.java │ │ │ ├── IViews.java │ │ │ ├── MVPTestActivity.java │ │ │ ├── Model.java │ │ │ └── Presenter.java │ └── res │ │ ├── layout │ │ ├── activity_main.xml │ │ └── activity_mvp_test.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── cn │ └── sun │ └── pxandroid │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── pxandroid ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── cn │ │ └── sun │ │ └── pxandroid │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── cn │ │ │ └── sun │ │ │ └── pxandroid │ │ │ ├── Action.java │ │ │ ├── Function.java │ │ │ ├── Px.java │ │ │ ├── PxLog.java │ │ │ ├── PxTask.java │ │ │ └── proxy │ │ │ ├── CollectionProxy.java │ │ │ ├── HandlerProxy.java │ │ │ ├── NewThreadProxy.java │ │ │ ├── NullableProxy.java │ │ │ ├── UIProxy.java │ │ │ └── WorkProxy.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── cn │ └── sun │ └── pxandroid │ └── ExampleUnitTest.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .idea 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PxAndroid 2 | 这是一个使用动态代理技术来解决线程切换,集合事件分发,以及仿写RxJava的一个项目。 3 | 下面我们来简单针对各个模块做介绍。 4 | 5 | ##动态代理 6 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion '27.0.3' 6 | 7 | defaultConfig { 8 | applicationId "cn.sun.pxandroidtest" 9 | minSdkVersion 14 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | lintOptions { 21 | abortOnError false 22 | } 23 | } 24 | 25 | dependencies { 26 | implementation fileTree(dir: 'libs', include: ['*.jar']) 27 | implementation 'com.android.support:appcompat-v7:23.2.0' 28 | implementation project(':pxandroid') 29 | implementation 'io.reactivex:rxandroid:1.0.1' 30 | implementation 'io.reactivex:rxjava:1.0.14' 31 | } 32 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/sunzheng/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/cn/sun/pxandroidtest/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/cn/sun/pxandroidtest/MainActivity.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.os.Looper; 7 | import android.util.Log; 8 | import android.view.View; 9 | 10 | import cn.sun.pxandroid.Action; 11 | import cn.sun.pxandroid.Function; 12 | import cn.sun.pxandroid.PxLog; 13 | import cn.sun.pxandroid.Px; 14 | import cn.sun.pxandroidtest.collection.PlayerManager; 15 | import cn.sun.pxandroidtest.invoke.InvokeTest; 16 | import cn.sun.pxandroidtest.mvp.MVPTestActivity; 17 | import rx.Observable; 18 | import rx.android.schedulers.AndroidSchedulers; 19 | import rx.functions.Action1; 20 | import rx.functions.Func1; 21 | import rx.schedulers.Schedulers; 22 | 23 | public class MainActivity extends Activity implements View.OnClickListener { 24 | 25 | @Override 26 | protected void onCreate(Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | setContentView(R.layout.activity_main); 29 | findViewById(R.id.btnPxAndroid2).setOnClickListener(this); 30 | findViewById(R.id.btnMvpTest).setOnClickListener(this); 31 | findViewById(R.id.btnRxJava).setOnClickListener(this); 32 | findViewById(R.id.btnPxAndroid).setOnClickListener(this); 33 | findViewById(R.id.btnCollectionTest).setOnClickListener(this); 34 | findViewById(R.id.btnProxy).setOnClickListener(this); 35 | } 36 | 37 | private static boolean isMainThread() { 38 | return Looper.getMainLooper() == Looper.myLooper(); 39 | } 40 | 41 | public static void testPxAndroid() { 42 | Px.just("hello", "world", "sunzheng").io().map(new Function() { 43 | @Override 44 | public String call(Px px, String data) {//io线程,每一个px行为有一个 45 | TestUtil.sleep(500); 46 | Log.d("suntest", "Function1." + data + "." + isMainThread()); 47 | return data + ".call1."; 48 | } 49 | }).newThread().map(new Function() { 50 | @Override 51 | public String call(Px px, String data) {//全新的IO线程 52 | Log.d("suntest", "Function2." + data + "." + isMainThread()); 53 | TestUtil.sleep(500); 54 | return data + ".call2"; 55 | } 56 | }).newThread().map(new Function() { 57 | @Override 58 | public String call(Px px, String data) {//全新的IO线程 59 | Log.d("suntest", "Function3." + data + "." + isMainThread()); 60 | TestUtil.sleep(500); 61 | return data + ".call3"; 62 | } 63 | }).io().map(new Function() { 64 | @Override 65 | public String call(Px px, String data) {//线程池 66 | Log.d("suntest", "Function4." + data + "." + isMainThread()); 67 | TestUtil.sleep(500); 68 | return data + ".call4"; 69 | } 70 | }).ui().execute(new Action() { 71 | @Override 72 | public void run(String Object) { 73 | Log.d("suntest", "Function5." + Object + "." + isMainThread()); 74 | } 75 | }); 76 | } 77 | 78 | private static void testPxAndroid2() { 79 | Px.just("one", "two", "three") 80 | .newThread().map(new Function() { 81 | @Override 82 | public String call(Px px, String s) { 83 | PxLog.d("suntest", "pxAndroid.Funct1." + s + "." + isMainThread()); 84 | TestUtil.sleep(500); 85 | return s + ".Funct1."; 86 | } 87 | }).ui().execute(new Action() { 88 | @Override 89 | public void run(String Object) { 90 | Log.d("suntest", "Function5." + Object + "." + isMainThread()); 91 | } 92 | }); 93 | } 94 | 95 | @Override 96 | public void onClick(View v) { 97 | switch (v.getId()) { 98 | case R.id.btnMvpTest: { 99 | startActivity(new Intent(this, MVPTestActivity.class)); 100 | } 101 | break; 102 | case R.id.btnRxJava: { 103 | testRxJava(); 104 | } 105 | break; 106 | case R.id.btnPxAndroid: { 107 | testPxAndroid(); 108 | } 109 | break; 110 | case R.id.btnPxAndroid2: { 111 | testPxAndroid2(); 112 | } 113 | break; 114 | case R.id.btnCollectionTest: { 115 | testCollectionProxy(); 116 | } 117 | break; 118 | case R.id.btnProxy: { 119 | testProxy(); 120 | } 121 | break; 122 | } 123 | } 124 | 125 | private void testProxy() { 126 | InvokeTest.newInstance().helloWorld(); 127 | } 128 | 129 | private void testCollectionProxy() { 130 | PlayerManager.getInstance().test(); 131 | } 132 | 133 | private void testRxJava() { 134 | Observable.just("one", "two", "three", "four", "five") 135 | .map(new Func1() { 136 | @Override 137 | public String call(String s) { 138 | PxLog.d("suntest", "rxJava.Funct1." + s + "." + isMainThread()); 139 | TestUtil.sleep(500); 140 | return s + ".Funct1."; 141 | } 142 | }).subscribeOn(Schedulers.newThread()) 143 | .observeOn(AndroidSchedulers.mainThread()) 144 | .subscribe(new Action1() { 145 | @Override 146 | public void call(String s) { 147 | PxLog.d("suntest", "rxJava.subscribe." + s + "." + isMainThread()); 148 | } 149 | }); 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /app/src/main/java/cn/sun/pxandroidtest/TestUtil.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest; 2 | 3 | /** 4 | * Created by sunzheng on 16/6/28. 5 | */ 6 | public class TestUtil { 7 | public static void sleep(int times) { 8 | try { 9 | Thread.sleep(times); 10 | } catch (InterruptedException e) { 11 | e.printStackTrace(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/cn/sun/pxandroidtest/collection/IPlayerStateDispatcher.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest.collection; 2 | 3 | /** 4 | * Created by sunzheng on 16/6/28. 5 | */ 6 | public interface IPlayerStateDispatcher { 7 | void dispatcherStart(); 8 | 9 | void dispatcherParpered(); 10 | 11 | void dispatcherPause(); 12 | 13 | void dispatcherStop(); 14 | 15 | void dispatcherError(int errorCode); 16 | 17 | void dispatcherComplection(); 18 | 19 | void addPlayerStateListener(PlayerStateListener playerStateListener); 20 | 21 | void removePlayerStateListener(PlayerStateListener playerStateListener); 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/cn/sun/pxandroidtest/collection/PlayerManager.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest.collection; 2 | 3 | import cn.sun.pxandroid.PxLog; 4 | 5 | /** 6 | * Created by sunzheng on 16/6/28. 7 | */ 8 | public class PlayerManager { 9 | 10 | private static PlayerManager instance = new PlayerManager(); 11 | 12 | public static PlayerManager getInstance() { 13 | return instance; 14 | } 15 | 16 | private PlayerStateListener myListener = new PlayerStateListener() { 17 | @Override 18 | public void onStart() { 19 | PxLog.d("suntest", "onStart." + Thread.currentThread()); 20 | } 21 | 22 | @Override 23 | public void onParpered() { 24 | PxLog.d("suntest", "onParpered." + Thread.currentThread()); 25 | } 26 | 27 | @Override 28 | public void onPause() { 29 | PxLog.d("suntest", "onPause." + Thread.currentThread()); 30 | } 31 | 32 | @Override 33 | public void onStop() { 34 | PxLog.d("suntest", "onStop." + Thread.currentThread()); 35 | } 36 | 37 | @Override 38 | public void onError(int errorCode) { 39 | PxLog.d("suntest", "onError." + Thread.currentThread()); 40 | } 41 | 42 | @Override 43 | public void onComplection() { 44 | PxLog.d("suntest", "onComplection." + Thread.currentThread()); 45 | } 46 | }; 47 | private PlayerStateListener myListener2 = new PlayerStateListener() { 48 | @Override 49 | public void onStart() { 50 | PxLog.d("suntest", "onStart2." + Thread.currentThread()); 51 | } 52 | 53 | @Override 54 | public void onParpered() { 55 | PxLog.d("suntest", "onParpered2." + Thread.currentThread()); 56 | } 57 | 58 | @Override 59 | public void onPause() { 60 | PxLog.d("suntest", "onPause2." + Thread.currentThread()); 61 | } 62 | 63 | @Override 64 | public void onStop() { 65 | PxLog.d("suntest", "onStop2." + Thread.currentThread()); 66 | } 67 | 68 | @Override 69 | public void onError(int errorCode) { 70 | PxLog.d("suntest", "onError2." + Thread.currentThread()); 71 | } 72 | 73 | @Override 74 | public void onComplection() { 75 | PxLog.d("suntest", "onComplection2." + Thread.currentThread()); 76 | } 77 | }; 78 | public void test() { 79 | PxLog.d("suntest","一般写法回调"); 80 | //一般写法 81 | IPlayerStateDispatcher dispatcher1 = new PlayerStateDispatcher(); 82 | dispatcher1.addPlayerStateListener(myListener); 83 | dispatcher1.addPlayerStateListener(myListener2); 84 | dispatcher1.dispatcherStart(); 85 | dispatcher1.dispatcherParpered(); 86 | dispatcher1.dispatcherError(0); 87 | dispatcher1.dispatcherComplection(); 88 | 89 | PxLog.d("suntest","集合代理回调"); 90 | //集合代理 91 | IPlayerStateDispatcher dispatcher2 = new PlayerStateDispatcher2(); 92 | dispatcher2.addPlayerStateListener(myListener); 93 | dispatcher2.addPlayerStateListener(myListener2); 94 | dispatcher2.dispatcherStart(); 95 | dispatcher2.dispatcherParpered(); 96 | dispatcher2.dispatcherError(0); 97 | dispatcher2.dispatcherComplection(); 98 | 99 | 100 | // //集合代理+线程代理 101 | // MyLog.d("suntest","集合代理+线程代理回调"); 102 | // IPlayerStateDispatcher dispatcher3 = (IPlayerStateDispatcher) WorkProxy.proxy(new PlayerStateDispatcher2()); 103 | // dispatcher3.addPlayerStateListener(myListener); 104 | // dispatcher3.addPlayerStateListener(myListener2); 105 | // dispatcher3.dispatcherStart(); 106 | // dispatcher3.dispatcherParpered(); 107 | // dispatcher3.dispatcherError(0); 108 | // dispatcher3.dispatcherComplection(); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /app/src/main/java/cn/sun/pxandroidtest/collection/PlayerStateDispatcher.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest.collection; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by sunzheng on 16/6/28. 8 | */ 9 | public class PlayerStateDispatcher implements IPlayerStateDispatcher { 10 | private List playerStateListeners = new ArrayList<>(); 11 | 12 | @Override 13 | public void dispatcherStart() { 14 | synchronized (playerStateListeners) { 15 | for (PlayerStateListener listener : playerStateListeners) { 16 | listener.onStart(); 17 | } 18 | } 19 | } 20 | 21 | @Override 22 | public void dispatcherParpered() { 23 | synchronized (playerStateListeners) { 24 | for (PlayerStateListener listener : playerStateListeners) { 25 | listener.onParpered(); 26 | } 27 | } 28 | } 29 | 30 | @Override 31 | public void dispatcherPause() { 32 | synchronized (playerStateListeners) { 33 | for (PlayerStateListener listener : playerStateListeners) { 34 | listener.onPause(); 35 | } 36 | } 37 | } 38 | 39 | @Override 40 | public void dispatcherStop() { 41 | synchronized (playerStateListeners) { 42 | for (PlayerStateListener listener : playerStateListeners) { 43 | listener.onStop(); 44 | } 45 | } 46 | } 47 | 48 | @Override 49 | public void dispatcherError(int errorCode) { 50 | synchronized (playerStateListeners) { 51 | for (PlayerStateListener listener : playerStateListeners) { 52 | listener.onError(errorCode); 53 | } 54 | } 55 | } 56 | 57 | @Override 58 | public void dispatcherComplection() { 59 | synchronized (playerStateListeners) { 60 | for (PlayerStateListener listener : playerStateListeners) { 61 | listener.onComplection(); 62 | } 63 | } 64 | } 65 | 66 | @Override 67 | public void addPlayerStateListener(PlayerStateListener playerStateListener) { 68 | synchronized (playerStateListeners){ 69 | playerStateListeners.add(playerStateListener); 70 | } 71 | } 72 | 73 | @Override 74 | public void removePlayerStateListener(PlayerStateListener playerStateListener) { 75 | synchronized (playerStateListeners){ 76 | playerStateListeners.remove(playerStateListener); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/cn/sun/pxandroidtest/collection/PlayerStateDispatcher2.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest.collection; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import cn.sun.pxandroid.proxy.CollectionProxy; 7 | 8 | /** 9 | * Created by sunzheng on 16/6/28. 10 | */ 11 | public class PlayerStateDispatcher2 implements IPlayerStateDispatcher { 12 | 13 | private List playerStateListeners = new ArrayList<>(); 14 | 15 | private PlayerStateListener listenerProxy = (PlayerStateListener) CollectionProxy.proxy(playerStateListeners, PlayerStateListener.class); 16 | 17 | @Override 18 | public void dispatcherStart() { 19 | listenerProxy.onStart(); 20 | } 21 | 22 | @Override 23 | public void dispatcherParpered() { 24 | listenerProxy.onParpered(); 25 | } 26 | 27 | @Override 28 | public void dispatcherPause() { 29 | listenerProxy.onPause(); 30 | } 31 | 32 | @Override 33 | public void dispatcherStop() { 34 | listenerProxy.onStop(); 35 | } 36 | 37 | @Override 38 | public void dispatcherError(int errorCode) { 39 | listenerProxy.onError(errorCode); 40 | } 41 | 42 | @Override 43 | public void dispatcherComplection() { 44 | listenerProxy.onComplection(); 45 | } 46 | 47 | @Override 48 | public void addPlayerStateListener(PlayerStateListener playerStateListener) { 49 | synchronized (playerStateListeners) { 50 | playerStateListeners.add(playerStateListener); 51 | } 52 | } 53 | 54 | @Override 55 | public void removePlayerStateListener(PlayerStateListener playerStateListener) { 56 | synchronized (playerStateListeners) { 57 | playerStateListeners.remove(playerStateListener); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/cn/sun/pxandroidtest/collection/PlayerStateListener.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest.collection; 2 | 3 | /** 4 | * Created by sunzheng on 16/6/28. 5 | */ 6 | public interface PlayerStateListener { 7 | 8 | void onStart(); 9 | 10 | void onParpered(); 11 | 12 | void onPause(); 13 | 14 | void onStop(); 15 | 16 | void onError(int errorCode); 17 | 18 | void onComplection(); 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/cn/sun/pxandroidtest/invoke/InvokeTest.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest.invoke; 2 | 3 | import java.lang.reflect.Proxy; 4 | 5 | import cn.sun.pxandroid.PxLog; 6 | 7 | /** 8 | * Created by sunzheng on 16/6/28. 9 | */ 10 | public class InvokeTest implements TestInterface { 11 | public static TestInterface newInstance() { 12 | return (TestInterface) Proxy.newProxyInstance(InvokeTest.class.getClassLoader(), 13 | new Class[]{TestInterface.class}, new TestProxy(new InvokeTest())); 14 | } 15 | 16 | @Override 17 | public void helloWorld() { 18 | PxLog.d("suntest", "helloWorld"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/cn/sun/pxandroidtest/invoke/TestInterface.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest.invoke; 2 | 3 | /** 4 | * Created by sunzheng on 16/6/28. 5 | */ 6 | public interface TestInterface { 7 | void helloWorld(); 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/cn/sun/pxandroidtest/invoke/TestProxy.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest.invoke; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.Method; 5 | 6 | import cn.sun.pxandroid.PxLog; 7 | 8 | /** 9 | * Created by sunzheng on 16/6/28. 10 | */ 11 | public class TestProxy implements InvocationHandler { 12 | private Object subject; 13 | 14 | public TestProxy(Object subject) { 15 | this.subject = subject; 16 | } 17 | 18 | @Override 19 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 20 | PxLog.d("suntest", "TestProxy.before.invoke." + method.getName()); 21 | Object object = method.invoke(subject, args); 22 | PxLog.d("suntest", "TestProxy.after.invoke"); 23 | return object; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/cn/sun/pxandroidtest/mvp/IModel.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest.mvp; 2 | 3 | /** 4 | * Created by sunzheng on 16/6/1. 5 | */ 6 | public interface IModel { 7 | public String getMessage(); 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/cn/sun/pxandroidtest/mvp/IPresenter.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest.mvp; 2 | 3 | /** 4 | * Created by sunzheng on 16/6/1. 5 | */ 6 | public interface IPresenter { 7 | void loadMessage(); 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/cn/sun/pxandroidtest/mvp/IViews.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest.mvp; 2 | 3 | /** 4 | * Created by sunzheng on 16/6/1. 5 | */ 6 | public interface IViews { 7 | public void showMessage(String message); 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/cn/sun/pxandroidtest/mvp/MVPTestActivity.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest.mvp; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.view.View; 6 | import android.widget.TextView; 7 | 8 | import cn.sun.pxandroid.PxLog; 9 | import cn.sun.pxandroid.proxy.WorkProxy; 10 | import cn.sun.pxandroidtest.R; 11 | 12 | /** 13 | * Created by sunzheng on 16/6/1. 14 | */ 15 | public class MVPTestActivity extends Activity implements IViews, View.OnClickListener { 16 | 17 | private IPresenter presenter; 18 | 19 | @Override 20 | protected void onCreate(Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | setContentView(R.layout.activity_mvp_test); 23 | findViewById(R.id.btnMvpTest).setOnClickListener(this); 24 | 25 | IPresenter iPresenter = new Presenter(this, new Model()); 26 | presenter = (IPresenter) WorkProxy.proxy(iPresenter); 27 | } 28 | 29 | @Override 30 | public void showMessage(String message) { 31 | PxLog.d("suntest", "IViews.showMessage." + Thread.currentThread()); 32 | ((TextView) findViewById(R.id.tvTest)).setText(message); 33 | } 34 | 35 | @Override 36 | public void onClick(View v) { 37 | switch (v.getId()) { 38 | case R.id.btnMvpTest: { 39 | //method will be invoke in work thread 40 | presenter.loadMessage(); 41 | } 42 | break; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/cn/sun/pxandroidtest/mvp/Model.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest.mvp; 2 | 3 | import java.util.UUID; 4 | 5 | import cn.sun.pxandroid.PxLog; 6 | import cn.sun.pxandroidtest.TestUtil; 7 | 8 | /** 9 | * Created by sunzheng on 16/6/1. 10 | */ 11 | public class Model implements IModel { 12 | 13 | @Override 14 | public String getMessage() { 15 | PxLog.d("suntest", "Model.getMessage." + Thread.currentThread()); 16 | TestUtil.sleep(500); 17 | return "new message:" + UUID.randomUUID(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/cn/sun/pxandroidtest/mvp/Presenter.java: -------------------------------------------------------------------------------- 1 | package cn.sun.pxandroidtest.mvp; 2 | 3 | import cn.sun.pxandroid.PxLog; 4 | import cn.sun.pxandroid.proxy.UIProxy; 5 | 6 | /** 7 | * Created by sunzheng on 16/6/1. 8 | */ 9 | public class Presenter implements IPresenter { 10 | private IViews iViews; 11 | private IModel model; 12 | 13 | public Presenter(IViews views, IModel model) { 14 | //notice a UI proxy will be returen; 15 | this.iViews = (IViews) UIProxy.proxy(views); 16 | this.model = model; 17 | } 18 | 19 | @Override 20 | public void loadMessage() { 21 | PxLog.d("suntest", "Presenter.loadMessage." + Thread.currentThread()); 22 | //notice this is work thread,耗时操作 23 | String messgae = model.getMessage(); 24 | //next action will be invoked in UI thread 25 | iViews.showMessage(messgae); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 18 | 19 |