標籤:
Android應用的MVC架構,Activity往往充當了View和Control雙重角色,造成代碼耦合性較強。怎樣將View和Control解耦呢,可以使用MVP架構(Model、Control、Prestener)將Activity的View和Control徹底分離,不說廢話了直接上代碼吧!
github: https://github.com/Allin1579/Allin-android
以Activity為例,Fragment的原理相同:
View:我們將Activity看作一個單純的View
package com.allin.android.activity;import com.allin.android.presenter.BasePrestener;import android.app.Activity;import android.os.Bundle;/** * MVP架構中Activity的基類,主要用於與Prestener建立關聯並管理生命週期 * @author Allin * 2015.11.24 * @param <V> BaseActivity子類需繼承的View介面,該介面聲明了Activity的各種視圖操作邏輯, MVP中的V * @param <P> BasePrestener子類, MVP中的P */public abstract class BaseActivity<V, P extends BasePrestener<V>> extends Activity { protected P mPrestener; //持有一個Prestener對象的引用,用來調用Prestener中的資料邏輯 @SuppressWarnings("unchecked") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mPrestener = createPrestener(); mPrestener.attachView((V)this); } @Override protected void onDestroy() { super.onDestroy(); mPrestener.detachView(); } protected abstract P createPrestener(); //mPrestener對象延遲到子類生產 }
Prestener:中介者用來處理資料邏輯和View中視圖邏輯的流程式控制制
package com.allin.android.presenter;import java.lang.ref.Reference;import java.lang.ref.WeakReference;/** * MVP架構中Prestener的基類,主要用於與View建立關聯並管理生命週期 * @author Allin * 2015.11.24 * @param <V> View介面 */public abstract class BasePrestener<V> { protected Reference<V> mViewRef; //持有一個V的引用,用來調用Activity或Fragment中的視圖邏輯 public void attachView(V view){ mViewRef = new WeakReference<V>(view); //此處使用弱引用,防止因Activity或Fragment異常關閉造成記憶體泄露 } protected V getView(){ return mViewRef.get(); } public boolean isViewAttached(){ return mViewRef != null && mViewRef.get() != null; } public void detachView(){ if(mViewRef != null){ mViewRef.clear(); mViewRef = null; } } }
至此,V和C已經完全解耦。
為了避免Prestener臃腫,我們可以將具體邏輯進一步分離,以連網Api為例:
package com.allin.android.api;import java.util.Map;/**Api基類 * @author Allin * 2015.11.24 */class BaseApi { /** * http get請求 * @param url * @param params * @param callback 將網路擷取的資料回調給調用者 */ public void httpGet(final String url, final Map<?, ?> params, final ApiCallback callback){ // TODO Auto-generated method stub } /** * http post請求 * @param url * @param params * @param callback 將網路擷取的資料回調給調用者 */ public void httpPost(final String url, final Map<?, ?> params, final ApiCallback callback){ // TODO Auto-generated method stub }}
Api回調介面:
package com.allin.android.api;/** * ApiCallback * @author Allin * 2015.11.24 */public interface ApiCallback { /** * 網路請求成功的回調 * @param result */ <T> void onSucceed(T result); /** * 網路請求失敗的回調 * @param msg */ void onFailed(String msg);}
Android中的MVP架構