編輯:Android資訊
本文由碼農網 – 蘇耀東原創,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃!
本文是參考google官方發布的MVP架構demo以及前人對MVP實現方式的一些總結做的一個簡單demo,在這裡記錄一下一點心得,希望能給想用MVP的人一點幫助。
首先先看下整個工程的目錄結構:
目錄的代碼組織方式是按照功能來組織的,功能內部分為xactivity、xcontract、xfragment、xpresenter四個類文件(x代表業務名稱)。base文件夾存放一些公用的基類文件,data文件夾存放業務邏輯相關的代碼,utils文件夾則放一些公用的工具類。本demo實現的功能為:通過點擊界面上的按鈕,獲取手機相關信息,獲取過程中加入延時及等待提示(模擬網絡),最終將信息顯示於界面上(簡單演示,只是顯示了系統時間)。
先看下BasePresenter與BaseView這兩個接口類,它們分別是所有Presenter與View的基類。
public interface BasePresenter { void start(); }
BasePresenter中含有方法start(),該方法的作用是presenter開始獲取數據並調用view中方法改變界面顯示,其調用時機是在Fragment類的onResume方法中。
public interface BaseView<T> { void setPresenter(T presenter); }
BaseView中含方法setPresenter,該方法作用是將presenter實例傳入view中,其調用時機是在activity的presenter實現類的構造函數中。
public interface GetPhoneInfoContract { interface View extends BaseView<Presenter> { void setTime(String time); void showLoading(); void hideLoading(); } interface Presenter extends BasePresenter { void getTime(); } }
與比較常見的mvp實現不同,官方的實現中加入了契約類來統一管理view與presenter的所有的接口,這種方式使得view與presenter中有哪些功能,一目了然,維護起來也方便,該實例中presenter的接口實現獲取系統時間,view的接口實現時間的顯示以及提示對話框的顯示及隱藏。
activity作為全局的控制者,負責創建view以及presenter實例,並將二者聯系起來,具體的view交由fragment來實現,兩者各司其職。
@EActivity(R.layout.get_phone_info_act) public class GetPhoneInfoActivity extends ActionBarActivity { private FragmentManager fm; private GetPhoneInfoFragment mGetPhoneInfoFragment = new GetPhoneInfoFragment_(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setDefaultFragment(); new GetPhoneInfoPresenter(mGetPhoneInfoFragment); } private void setDefaultFragment() { fm = getFragmentManager(); FragmentTransaction transaction = fm.beginTransaction(); transaction.add(R.id.fragcontent, mGetPhoneInfoFragment); transaction.commit(); } }
本例中,activity中通過setDefaultFragment()設置了fragment,之後實例化GetPhoneInfoPresenter,並將frament傳遞進去,實現在presenter中通過fragment的接口對view進行操作展示。
public class GetPhoneInfoPresenter implements GetPhoneInfoContract.Presenter{ private final GetPhoneInfoContract.View mGetPhoneInfoView; private PhoneInfoBiz phoneInfoBiz; public GetPhoneInfoPresenter(GetPhoneInfoContract.View getPhoneInfoView) { mGetPhoneInfoView = getPhoneInfoView; mGetPhoneInfoView.setPresenter(this); phoneInfoBiz = new PhoneInfoBizIml(); } @Override public void start() { getTime(); } @Override public void getTime() { mGetPhoneInfoView.showLoading(); phoneInfoBiz.getPhoneInfo(new PhoneInfoBiz.GetPhoneInfoCallback() { @Override public void onGetPhoneInfo(PhoneInfo phoneInfo) { mGetPhoneInfoView.setTime(phoneInfo.getTime()); mGetPhoneInfoView.hideLoading(); } }); } }
presenter構造函數中調用了view的setPresenter方法將自身實例傳入,start方法中處理了數據加載與展示。如果需要界面做對應的變化,直接調用view層的方法即可,這樣view層與presenter層就能夠很好的被劃分。
@EFragment(R.layout.get_phone_info_frag) public class GetPhoneInfoFragment extends Fragment implements GetPhoneInfoContract.View { private GetPhoneInfoContract.Presenter mPresenter; ProgressDialog dialog; @ViewById TextView tv_time; @ViewById Button btn_get_time; @Click void btn_get_time() { mPresenter.getTime(); } @AfterViews void initView() { dialog = new ProgressDialog(getActivity()); } @Override public void onResume() { super.onResume(); mPresenter.start(); } @Override public void setPresenter(GetPhoneInfoContract.Presenter presenter) { if (presenter != null) mPresenter = presenter; } @Override @UiThread public void setTime(String time) { tv_time.setText(time); } @Override public void showLoading() { dialog.setTitle("請稍候"); dialog.setMessage("loading!"); dialog.show(); } @Override public void hideLoading() { dialog.dismiss(); } }
setPresenter方法繼承於父類,通過該方法,view獲得了presenter得實例,從而可以調用presenter代碼來處理業務邏輯。在onResume中還調用了presenter得start方法,處理數據的加載與展示。
簡單介紹下model層,PhoneInfo對象存儲手機相關信息,PhoneInfoBiz為借口類實現該業務所需要的接口及回調接口,PhoneInfoBizIml為接口的實現類。直接貼代碼:
public interface PhoneInfoBiz { interface GetPhoneInfoCallback { void onGetPhoneInfo(PhoneInfo phoneInfo); } void getPhoneInfo(GetPhoneInfoCallback getPhoneInfoCallback); } public class PhoneInfoBizIml implements PhoneInfoBiz{ @Override public void getPhoneInfo(final GetPhoneInfoCallback getPhoneInfoCallback) { new Thread(new Runnable() { @Override public void run() { try { PhoneInfo phoneInfo = new PhoneInfo(); phoneInfo.setTime(System.currentTimeMillis() + ""); phoneInfo.setMobileType(Build.MODEL); phoneInfo.setMobileVer(Build.VERSION.RELEASE); Thread.sleep(1000); getPhoneInfoCallback.onGetPhoneInfo(phoneInfo); }catch(Exception e){ e.printStackTrace(); } } }).start(); } }
至此,一個簡單的mvp框架到此結束,對於mvp的使用目前也還在探索中,上例是結合官方發布的demo做的一個簡化工程,有不足之處歡迎一起探討交流!
最後附上本文demo及官方demo的地址:本文demo鏈接 官方demo鏈接 個人博客
我相信每一個安卓開發者都會同意 2015年安卓開發者大會上宣布的最大事情就是 Android Studio 2.0和安卓模擬器2.0,其中安卓模擬器2.0宣稱運行
一直有一個幾乎所有機友都認同的說法:Android 是全球用戶數最多的操作系統,市場份額十分驚人。無論是問你的表哥表姐,還是弟弟妹妹,即便他們不是很關注移動領域或
Jenkins簡介 Jenkins是一個開源軟件項目,旨在提供一個開放易用的軟件平台,使軟件的持續集成變成可能。目前大部分公司都在使用Jenkins來持續構建。
顧名思義,AndroidEventBus ( github鏈接 : https://github.com/bboyfeiyu/AndroidEventBus )是