Mosby——a mode-view-presenter library for anroid_3.1.0

Github地址
使用手册 :
Model-View-Presenter library for android

model:获取数据模型
view:视图、数据展示
Presenter:持有view和model的引用,从model获取数据模型,通知view去更新视图

在这里插入图片描述

这是一个内部使用代理和组合实现的库,不是一个框架,没有框架的限制。
去掉所有三方库,三方库的维护和升级都会带来问题。

总结:
Activity持有presenter的引用
Presenter持有MvpView的引用

  • Activity在onCreate()、onDestroy()
  • Fragment在onViewCreated()、onDestroyView()
  • View在onAttachedToWindow()、onDetachedFromWindow()
presenter.attachView(getMvpView()); //presenter通过弱引用持有view的引用
presenter.detachView(); //presenter移除view的引用

mosby源码介绍

    dependencies {
    	compile 'com.hannesdorfmann.mosby3:mvp-lce:3.1.0'
    	compile 'com.hannesdorfmann.mosby3:mvp-nullobject-presenter:3.1.0'
    }

MvpLceActivity 相对于MvpActivity,多了一个loadingView、

//CV contentView、M setData()中的数据模型,V view interface, P presenter
public abstract class MvpLceActivity<CV extends View, M, V extends MvpLceView<M>, P extends MvpPresenter<V>>
    extends MvpActivity<V, P> implements MvpLceView<M> {

  protected View loadingView;
  protected CV contentView;
  protected TextView errorView;

//当Activity的布局改动时,即setContentView()或者addContentView()方法执行完毕时就会调用该方法
  @CallSuper @Override public void onContentChanged() {
    super.onContentChanged();
    //createView 都是通过findViewById()来实现的,所以继承自MvpLceActivity的layoutResId都要包含这几个resId
    loadingView = createLoadingView();  // findViewById(R.id.loadingView);
    contentView = createContentView(); // (CV) findViewById(R.id.contentView);
    errorView = createErrorView(); // (TextView) findViewById(R.id.errorView);
	//省略判断,loadingView、contentView、errorView都不能为空,且为errorView注册监听事件
  }

// errorView的监听事件
  protected void onErrorViewClicked() {
    loadData(false);
  }

//pullToRefresh 为true,由refreshLayout进行加载动画(下拉刷新,上拉加载),false,由自己处理
  @Override public void showLoading(boolean pullToRefresh) {
    if (!pullToRefresh) {
      animateLoadingViewIn();
    }
  }

//子类重写,可以自定义错误提示文本
  protected abstract String getErrorMessage(Throwable e, boolean pullToRefresh);

  protected void showLightError(String msg) {
    Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
  }

  @Override public void showError(Throwable e, boolean pullToRefresh) {
    String errorMsg = getErrorMessage(e, pullToRefresh);
    if (pullToRefresh) { //如果是refreshLayout产生的下拉刷新和上拉加载,则直接toast
      showLightError(errorMsg); 
    } else { //否则展示错误layout
      errorView.setText(errorMsg); 
      animateErrorViewIn();
    }
  }

// 展示loading
  protected void animateLoadingViewIn() {
    LceAnimator.showLoading(loadingView, contentView, errorView);
  }

// 展示content
  @Override public void showContent() {
     LceAnimator.showContent(loadingView, contentView, errorView);
  }
  
  // 展示errorView
  protected void animateErrorViewIn() {
    LceAnimator.showErrorView(loadingView, contentView, errorView);
  }
  
}

MvpActivity
使用代理

//V view interface, P presenter
public abstract class MvpActivity<V extends MvpView, P extends MvpPresenter<V>>
    extends AppCompatActivity implements MvpView,
    com.hannesdorfmann.mosby3.mvp.delegate.MvpDelegateCallback<V,P>{

  protected ActivityMvpDelegate mvpDelegate; //使用代理
  protected P presenter; //提供get、set操作
  protected boolean retainInstance;

  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getMvpDelegate().onCreate(savedInstanceState);
  }

  @Override protected void onDestroy() {
    super.onDestroy();
    getMvpDelegate().onDestroy();
  }

  @NonNull public abstract P createPresenter(); //创建presenter

  @NonNull protected ActivityMvpDelegate<V, P> getMvpDelegate() {
    if (mvpDelegate == null) {
      mvpDelegate = new ActivityMvpDelegateImpl(this, this, true); //创建代理类
    }
    return mvpDelegate;
  }

  @NonNull @Override public V getMvpView() {
    return (V) this; //得到activity的引用转为viewInterface
  }
}

MvpLceView,通用的用于MvpLceActivity。
MvpView 是一个空接口

