Android MVP-编程思想7(为什么使用代理类抽取通用方法而不是工具类?,基类BaseMvpFragment)
Posted 0 and 1
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android MVP-编程思想7(为什么使用代理类抽取通用方法而不是工具类?,基类BaseMvpFragment)相关的知识,希望对你有一定的参考价值。
前言
通过一个小的登录功能模块案例,帮助大家了解MVP。最终实现一个结合Rxjava2,Retrofit 的MVP通用框架。代码放到github上。(如有错误之处,请在评论区指出,谢谢。如果感觉写的不错,请点赞,关注,谢谢。)
目录:
Android MVP-编程思想1(什么是MVC-MVP-MVVM模式?)
Android MVP-编程思想2(代码实现初级版)
Android MVP-编程思想3(内存泄露问题处理,基类封装,有没有必要再使用软引用?)
Android MVP-编程思想4(AOP思想-动态代理运用,反射创建M层实例对象)
Android MVP-编程思想5(如何处理多个P层的问题?)
Android MVP-编程思想6(依赖注入多个P层优化—注解,反射)
Android MVP-编程思想7(为什么使用代理类抽取通用方法而不是工具类?,基类BaseMvpFragment)
未完待续--------
android MVP-编程思想8(集成Rxjava2,Retrofit)
上一小节使用注解和反射优化了P层依赖注入的方式。这一节学习基类BaseMvpFragment,代理类抽取通用方法.
BaseMvpFragment 和BaseMvpActivity 都属于V层的封装,有很多通用的代码,比如注入P层的代码。如何把这些代码抽离复用呢? 很多程序员首先想到的就是做成工具类。当然这种方式也可以,但是总是感觉不优雅。因为,当很多地方都需要使用的情况下我们才会做成工具类,而且工具类一般不依赖系统架构,这里只是两个地方用,而且是服务于MVP架构的代码块。所以做成工具类不太优雅。
还有没有别的方式?
不使用工具类?代理类抽取通用代码
定义代理接口
因为只是抽离P层 注入和销毁的代码所以可以抽象出两个行为接口,如下
public interface IMvpProxy
void bindPresenter();
void unbindPresenter();
代理接口实现类
public class MvpProxyImpl<V extends IBaseView> implements IMvpProxy
private V mView;
private List<BasePresenter> mPresenters;
public MvpProxyImpl(V view)
this.mView = view;
mPresenters = new ArrayList<>();
@Override
public void bindPresenter()
//获得已经申明的变量,包括私有的
Field[] fields = mView.getClass().getDeclaredFields();
for (Field field : fields)
//获取变量上面的注解类型
InjectPresenter injectPresenter = field.getAnnotation(InjectPresenter.class);
if (injectPresenter != null)
try
Class<? extends BasePresenter> type = (Class<? extends BasePresenter>) field.getType();
BasePresenter mInjectPresenter = type.newInstance();
mInjectPresenter.attachView(mView);
field.setAccessible(true);
field.set(mView, mInjectPresenter);
mPresenters.add(mInjectPresenter);
catch (IllegalAccessException e)
e.printStackTrace();
catch (InstantiationException e)
e.printStackTrace();
catch (ClassCastException e)
e.printStackTrace();
throw new RuntimeException("SubClass must extends Class:BasePresenter");
@Override
public void unbindPresenter()
/**
* 解绑,避免内存泄漏
*/
for (BasePresenter presenter : mPresenters)
presenter.detachView();
mPresenters.clear();
mPresenters = null;
BaseMvpActivity代码
public abstract class BaseMvpActivity extends AppCompatActivity
private MvpProxyImpl mvpProxy;
protected List<BasePresenter> mPresenters;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);
View rootView;
final Object layout = getLayout();
if (layout instanceof Integer)
rootView = View.inflate(this, (int) getLayout(), null);
else if (layout instanceof View)
rootView = (View) getLayout();
else
throw new ClassCastException("type of setLayout() must be int or View!");
setContentView(rootView);
mvpProxy = createProxy();
mvpProxy.bindPresenter();
afterCreate();
private MvpProxyImpl createProxy()
if (mvpProxy == null)
return new MvpProxyImpl<>((IBaseView) this);
return mvpProxy;
@Override
protected void onDestroy()
super.onDestroy();
for (BasePresenter p : mPresenters)
p.detachView();
mvpProxy.unbindPresenter();
mPresenters.clear();
mPresenters = null;
@SuppressWarnings("ConstantConditions")
protected <T extends View> T $(@IdRes int viewId)
return findViewById(viewId);
public void showProgress(boolean isShow)
if (isShow)
Log.i("mvp_", "显示等待框");
else
Log.i("mvp_", "隐藏等待框");
public void showToast(String msg)
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
protected abstract Object getLayout();
protected abstract void afterCreate();
BaseMvpFragment 代码
public abstract class BaseMvpFragment extends Fragment
private MvpProxyImpl mvpProxy;
public Activity mActivity;
private View mRootView;
protected abstract @LayoutRes
int getLayoutId();
@Override
public void onAttach(Context context)
super.onAttach(context);
mActivity = (Activity) context;
@SuppressWarnings("ConstantConditions")
protected <T extends View> T $(@IdRes int viewId)
return this.getView().findViewById(viewId);
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
if (mRootView == null)
try
mRootView = inflater.inflate(getLayoutId(), container, false);
catch (Resources.NotFoundException e)
e.printStackTrace();
throw new RuntimeException("根布局的id非法导致根布局为空,请检查后重试!");
mvpProxy = createProxy();
mvpProxy.bindPresenter();
return mRootView;
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
afterCreate();
private MvpProxyImpl createProxy()
if (mvpProxy == null)
return new MvpProxyImpl<>((IBaseView) this);
return mvpProxy;
@Override
public void onDestroyView()
super.onDestroyView();
mvpProxy.unbindPresenter();
protected abstract void afterCreate();
以上是关于Android MVP-编程思想7(为什么使用代理类抽取通用方法而不是工具类?,基类BaseMvpFragment)的主要内容,如果未能解决你的问题,请参考以下文章
Android MVP-编程思想4(AOP思想-动态代理运用,反射创建M层实例对象)
Android MVP-编程思想1(什么是MVC-MVP-MVVM模式?)
Android MVP-编程思想3(MVP-内存泄露问题处理,基类封装,有没有必要再使用软引用?)