国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

MVP理解與實(shí)踐

2019-11-09 14:03:56
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

MVP模式概念

在MVP模式里通常包含4個(gè)要素:

View:負(fù)責(zé)繪制UI元素、與用戶進(jìn)行交互(在Android中體現(xiàn)為Activity); View interface:需要View實(shí)現(xiàn)的接口,View通過View interface與PResenter進(jìn)行交互,降低耦合,方便進(jìn)行單元測(cè)試; Model:負(fù)責(zé)存儲(chǔ)、檢索、操縱數(shù)據(jù)(有時(shí)也實(shí)現(xiàn)一個(gè)Model interface用來(lái)降低耦合);Presenter:作為View與Model交互的中間紐帶,處理與用戶交互的負(fù)責(zé)邏輯。

??在Android開發(fā)中,Activity并不是一個(gè)標(biāo)準(zhǔn)的MVC模式中的Controller,它 的首要職責(zé)是加載應(yīng)用的布局和初始化用戶界面,并接受并處理來(lái)自用戶的操作請(qǐng)求,進(jìn)而作出響應(yīng)。隨著界面及其邏輯的復(fù)雜度不斷提升,Activity類的職責(zé)不斷增加,以致變得龐大臃腫。 ??當(dāng)我們將其中復(fù)雜的邏輯處理移至另外的一個(gè)類(Presneter)中時(shí),Activity其實(shí)就是MVP模式中 View,它負(fù)責(zé)UI元素的初始化,建立UI元素與Presenter的關(guān)聯(lián)(Listener之類),同時(shí)自己也會(huì)處理一些簡(jiǎn)單的邏輯(復(fù)雜的邏輯交由 Presenter處理)。

MVP與MVC模式對(duì)比

MVP模式:

View不直接與Model交互,而是通過與Presenter交互來(lái)與Model間接交互Presenter與View的交互是通過接口來(lái)進(jìn)行的,更有利于添加單元測(cè)試通常View與Presenter是一對(duì)一的,但復(fù)雜的View可能綁定多個(gè)Presenter來(lái)處理邏輯

MVC模式:

View可以與Model直接交互Controller是基于行為的,并且可以被多個(gè)View共享

MVP項(xiàng)目代碼組織方式

項(xiàng)目含一個(gè)app src目錄,4個(gè)測(cè)試目錄:

測(cè)試目錄 分別是androidTest(UI層測(cè)試)、androidTestMock(UI層測(cè)試mock數(shù)據(jù)支持)、test(業(yè)務(wù)層單元測(cè)試)、mock(業(yè)務(wù)層單元測(cè)試mock數(shù)據(jù)支持)。

src目錄

按照功能組織,功能內(nèi)部分為xactivity、xcontract、xfragment、xpresenter四個(gè)類文件(x代表業(yè)務(wù)名稱);按照類型組織,比如按照activity、adapter、fragment、contract、presenter進(jìn)行劃分,不同的類文件分別放到不同的目錄中。

MVP具體應(yīng)用實(shí)現(xiàn)

/** * mvp 中的 v */public interface IView { /** * 添加 presenter */ void addPresenter(ipresenter presenter); /** * 結(jié)束當(dāng)前view */ void finish();}
/** * mvp中的P */public interface IPresenter { /** * 回調(diào) * @return true,已經(jīng)處理. */ boolean onActivityResult(int requestCode, int resultCode, Intent data); /** * 注冊(cè)廣播 */ String[] registerLocalReceivers(); /** * 接收到廣播 */ void onLocalReceive(Intent intent); /** * UI銷毀,釋放view */ void onDestroyView();}/** * 業(yè)務(wù)處理基類 */public abstract class AbsPresenter implements IPresenter { protected AppCompatActivity mActivity; protected Context mContext; protected LoaderManager mLoaderManager; public AbsPresenter(@NonNull IView view) { if (view instanceof AppCompatActivity) { initWithActivity((AppCompatActivity) view); } else if (view instanceof Fragment) { initWithFragment((Fragment) view); } else if (view instanceof ActivityInstrumentationTestCase2) { ActivityInstrumentationTestCase2 testCase = (ActivityInstrumentationTestCase2) view; mContext = testCase.getActivity(); mActivity = (AppCompatActivity) testCase.getActivity(); mLoaderManager = mActivity.getSupportLoaderManager(); } else { throw new RuntimeException("view must be instance of AppCompatActivity or Fragment."); } } private void initWithActivity(AppCompatActivity activity) { mActivity = activity; mContext = mActivity; mLoaderManager = mActivity.getSupportLoaderManager(); } private void initWithFragment(Fragment fragment) { mActivity = (AppCompatActivity) fragment.getActivity(); mContext = fragment.getContext(); mLoaderManager = fragment.getLoaderManager(); } @Override public boolean onActivityResult(int requestCode, int resultCode, Intent data) { return false; } @Override public String[] registerLocalReceivers() { return new String[0]; } @Override public void onLocalReceive(Intent intent) { } @Override @CallSuper public void onDestroyView() { mActivity = null; mContext = null; mLoaderManager = null; }}

