Android MVP架构项目搭建封装,基类封装
2017-12-21 14:12
453 查看
综述
对于MVP (Model View Presenter)架构是从著名的MVC(Model View Controller)架构演变而来的。而对于Android应用的开发中本身可视为一种MVC架构。通常在开发中将XML文件视为MVC中的View角色,而将Activity则视为MVC中的Controller角色。不过更多情况下在实际应用开发中Activity不能够完全充当Controller,而是Controller和View的合体。于是Activity既要负责视图的显示,又要负责对业务逻辑的处理。这样在Activity中代码达到上千行,甚至几千行都不足为其,同时这样的Activity也显得臃肿不堪。所以对于MVC架构并不很合适运用于Android的开发中
MVP架构简介
对于一个应用而言我们需要对它抽象出各个层面,而在MVP架构中它将UI界面和数据进行隔离,所以我们的应用也就分为三个层次。
- View: 对于View层也是视图层,在View层中只负责对数据的展示,提供友好的界面与用户进行交互。在Android开发中通常将Activity或者Fragment作为View层。
- Model: 对于Model层也是数据层。它区别于MVC架构中的Model,在这里不仅仅只是数据模型。在MVP架构中Model它负责对数据的存取操作,例如对数据库的读写,网络的数据的请求等。
- Presenter:这一层处理着程序各种逻辑的分发,收到View层UI上的反馈命令、定时命令、系统命令等指令后分发处理逻辑交由Model层做具体的业务操作。
封装应用
[b]BaseView:这个baseView没有做太多的处理,你可以添加一些属于你自己的公共业务逻辑[/b]
[b]BasePresent:我们这里每次将我们的View层作为泛型传入到我们的Presenter层中,并且作为弱引用将其持有,定义初始化数据的方法,并且做绑定和解绑处理,定义一个抽象的销毁方法[/b]
[b]BaseModel:在BaseModel中,我没有做太多的处理,如果你这边需要添加一些自己的业务逻辑,可以将baseModel写为抽象类,方便以后的扩展[/b]
实际应用
直接上代码
直接将View层与Present作为泛型传入其中,将View层与Presenter层进行了绑定,每次将BasePresenter层中的初始化数据方法进行了调用,并且在各个生命周期中,做了防止内存泄漏等。这里我只是抽出了MVP的代码部分进行了讲解,demo中对BaseActivity进行了不错的封装,对Android 兼容性的沉浸式、6.0动态授权,和公共方法的抽取都进行了封装
下面接着来看代码
每次在我们进行调用的时候我是喜欢写这样的一个接口,因为这样的话后期方便你的管理,你直接从Contract中就看了大概你这个Activity做了些什么事情。
这个是Mdoel层的使用
接下来继续看代码
我们的Present层没有进行去 new 一个View 层,仅仅是将我们的泛型坐入其中,让其使用
接下来是我们的View层
在我们的View层中我们主要是刷新UI来使用的。
这就是我今天带来的我理解封装MVP,有不足的地方欢迎大家指正批评。
源码地址:https://github.com/MarkMingShuai/AndroidMVPObject
喜欢的话请点个赞,给个start
对于MVP (Model View Presenter)架构是从著名的MVC(Model View Controller)架构演变而来的。而对于Android应用的开发中本身可视为一种MVC架构。通常在开发中将XML文件视为MVC中的View角色,而将Activity则视为MVC中的Controller角色。不过更多情况下在实际应用开发中Activity不能够完全充当Controller,而是Controller和View的合体。于是Activity既要负责视图的显示,又要负责对业务逻辑的处理。这样在Activity中代码达到上千行,甚至几千行都不足为其,同时这样的Activity也显得臃肿不堪。所以对于MVC架构并不很合适运用于Android的开发中
MVP架构简介
对于一个应用而言我们需要对它抽象出各个层面,而在MVP架构中它将UI界面和数据进行隔离,所以我们的应用也就分为三个层次。
- View: 对于View层也是视图层,在View层中只负责对数据的展示,提供友好的界面与用户进行交互。在Android开发中通常将Activity或者Fragment作为View层。
- Model: 对于Model层也是数据层。它区别于MVC架构中的Model,在这里不仅仅只是数据模型。在MVP架构中Model它负责对数据的存取操作,例如对数据库的读写,网络的数据的请求等。
- Presenter:这一层处理着程序各种逻辑的分发,收到View层UI上的反馈命令、定时命令、系统命令等指令后分发处理逻辑交由Model层做具体的业务操作。
封装应用
在我们初次搭建项目的时候,我们需要一个高扩展的架构,要学会未雨绸缪。在使用MVP架构的时候我们要考虑到如何将View层与Pesenter层进行连接,如何将Model层与Presenter进行连接 首先我们需要一个较好的Base基类
[b]BaseView:这个baseView没有做太多的处理,你可以添加一些属于你自己的公共业务逻辑[/b]
public interface BaseView<T> { //显示进度框 void showDialog(); //隐藏进度框 void dismissDialog(); }
[b]BasePresent:我们这里每次将我们的View层作为泛型传入到我们的Presenter层中,并且作为弱引用将其持有,定义初始化数据的方法,并且做绑定和解绑处理,定义一个抽象的销毁方法[/b]
public abstract class BasePresent<T> { /** * 持有UI接口的弱引用 */ protected WeakReference<T> mViewRef; /** * 获取数据方法 */ public abstract void fetch(); /** * 绑定的方法 * 在onCreate()中调用 * * @param view */ public void attachView(T view) { mViewRef = new WeakReference<T>(view); } /** * 解绑 * 在onDestroy方法中调用,防止内存泄漏 */ public void detach() { if (mViewRef != null) { mViewRef.clear(); mViewRef = null; } onDestroy(); } //释放资源处理 public abstract void onDestroy(); }
[b]BaseModel:在BaseModel中,我没有做太多的处理,如果你这边需要添加一些自己的业务逻辑,可以将baseModel写为抽象类,方便以后的扩展[/b]
public interface BaseModel { }
实际应用
直接上代码
public abstract class BaseActivity<V, T extends BasePresent<V>> extends AppCompatActivity { /** * P层引用 */ protected T mPresent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //创建Presenter层 mPresent = createPresent(); //做绑定 mPresent.attachView((V) this); //P层数据初始化逻辑 mPresent.fetch(); } /* * @params * @name 子类实现具体的构建过程 * @data 2017/11/20 15:39 * @author :MarkShuai */ protected abstract T createPresent(); @Override protected void onDestroy() { mPresent.detach(); super.onDestroy(); Log.d(TAG, "onDestroy()"); } }
直接将View层与Present作为泛型传入其中,将View层与Presenter层进行了绑定,每次将BasePresenter层中的初始化数据方法进行了调用,并且在各个生命周期中,做了防止内存泄漏等。这里我只是抽出了MVP的代码部分进行了讲解,demo中对BaseActivity进行了不错的封装,对Android 兼容性的沉浸式、6.0动态授权,和公共方法的抽取都进行了封装
下面接着来看代码
public interface SerViceUpLoadContract { interface View extends BaseView<SerViceUpLoadContract.Present> { void setProgress(Integer progress); } abstract class Present<T> extends BasePresent<SerViceUpLoadContract.View> { //绑定服务 abstract void bindPresentService(); //开始更新APK abstract void startUpLoadAPK(T t); } interface Model extends BaseModel { //绑定服务 void bindModelService(Context context); //开始下载 void startUpLoad(Context mContext, ProgressListener listener); //观察者的监听接口回调 interface ProgressListener { void onSubscribeProgress(Disposable d); void onNextProgress(Integer progress); void onErrorProgress(Throwable throwable); void onCompleteProgress(); } } }
每次在我们进行调用的时候我是喜欢写这样的一个接口,因为这样的话后期方便你的管理,你直接从Contract中就看了大概你这个Activity做了些什么事情。
public class SerViceUpLoadModel implements SerViceUpLoadContract.Model { private DownloadService.DownloadBinder mDownloadBinder; private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mDownloadBinder = (DownloadService.DownloadBinder) service; } @Override public void onServiceDisconnected(ComponentName name) { mDownloadBinder = null; } }; @Override public void bindModelService(Context context) { Intent intent = new Intent(context, DownloadService.class); context.startService(intent); context.bindService(intent, mConnection, BIND_AUTO_CREATE);//绑定服务 } @Override public void startUpLoad(Context mContext, ProgressListener listener) { File file = new File(mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "test.apk"); boolean isHave = SDCardHelper.fileIsHave(file.getPath()); if (isHave) { ToastUtils.showToast("存在了"); } else { if (mDownloadBinder != null) { long downloadId = mDownloadBinder.startDownload(ContentManager.APK_URL); startCheckProgress(downloadId, mContext, listener); } } } //开始监听进度 private void startCheckProgress(long downloadId, Context mContext, ProgressListener listener) { Observable .interval(100, 200, TimeUnit.MILLISECONDS, Schedulers.io())//无限轮询,准备查询进度,在io线程执行 .filter(time -> mDownloadBinder != null) .map(i -> mDownloadBinder.getProgress(downloadId))//获得下载进度 .takeUntil(progress -> progress >= 100)//返回true就停止了,当进度>=100就是下载完成了 .distinct()//去重复 .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new ProgressObserver(mContext, listener)); } //观察者 private class ProgressObserver implements Observer<Integer> { private Context mContext; private ProgressListener listener; public ProgressObserver(Context mContext, ProgressListener listener) { this.mContext = mContext; this.listener = listener; } @Override public void onSubscribe(Disposable d) { listener.onSubscribeProgress(d); } @Override public void onNext(Integer progress) { listener.onNextProgress(progress); } @Override public void onError(Throwable throwable) { listener.onErrorProgress(throwable); } @Override public void onComplete() { listener.onCompleteProgress(); } } }
这个是Mdoel层的使用
接下来继续看代码
public class SerViceUpLoadPresent<T> extends SerViceUpLoadContract.Present<SerViceUpLoadContract.View> { private Context mContext; private SerViceUpLoadContract.Model mModel; private Disposable mDisposable;//可以取消观察者 public SerViceUpLoadPresent(Context mContext) { this.mContext = mContext; mModel = new SerViceUpLoadModel(); } @Override public void fetch() { } @Override void bindPresentService() { mModel.bindModelService(mContext); } @Override void startUpLoadAPK(SerViceUpLoadContract.View view) { mModel.startUpLoad(mContext, new SerViceUpLoadContract.Model.ProgressListener() { @Override public void onSubscribeProgress(Disposable d) { mDisposable = d; } @Override public void onNextProgress(Integer progress) { view.setProgress(progress); } @Override public void onErrorProgress(Throwable throwable) { throwable.printStackTrace(); ToastUtils.showToast("出错了"); } @Override public void onCompleteProgress() { view.setProgress(100); ToastUtils.showToast("下载完成"); } }); } @Override public void onDestroy() { if (mDisposable != null) { //取消监听 mDisposable.dispose(); } } }
我们的Present层没有进行去 new 一个View 层,仅仅是将我们的泛型坐入其中,让其使用
接下来是我们的View层
public class SerViceUpLoadActivity extends BaseActivity<SerViceUpLoadContract.View, SerViceUpLoadPresent<SerViceUpLoadContract.View>> implements SerViceUpLoadContract.View { @BindView(R.id.bt_upload) Button mButtonUpLoad; @BindView(R.id.down_progress) ProgressBar mDownLoadProgress; @Override public View bindView() { return null; } @Override public int bindLayout() { return R.layout.activity_ser_vice_up_load; } @Override public void initView(View view) { //绑定下载服务 mPresent.bindPresentService(); } @Override public void initDataAfter() { } @Override public void setListener() { mButtonUpLoad.setOnClickListener(this); } @Override public void widgetClick(View v) { switch (v.getId()) { case R.id.bt_upload: mPresent.startUpLoadAPK(this); break; } } @Override protected SerViceUpLoadPresent<SerViceUpLoadContract.View> createPresent() { return new SerViceUpLoadPresent<>(this); } @Override public void showDialog() { LoadingDialog.show(mContext); } @Override public void dismissDialog() { LoadingDialog.dismiss(mContext); } @Override public void setProgress(Integer progress) { mDownLoadProgress.setProgress(progress); } }
在我们的View层中我们主要是刷新UI来使用的。
这就是我今天带来的我理解封装MVP,有不足的地方欢迎大家指正批评。
源码地址:https://github.com/MarkMingShuai/AndroidMVPObject
喜欢的话请点个赞,给个start
相关文章推荐
- 基于Android真实项目教你一步一步搭建架构2 -- Google官方Mvp架构
- Android官方MVP架构示例项目解析
- Android APP架构的那点事儿[MVP架构搭建]
- Android——MVP架构OkHttp的二次封装以及RecyclerView的使用
- Android官方MVP架构示例项目解析
- 从零开始搭建架构实施Android项目
- Android官方MVP架构示例项目解析
- Android -- 带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava(三)
- Arms是一个整合了大量主流开源项目的Android Mvp快速搭建框架
- 如何使用MVP架构Android应用项目
- Android官方MVP架构示例项目解析[转载]
- Android-多列表的项目(Rxjava+Rtrofit+Recyclerview+Glide+Adapter封装)之(一)项目架构
- Android MVP架构 完整封装实例
- 从零开始搭建架构实施Android项目
- mvp+okgo+butterknife搭建android app架构
- 软件设计模式:基于MVP的Android项目架构
- 转:Android官方MVP架构示例项目解析
- 一个Android项目搞定所有主流架构-MVP+单元测试
- Android 开源项目Kotlin+MVP+Retofit2+RxJava2架构开发一款短视频App
- Android面试系列文章2018之架构搭建之MVP模式篇