從頭開始敲代碼之《從BaseApplication/Activity開始》,applicationactivity
轉載請註明出處王亟亟的大牛之路
其安易持,其未兆易謀;其脆易泮,其微易散。為之於未有,治之於未亂。合抱之木,生於毫末;九層之台,起於壘土;千裡之行,始於足下。為者敗之,執者失之。是以聖人無為故無敗,無執故無失。民之從事,常於幾成而敗之。慎終如始,則無敗事。是以聖人慾不欲,不貴難得之貨,學不學,複眾人之所過,以輔萬物之自然而不敢為。
作為系列專題的第一篇,這一篇文章屬於小難產,中間夾雜著一些工作上的事,一些蛋疼的事(學車之類的),說實在的,做了Coder之後發現業餘時間還真不是太多。。。。唉。。。整個專欄的前 5 6篇將會比較簡單,便於過度。
包目錄:
好,廢話不多進入正題
這篇文章幹什麼呢?
對我們平時用的最多相當較為常用的Activity進行簡單的封裝,以滿足基礎的需求
封裝是什嗎?封裝的好處是什嗎?
1.將抽象得到的資料和行為(或功能)相結合,形成一個有機的整體.
2.增強安全性和簡化編程,使用者不必瞭解具體的實現細節,而只是要通過外部介面,以特定的存取權限來使用類的成員.
這一篇來自訂我們自己的 BaseApplication 以及 BaseActivity
為什麼要那麼做?
白話版:把什麼初始化,稀裡嘩啦一大堆的Toast Dialog的工具全部丟進去,讓後續的Activity的業務更清晰。
每一次的例子都是自己花心思寫的,品質好壞客觀見諒
BaseActivity
public class BaseApplication extends Application{ /* * 初始化TAG * */ private static String TAG=BaseApplication.class.getName(); /*Activity堆*/ private Stack<Activity> activityStack = new Stack<Activity>(); @Override public void onCreate() { super.onCreate(); LogUtils.d(TAG,TAG+"---onCreate()"); printAppParameter(); } /*列印出一些app的參數*/ private void printAppParameter(){ LogUtils.d(TAG, "OS : "+Build.VERSION.RELEASE + " ( " + Build.VERSION.SDK_INT + " )"); DeviceMgr.ScrSize realSize = DeviceMgr.getScreenRealSize(this); LogUtils.d(TAG, "Screen Size: " + realSize.w + " X " + realSize.h); } public void addActivity(final Activity curAT) { if (null == activityStack) { activityStack = new Stack<Activity>(); } activityStack.add(curAT); } public void removeActivity(final Activity curAT) { if (null == activityStack) { activityStack = new Stack<Activity>(); } activityStack.remove(curAT); } //擷取最後一個Activity public Activity currentActivity() { Activity activity = activityStack.lastElement(); return activity; } //返回寨內Activity的總數 public int howManyActivities() { return activityStack.size(); } //關閉所有Activity public void finishAllActivities() { for (int i = 0, size = activityStack.size(); i < size; i++) { if (null != activityStack.get(i)) { activityStack.get(i).finish(); } } activityStack.clear(); }}
上面就是一個比較常用的一個實現,聲明了Stack<Activity>用於存放項目過程中未Destory的Activity。寫了幾個常用增刪查的操作,然後列印出一些APP的屬性。
那還可以在Application裡做什嗎?
初始化 如初始化 ImageLoader這一類的第三方控制項還有Sp,緩衝等操作
在onCreate方法中調用
//建立預設的ImageLoader配置參數 ImageLoaderConfiguration configuration = ImageLoaderConfiguration .createDefault(this); //Initialize ImageLoader with configuration. ImageLoader.getInstance().init(configuration);
編寫一些通用的方法 如多士 Dialog等
簡化多士
public void showMyToast(final Activity curAT, int textResId) { showMyToast(curAT, textResId, Toast.LENGTH_LONG); }
退出App
public void exit() { TRIeIDLog.logD(TAG, "finishAllActivities..."); finishAllActivities(); android.os.Process.killProcess(android.os.Process.myPid()); System.exit(0); }
諸如此類的方法都可以在 Application中進行編寫。
那麼我們再來看下我們的BaseActivity
public abstract class BaseActivity extends Activity { InputMethodManager _inputMethodManager; protected Resources res; protected BaseApplication baseApp; protected static final String TAG = BaseActivity.class.getName(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getLayout()); res = this.getApplicationContext().getResources(); baseApp = (BaseApplication) this.getApplication(); _inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); this.getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); findById(); setListener(); logic(); baseApp.addActivity(this); } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (getCurrentFocus() != null && getCurrentFocus().getWindowToken() != null) { _inputMethodManager.hideSoftInputFromWindow(getCurrentFocus() .getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } } return super.onTouchEvent(event); } @Override protected void onPause() { super.onPause(); } @Override protected void onResume() { super.onResume(); } @Override protected void onDestroy() { super.onDestroy(); baseApp.removeActivity(this); } //FindById protected abstract void findById(); //setListener protected abstract void setListener(); //Logic protected abstract void logic(); protected abstract int getLayout(); //是否支援最小SDK protected boolean isSupportedSDK(int sdkVerCode) { LogUtils.d(TAG, "isSupportedSDK - ConfigUtil.MIN_SDK_VER_CODE = \"" + ConfigUtil.MIN_SDK_VER_CODE + "\""); LogUtils.d(TAG, "isSupportedSDK - sdkVerCode = \"" + sdkVerCode + "\""); return sdkVerCode >= ConfigUtil.MIN_SDK_VER_CODE; } //網路錯誤種類 protected int getNetworkErrorTip(int code) { LogUtils.d(TAG, "getNetworkErrorTip - code = \"" + code + "\""); int textResId = R.string.error_network_time_out; switch (code) { case RespHandleListener.ErrCode.ERR_NETWORK_NOT_AVAILABLE: textResId = R.string.error_network_not_available; break; case RespHandleListener.ErrCode.ERR_SERVER_ERROR: textResId = R.string.error_network_server_busy; break; case RespHandleListener.ErrCode.ERR_TIME_OUT: case RespHandleListener.ErrCode.ERR_CLIENT_ERROR: case RespHandleListener.ErrCode.ERR_UNKNOWN_ERROR: break; default: break; } LogUtils.d(TAG, "getNetworkErrorTip - textResId = \"" + textResId + "\""); return textResId; }}
網路判斷的工具介面
RespHandleListener
public interface RespHandleListener { class ErrCode { public static final int ERR_SUCCEED = 0; public static final int ERR_NETWORK_NOT_AVAILABLE = -1; public static final int ERR_TIME_OUT = -2; public static final int ERR_SERVER_ERROR = -3; public static final int ERR_CLIENT_ERROR = -4; public static final int ERR_UNKNOWN_ERROR = -5; } void onError(int code); void onReqBegin(); void onReqEnd(String jsonResp);}
分析:
之前 BaseApplication中的一些方法在BaseActivity中進行了調用,BaseActivity又對我們的onCreate進行了簡單的封裝,把商務邏輯與控制項捕捉等操作進行了分離
(具體的使用,在之後會貼出)
那我們還可以在BaseActivity中做些什嗎?
多士也可以做在這裡,Dialog也一樣
protected void showErrorToast(int code) { baseApp.showMyToast(this, getNetworkErrorTip(code)); }
網路判斷的工具類getNetworkErrorTip()
螢幕資訊等也可以在預設這裡擷取,以及一些硬體情況諸如NFC BLE等(這部分會在下一篇博文寫)
接下來貼下Demo代碼
public class MainActivity extends BaseActivity implements View.OnClickListener{ Button button; @Override protected void findById() { button=(Button)findViewById(R.id.button); } @Override protected void setListener() { button.setOnClickListener(this); } @Override protected void logic() { LogUtils.d("-------->logic",add(1,3)); } @Override protected int getLayout() { return R.layout.activity_main; } @Override public void onClick(View v) { if (v.getId()==R.id.button){ Toast.makeText(MainActivity.this,"點擊了按鈕",Toast.LENGTH_SHORT).show(); } } private int add(int a, int b){ return a+b; }}
運行效果
這麼做,媽媽再也不擔心我的onCreate方法幾百行了,再也不擔心我少findById一個控制項了,當然還可以進一步的封裝 用泛型<T>來對控制項操作進一步簡化,這個會在後面的文章寫到。
用到的第三方庫:
一個很簡便的日誌庫
compile 'com.apkfuns.logutils:library:1.0.6'
源碼:http://yunpan.cn/cmNbQInJuKHXw 訪問密碼 4a23
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。