Android 開發技巧 開發常見問題歸納 需要注意的坑和解決方案
1. 在Activity還沒完全顯示時,彈出PopupWindow或者Dialog 崩Activity not running 錯誤
解決方案: 重寫onWindowFocusChanged方法
@Override
public void onWindowFocusChanged(boolean hasFocus) {
if (hasFocus) {
if (!mIsInitData) {
initData();
mIsInitData = true;
}
}
super.onWindowFocusChanged(hasFocus);
}
protected void initData() {
// 在此處編寫彈出Popup或者Dialog的方法
}2. 在library中使用switch語句處理id 時報錯
產生原因:library中生成的R文件中生成的id 沒有用final 修飾(不要問為什么,我也想知道)
解決方案:使用if else 替換switch
3. 不要在Application中緩存任何數據,NoPointException
產生原因:一般情況下不會出現異常,當按下Home 應用隱藏到后臺,長時間未使用,導致應用被回收,當再次啟動時,Application會重新創建,而Activity此時再向Application里取數據,異常發生
解決方案:將數據緩存到sp 或者數據庫或者sd卡。或者在使用Application緩存數據時,進行null判斷
4. AsyncTask只能執行一次
5. 提取一個BaseActivity,里面進行一些統一處理,能讓你的代碼更簡潔。繼承第三方框架的時候也很方便處理,特別是繼承友盟統計是,如果沒有Base,那你就哭(┬_┬)吧
public abstract class BaseActivity extends Activity implements OnClickListener {
private boolean mIsInitData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void setContentView(int layoutResID) {
super.setContentView(layoutResID);
initView();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
if (hasFocus) {
if (!mIsInitData) {
initData();
mIsInitData = true;
}
}
super.onWindowFocusChanged(hasFocus);
}
protected void initData() {
}
protected abstract void initView();
/**
* 獲取View
*
* @param id
* @return
*/
@SuppressWarnings("unchecked")
protected <T extends View> T mGetView(int id) {
return (T) findViewById(id);
}
/**
* 獲取Button的實例 并綁定點擊事件
*
* @param id
* @return
*/
protected Button mGetButtonSetOnClick(int id) {
Button btn = (Button) findViewById(id);
btn.setOnClickListener(this);
return btn;
}
/**
* 獲取ImageView的實例 并綁定點擊事件
*
* @param id
* @return
*/
protected ImageView mGetImageViewSetOnClick(int id) {
ImageView image = (ImageView) findViewById(id);
image.setOnClickListener(this);
return image;
}
/**
* 獲取View的實例 并綁定點擊事件
*
* @param id
* @return
*/
protected View mGetViewSetOnClick(int id) {
View view = (View) findViewById(id);
view.setOnClickListener(this);
return view;
}
/**
* 獲取TextView中的文本信息
*
* @param tv
* @return
*/
protected String mGetTextViewContent(TextView tv) {
return tv.getText().toString().trim();
}
/**
* 獲取EditText中的文本信息
*
* @param et
* @return
*/
protected String mGetEditTextContent(EditText et) {
return et.getText().toString().trim();
}
protected void showHintMsg(int sid) {
MToast.showToast(this, getResources().getString(sid));
}
protected void showHintMsg(String sMsg) {
MToast.showToast(this, sMsg);
}
}6. Toast定義為全局,避免一直不斷的吐吐吐吐。
public class MToast {
private static Toast mToast;
private static TextView tv_content;
public static void showToast(Context context, String msg) {
try {
if (mToast == null) {
mToast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
mToast.setGravity(Gravity.TOP, 0,
DensityUtil.dip2px(context, 3));
View view = View.inflate(context, R.layout.m_toast, null);
tv_content = (TextView) view.findViewById(R.id.tv_content);
mToast.setView(view);
tv_content.setText(msg);
} else {
tv_content.setText(msg);
}
mToast.show();
} catch (Exception e) {
// TODO: handle exception
}
}
}7. 標題欄樣式抽取,抽取思路大概有兩種,第一種:用<inlcude>標簽在xml布局時引入,第二種:自定義一個TitleView,千萬不要偷懶節省這個步驟。指不定那天產品就要讓你改個樣式,到時候你就哭吧。不僅僅是標題欄,字體大小,主題顏色,能抽取的都統一處理,產品的心和女人的新一樣,說變就變。
8. TextView.setText();中要顯示int類型的值,用String.valueOf()轉,不要直接124+“”,不知道為什么這樣的同學,基礎太差,去看看源碼就知道為什么了。
9. 退出應用方式,1.直接殺死進程 2.在BaseActivity中注冊一個廣播,發送廣播關閉 3.定義一個全局容器存儲Activity應用,退出時遍歷退出(不推薦)
10. 一個功能分幾個頁面處理時,使用Dialog 模擬Activity 避免了數據在Activity之間傳遞。
11. 手機重啟,知乎上看到滴,通過不斷的new 空Toast,導致系統奔潰而重啟,想想竟有一種無言以對的感覺,原來Toast還可以尼瑪這么玩
public void onClick(View v){
while(true){
Toast toast = new Toast(this);
toast.setView(new View(this));
toast.show();
}
}12. View類中的 setSelected(boolean)方法結合android:state_selected="" 用來實現圖片選中效果 自定義標題欄用起來很方便;
13. EditText 中有個 android:digits="" 屬性,用來自定義輸入的字符類型,比如輸入身份證只能是數字和x或者X 使用 android:digits="1234567890xX" 就輕松搞定了,不用再在代碼里面進行蛋疼的校驗了;
今天就補充到這