Android App架構設計之編寫基類BaseActivity
Android App架構設計之編寫基類BaseActivity
編寫基類BaseActivity
- OOP裡面子類裡面能夠共用父類的方法,提高代碼的可複用性
- 基類的編寫要根據實際項目的情況,有的可能很簡單 比如只是顯示 “關於” 資訊, 業務功能非常少 你可以不用繼承基類進行擴充
BaseActivity繼承Activity 還是 FragmentActivity 還是其它? 也是根據你的技術要求,因為解決問題的方法有很多種,或者你根本不用寫基類也能完成工作。
我們的目的是編寫較好的代碼,提高代碼可複用性,可擴充性,尤其是團隊協作非常重要,這就是OOP為什麼出現的原因之一。
考慮基類都應寫什嗎?通用的代碼。
網路環境監控 統一的資料介面 生命週期不同方法應該做的事情
剛工作的時候,看Spring源碼 根本就不知道為什麼搞那麼多介面和對象,一層層的。 隨著經驗的積累才知道OOP的好處。
下面我們編寫一個基礎的基類,並不複雜。 假設我們的業務是公司的移動OA系統 我們需要管理員工。
抽象一個員工
//Domine為通用實體類,後面可作為泛型參數有用public class Employee extends Domine { private static final long serialVersionUID = 1L; public Employee() { } public String fullName; public String mobileTel; public String email; public String empNo;}//可以添加公用屬性public class Domine implements Serializable { private static final long serialVersionUID = 1L; public Domine() { } public int id; public String desc;}
資料互動的模型
public class MData implements Serializable { private static final long serialVersionUID = 1L; public String id; public String type; public T dataList;//多種類型資料,一般是List集合,比如擷取所有員工列表}
下面是資料回調介面,我們從網路端擷取資料 需要通知給UI
public interface IDataCallback { //我們一樣傳入通用類型 public void onNewData(T data); public void onError(String msg,int code);}
下面是獨立出來一個UIHandler,一般是寫在Activity裡面作為內部類,我這裡沒有
public class UIHandler extends Handler { private IHandler handler;//回調介面,訊息傳遞給註冊者 public UIHandler(Looper looper) { super(looper); } public UIHandler(Looper looper,IHandler handler) { super(looper); this.handler = handler; } public void setHandler(IHandler handler) { this.handler = handler; } @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (handler != null) { handler.handleMessage(msg);//有訊息,就傳遞 } }}public interface IHandler { public void handleMessage(Message msg);}
我們有了基本的東西,現在組合到BaseActivity中
public abstract class BaseActivity extends Activity { // 可以把常量單獨放到一個Class中 public static final String ACTION_NETWORK_CHANGE = "android.net.conn.CONNECTIVITY_CHANGE"; public static final String ACTION_PUSH_DATA = "fm.data.push.action"; public static final String ACTION_NEW_VERSION = "apk.update.action"; protected static UIHandler handler = new UIHandler(Looper.getMainLooper()); // 資料回調介面,都傳遞Domine的子類實體 protected IDataCallback> dataCallback; public BaseActivity() { } //這個地方有點“模板方法“的設計模式樣子 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setBase(); setHandler(); initContentView(savedInstanceState); } private void setHandler() { handler.setHandler(new IHandler() { public void handleMessage(Message msg) { handler(msg);//有訊息就提交給子類實現的方法 } }); } // 初始化UI,setContentView等 protected abstract void initContentView(Bundle savedInstanceState); // 可能全屏或者沒有ActionBar等 private void setBase() { requestWindowFeature(Window.FEATURE_NO_TITLE);// 例 } protected void addLeftMenu(boolean enable) { // 如果你的項目有側滑欄可以處理此方法 if (enable) { // 是否能有側滑欄 } else { } } //讓子類處理訊息 protected abstract void handler(Message msg); // 橫豎屏切換,鍵盤等 @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { try { super.onRestoreInstanceState(savedInstanceState); } catch (Exception e) { } } @Override protected void onResume() { super.onResume(); // 你可以添加多個Action捕獲 IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_NETWORK_CHANGE); filter.addAction(ACTION_PUSH_DATA); filter.addAction(ACTION_NEW_VERSION); registerReceiver(receiver, filter); //還可能發送統計資料,比如第三方的SDK 做統計需求 } @Override protected void onPause() { super.onPause(); unregisterReceiver(receiver); //還可能發送統計資料,比如第三方的SDK 做統計需求 } BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // 處理各種情況 String action = intent.getAction(); if (ACTION_NETWORK_CHANGE.equals(action)) { // 網路發生變化 // 處理網路問題 } else if (ACTION_PUSH_DATA.equals(action)) { // 可能有新資料 Bundle b = intent.getExtras(); MData mdata = (MData) b.get("data"); if (dataCallback != null) { // 資料通知 dataCallback.onNewData(mdata); } } else if (ACTION_NEW_VERSION.equals(action)) { // 可能發現新版本 // VersionDialog 可能是版本提示是否需要下載的對話方塊 } } }; public void setDataCallback( IDataCallback> dataCallback) { this.dataCallback = dataCallback; }}
有了基類現在編寫一個子類Activity
public class EmployeeDisplayActivity extends BaseActivity implements IDataCallback> { //實現資料回調介面 public EmployeeDisplayActivity() { } @Override protected void initContentView(Bundle savedInstanceState) { setContentView(R.layout.activity_main); loadData(); } private void loadData() { setDataCallback(this);//設定回呼函數 //我們還可以把這個Callback傳給其它擷取資料的類,比如HTTP擷取資料 //比如 HttClient.get(url,this); } @Override public void onNewData(MData data) { //update UI 更新UI資料 final List list = (List) data.dataList; handler.post(new Runnable() { public void run() { //更新UI } }); //或者 handler.sendEmptyMessage(0);//通知Handler } @Override public void onError(final String msg, final int code) { handler.post(new Runnable() { public void run() { //通知錯誤訊息 } }); //或者 handler.sendEmptyMessage(0);//通知Handler } @Override protected void handler(Message msg) { //我們可以處理資料訊息了 switch (msg.what) { case 0: break; case -1: break; default: break; } }}
UML關係圖
本文編寫了基本的BaseActivity代碼,顯然不可能是完美的,需要不斷學習和改進,有問題歡迎探討,Thanks.