60a7a6a6921aa2b1b087757f4de44d327fe67a01.svn-base 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package eVVM.apk.mvp;
  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. import java.lang.reflect.Proxy;
  5. /**
  6. * desc : MVP 业务基类
  7. */
  8. public abstract class MvpPresenter<V extends IMvpView> implements InvocationHandler {
  9. // 当前 View 对象
  10. private V mView;
  11. // 代理对象
  12. private V mProxyView;
  13. @SuppressWarnings("unchecked")
  14. public void attach(V view) {
  15. mView = view;
  16. // 使用动态代理,解决 getView 方法可能为空的问题
  17. mProxyView = (V) Proxy.newProxyInstance(view.getClass().getClassLoader(), view.getClass().getInterfaces(), this);
  18. // V 层解绑了 P 层,那么 getView 就为空,调用 V 层就会发生空指针异常
  19. // 如果在 P 层的每个子类中都进行 getView() != null 防空判断会导致开发成本非常高,并且容易出现遗漏
  20. }
  21. /**
  22. * 动态代理接口,每次调用了代理对象的方法最终也会回到到这里
  23. *
  24. * {@link InvocationHandler}
  25. */
  26. @Override
  27. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  28. // 如果当前还是绑定状态就执行 View 的方法,否则就不执行
  29. return isAttached() ? method.invoke(mView, args) : null;
  30. }
  31. public void detach() {
  32. mView = null;
  33. // 这里注意不能把代理对象置空
  34. // mProxyView = null;
  35. }
  36. public boolean isAttached() {
  37. return mProxyView != null && mView != null;
  38. }
  39. public V getView() {
  40. return mProxyView;
  41. }
  42. /**
  43. * P 层初始化方法
  44. */
  45. public abstract void start();
  46. }