MVP中的M也就是Model層一般和Bean實(shí)體會(huì)抽離出來(lái),作為中間件接口調(diào)用,如ModelService Module


實(shí)現(xiàn)某個(gè)具體業(yè)務(wù)流程如下:

定義某個(gè)業(yè)務(wù)Presenter接口IXxPresenter extends IPresenter定義某個(gè)業(yè)務(wù)顯示View接口IXxView extends IView實(shí)現(xiàn)某個(gè)業(yè)務(wù)Presenter–XxPresenter(增刪查改) extends AbsPresenter implements IXxPresenter, LoaderManager.LoaderCallbacks<Cursor>private IXxView mView;private XxTask mXxTask;public XxPresenter(@NonNull IXxView view) { super(view); mView = view;}@Overridepublic Loader<Cursor> onCreateLoader(int id, Bundle args) {//返回一個(gè)new CursorLoader對(duì)象}@Overridepublic void onLoadFinished(Loader<Cursor> loader, Cursor data) {//完成對(duì)UI主界面的更新 if(mView != null) { mView.showXx(); }}@Overridepublic void onLoaderReset(Loader<Cursor> loader) {}@Overridepublic void queryXx() { mLoaderManager.destroyLoader(AppConst.LOADER_ID.XXX); mLoaderManager.initLoader(AppConst.LOADER_ID.XXX, null, this);}@Overridepublic void updateXx() { if (mXxTask == null || mXxTask.getStatus() != AsyncTask.Status.RUNNING) { mXxTask = new XxTask(); mXx.execute(); }}//deleteXx //saveXx(insert && update,根據(jù)是否有有效ID值判斷)private void destroyLoader() { mLoaderManager.destroyLoader(AppConst.LOADER_ID.XXX); mLoaderManager.destroyLoader(AppConst.LOADER_ID.YYY);}@Overridepublic void onDestroyView() { destroyLoader(); if (mXxTask != null) { mXxTask.cancel(true); mXxTask = null; } mView = null; super.onDestroyView();}private class XxTask extends AsyncTask<Void, Void, Boolean> { private xx; private xxx; XxTask() { //初始化成員變量 } @Override protected Boolean doInBackground(Void... params) { //返回類型自定義 } @Override protected void onPostExecute(Boolean res) { super.onPostExecute(res); if(mView != null) { mView.showXx(); } }}

Presenter實(shí)例化

/** * Presenter工廠,用于實(shí)例化相對(duì)的Presenter */public interface IPresenterFactory { /** * 返回Presenter實(shí)現(xiàn)類的實(shí)例 */ @Nullable IPresenter newPresenter(IView view, Class clazz);}/** * Presenter實(shí)例化工廠 */public class PresenterFactory implements IPresenterFactory { @Nullable @Override public IPresenter newPresenter(IView view, Class clazz) { final String className = clazz.getName(); IPresenter presenter = null; if (view instanceof IXxView && className.equals(IXxPresenter.class.getName())) { IXxView xxView = (IXxView) view; return new XxPresenter(xxView); } }}/** * app application */public class XxApplication extends ApplicationWrapper { @Override public void onCreate() { super.onCreate(); ...... // presenter初始化 Presenter.init(new PresenterFactory()); ...... }}

Presenter與Activity綁定,Activity實(shí)現(xiàn)View接口

/** * Activity基類 */public abstract class BaseActivity extends AppCompatActivity { protected Context mContext = this; protected ActionBar mActionBar; protected Toolbar mToolbar; protected TextView mTitleTv; protected ImageView mIconIv; private List<IPresenter> mPresenterList = new ArrayList<>(); private BroadcastReceiver mReceiver; @Override @CallSuper protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { AppBarActivity.this.onLocalReceive(intent); } }; registerLocalReceiver(); } @Override @CallSuper protected void onDestroy() { unregisterLocalReceiver(); for (IPresenter presenter : mPresenterList) { presenter.onDestroyView(); } super.onDestroy(); } /** * 查找控件 */ @CallSuper protected void findWidget() { mToolbar = (Toolbar) findViewById(R.id.toolbar); mTitleTv = (TextView) findViewById(R.id.title_tv); mIconIv = (ImageView) findViewById(R.id.logo_iv); } /** * 顯示或隱藏標(biāo)題圖標(biāo),由子類去實(shí)現(xiàn) */ protected void showIcon(boolean show) { if (show) { mIconIv.setVisibility(View.VISIBLE); mTitleTv.setVisibility(View.GONE); } else { mIconIv.setVisibility(View.GONE); mTitleTv.setVisibility(View.VISIBLE); } } /** * 設(shè)置標(biāo)題 */ public void setTitle(String title) { mTitleTv.setText(title); } /** * 設(shè)置actionBar的顯示和隱藏 */ public void setActionBarVisibility(int visibility) { mToolbar.setVisibility(visibility); } /** * 隱藏標(biāo)題 */ public void hideAppBar() { if (mToolbar != null) { mToolbar.setVisibility(View.GONE); } } /** * 初始化控件 */ protected void initWidget() { if (mToolbar != null) { setSupportActionBar(mToolbar); mActionBar = getSupportActionBar(); if (mActionBar != null) { mActionBar.setDisplayShowTitleEnabled(false); mActionBar.setDisplayHomeAsUpEnabled(true); mActionBar.setHomeAsUpIndicator(R.drawable.icon_back); } } } protected void setListener() { } @CallSuper public void addPresenter(IPresenter presenter) { mPresenterList.add(presenter); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { onBackPressed(); return true; } else { return super.onOptionsItemSelected(item); } } @CallSuper protected void onLocalReceive(Intent intent) { for (IPresenter presenter : mPresenterList) { presenter.onLocalReceive(intent); } } @CallSuper protected String[] registerLocalReceivers() { ArrayList<String> allActionList = new ArrayList<>(); List<String> actionList; for (IPresenter presenter : mPresenterList) { actionList = Arrays.asList(presenter.registerLocalReceivers()); allActionList.addAll(actionList); } String[] actions = new String[allActionList.size()]; actions = allActionList.toArray(actions); return actions; } private void registerLocalReceiver() { LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(mContext); IntentFilter intentFilter = new IntentFilter(); String[] actions = registerLocalReceivers(); for (String action : actions) { intentFilter.addAction(action); } localBroadcastManager.registerReceiver(mReceiver, intentFilter); } private void unregisterLocalReceiver() { LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(mContext); localBroadcastManager.unregisterReceiver(mReceiver); }}XxActivity extends BaseActivity implements IXxView, IXxxView, ...private IXxPresenter mXxPresenter;@Overrideprotected void onCreate(Bundle savedInstanceState) { Presenter.bind(this, IXxPresenter.class, IXxxPresenter.class, ...); super.onCreate(savedInstanceState); //setContentView() findWidget(); initWidget(); setListener();}@Overridepublic void addPresenter(IPresenter presenter) { super.addPresenter(presenter); if (presenter instanceof IXxPresenter) { mXxPresenter = (IXxPresenter) presenter; }...}/** * 初始化控件 */@Overrideprotected void initWidget() { super.initWidget(); if(mXxPresenter != null) { mXxPresenter.queryXx();//查詢數(shù)據(jù) }}@Overridepublic void showXx(params) {//傳遞數(shù)據(jù)//顯示數(shù)據(jù)到UI界面}
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 伊川县| 金阳县| 陈巴尔虎旗| 渭源县| 云梦县| 涿州市| 当雄县| 枝江市| 什邡市| 教育| 泰顺县| 耿马| 和平县| 镇赉县| 衡水市| 盐亭县| 抚顺县| 肥乡县| 金阳县| 墨玉县| 修武县| 敖汉旗| 双牌县| 社会| 德化县| 桐梓县| 沐川县| 邓州市| 滕州市| 韶关市| 德格县| 德江县| 海门市| 保德县| 平塘县| 东城区| 嘉兴市| 宝清县| 沂水县| 南阳市| 鲁山县|