public interface MvpLceView<M> extends MvpView {

  @UiThread
  void showLoading(boolean pullToRefresh); //耗时操作展示loading

  @UiThread
  void showContent(); //请求正确展示内容

  @UiThread
  void showError(Throwable e, boolean pullToRefresh); //请求错误的回调

  @UiThread
  void setData(M data); 设置数据源,一般和showContent一起使用

  @UiThread
  void loadData(boolean pullToRefresh); //加载数据
}

ActivityMvpDelegateImpl 代理实现类

public class ActivityMvpDelegateImpl<V extends MvpView, P extends MvpPresenter<V>>
    implements ActivityMvpDelegate {

  protected static final String KEY_MOSBY_VIEW_ID = "com.hannesdorfmann.mosby3.activity.mvp.id";

  private MvpDelegateCallback<V, P> delegateCallback;
  protected boolean keepPresenterInstance;
  protected Activity activity;
  protected String mosbyViewId = null;

  public ActivityMvpDelegateImpl(@NonNull Activity activity,
      @NonNull MvpDelegateCallback<V, P> delegateCallback, boolean keepPresenterInstance) {
// 空判断
    this.delegateCallback = delegateCallback;
    this.activity = activity;
    this.keepPresenterInstance = keepPresenterInstance;
  }

  static boolean retainPresenterInstance(boolean keepPresenterInstance, Activity activity) {
    return keepPresenterInstance && (activity.isChangingConfigurations()
        || !activity.isFinishing());
  }

  private P createViewIdAndCreatePresenter() {
    P presenter = delegateCallback.createPresenter(); //获取presenter
    if (keepPresenterInstance) { //做缓存,下次直接从缓存取
      mosbyViewId = UUID.randomUUID().toString();
      PresenterManager.putPresenter(activity, mosbyViewId, presenter);
    }
    return presenter;
  }

  @Override public void onCreate(Bundle bundle) {
    P presenter = null;
    if (bundle != null && keepPresenterInstance) {
      mosbyViewId = bundle.getString(KEY_MOSBY_VIEW_ID);

      if (mosbyViewId != null
          && (presenter = PresenterManager.getPresenter(activity, mosbyViewId)) != null) {
      //如果缓存里有,则直接从缓存中获取
      } else {
      //没有缓存,直接创建,most likely caused by process death
        presenter = createViewIdAndCreatePresenter();
      }
    } else {
      //activity第一次启动时,直接创建
      presenter = createViewIdAndCreatePresenter();
    }
    delegateCallback.setPresenter(presenter); //给代理设置缓存
    getPresenter().attachView(getMvpView()); //presenter持有view的引用
  }

//通过接口引用获取presenter
  private P getPresenter() {
    P presenter = delegateCallback.getPresenter();
    return presenter;
  }

//通过接口引用获取view
  private V getMvpView() {
    V view = delegateCallback.getMvpView();
    return view;
  }

  @Override public void onDestroy() {
    boolean retainPresenterInstance = retainPresenterInstance(keepPresenterInstance, activity);
    getPresenter().detachView(); //presenter移除view的引用
    if (!retainPresenterInstance){
      getPresenter().destroy();
    }
    if (!retainPresenterInstance && mosbyViewId != null) {
      PresenterManager.remove(activity, mosbyViewId);
    }
  }
}

MvpPresenter

public interface MvpPresenter<V extends MvpView> {

  @UiThread
  void attachView(@NonNull V view); //添加view的引用

  @UiThread
  void detachView(); //移除view的引用

  @UiThread
  void destroy();
}

MvpBasePresenter

public class MvpBasePresenter<V extends MvpView> implements MvpPresenter<V> {

  public interface ViewAction<V> {
    void run(@NonNull V view);
  }

  private WeakReference<V> viewRef; //弱引用
  private boolean presenterDestroyed = false;

//添加view的引用
  @UiThread @Override public void attachView(V view) {
    viewRef = new WeakReference<V>(view);
    presenterDestroyed = false;
  }

  protected final void ifViewAttached(boolean exceptionIfViewNotAttached, ViewAction<V> action) {
    final V view = viewRef == null ? null : viewRef.get();
    if (view != null) {
      action.run(view);
    } else if (exceptionIfViewNotAttached) {
      throw new IllegalStateException(
          "No View attached to Presenter. Presenter destroyed = " + presenterDestroyed);
    }
  }

//如果viewAttached,执行viewAction
  protected final void ifViewAttached(ViewAction<V> action) {
    ifViewAttached(false, action);
  }

 //移除view的引用
  @Override public void detachView() {
    if (viewRef != null) {
      viewRef.clear();
      viewRef = null;
    }
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值