編輯:關於Android編程
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.
最近因為項目中用到類似一個LinearLayout中水平布局中,有一個TextView和Button,然後對該LinearLayout布局設置點擊事件,點擊TextVie
adb驅動已正常安裝,但仍無法通過adb devices找到設備?Windows用戶方法1如果有sdk環境,只需要進入路徑/{sdk目錄}/tools/,再
??上一篇中,我們已經介紹了屬性動畫的基本使用,至少在動畫應用上問題不大,而本篇我們將來了解插值器(Interpolator)和類型估算器(TypeEvaluator)的
需求:Activity(fragment)跳轉的時候當前界面裂開,上下各自拉出手機屏幕,之後跳轉到相對應的Activity.整體效果圖如下思路:1,在當前Activity