背景
此文純粹總結開發Android以來遇到的一些坑,一來為了防止再次掉坑,二來是希望后面的朋友能躲開這些坑。
包名重復問題
由于Google Palyer沒有在中國登陸,中國存在有非常多的Android應用商城,而且這些商城并沒有聯合起來對APP包名進行檢測,所以你APP中使用的包名很有可能會跟別人的APP重復。那么小明手機裝了別人的應用,就裝不上你的應用了。
建議:
1.包名定義要有一定的技術,盡量避免太容易重復的包名,如:com.digital.home。
2.要確定包名前,可以將應用發到一些測試網站去測試,比如testin,它會將的你APP安裝到20臺機,看能否全部正常安裝。
textSize單位問題
Android Studio提示所有textSize的單位都應該使用sp,因為這樣該text就能夠隨用戶在系統setting里設置的字體大小的改變而改變。那么如果你使用了sp作單位,那么建議你調整setting字體至最大或最小后,看UI是否還能正常顯示。我個人使用了不規范的dp作為單位。
小米手機圖標異常問題
在別的手機顯示沒有這問題,在小米手機顯示就有下圖的問題,解壓apk包也沒發現該圖標。其實這是小米手機的BUG,解決方法是將APP上傳至小米應用商城,它會要求你上傳一整套桌面圖標icon,據說現在小米應用商城已經去掉了這部分功能。
部分手機因權限問題無法安裝應用問題
一時記不起是什么手機,大概是中興還是樂視手機,只需要在AndroidManifest.xml里增加一個自定義權限就可以了。
<permission android:name="cus.permission.com.xxx.xxx"
android:protectionLevel="normal"/>
魅藍手機EditText的enabled屬性無用問題
在xml里面讓EditText不可編輯狀態,是設置android:enabled="false",但是發現在魅藍note2這樣設置后還是可以編輯,再加上下面這句就可以了。
mPhoneNumEt.setEnabled(false);
百度更新與360更新沖突問題
之前應用集成了百度更新與360更新,然后上傳至360后臺發布,但是審核不通過,解決方法只需要把AndroidManifest.xml里百度相關的xml屏蔽再打包即可。
集成騰訊X5 WebKit無法讀取SD卡html文件問題
將html文件放到/data/data/com.example.demo/files/ 里面,結果發現X5根本無法讀取,后來通過跟騰訊工作人員溝通,原來舊版本的X5只允許讀取/sdcard 和私有目錄下的/data/data/com.example.demo/files/public目錄,其他目錄的調用都被禁止了。
我手機上的X5版本是2258,而新的版本如3321已經不再限制了,所以要兼容低版本的X5內核,還是需要把文件放在public目錄下。更詳細的集成方案請閱讀《集成第三方組件--Android APP集成騰訊X5 WebKit》
AsyncTask
AsyncTask只能執行簡短任務,執行長時間耗時任務會阻塞其他使用AsyncTask的任務。在項目中慎用,我踩過關于它的坑是在輪播圖里使用了它,導致其他AsyncTask阻塞,不能正常使用。比如集成七魚客服SDK無法獲取相冊圖片,比如獲取短信驗證碼倒計時無法正常倒計時。詳細可參考:AsyncTask 使用和缺陷
集成個推SDK的坑
個推最近推出了2.9.0版本的SDK,集成后打包apk文件,發現Android 5.0以上的系統都無法安裝,顯示“應用未安裝”,只能使用之前的2.8.1.0的版本,這個問題在他們Demo也已經驗證過,各位要注意。
簽名問題
生成簽名文件xxx.jks,兩個StorePassword和KeyPassword都沒有錯,但是還是提示:Cannot recover key,后來刪掉xxx.jks ,重新生成,并設置StorePassword和KeyPassword為同一個密碼,然后就可以了。
奇葩所在:
沒來得及分析這是為什么,因為我現在用的其他簽名文件兩個密碼不一致也沒問題。后面我再次嘗試使用不一樣的密碼,發覺原理問題不存在了。
可能的原因:
1.是IDE的BUG,重啟IDE就能搞定;
WebView加載htm影響原生頁面工作
公司項目使用HyBrid方式開發,直到有個頁面需要使用動畫、設置View顯示隱藏、設置View的高度、刷新GridView數據,但是發現加載a.html后這些功能全部失效或異常了,而選擇加載b.html就沒問題,而且這個只發生在我的4.3手機上。
奇葩所在:
不知道確切原因,問題還沒解決。
可能原因:
1.htm某些功能影響了原生頁面?
2.加載這個頁面是否需要開啟某些功能?
WebView加載html頁面后,部分手機顯示頁面過大
兩臺手機加載同一個html頁面,一個正常顯示,另一個頁面顯示不全,可以左右滑動,這個問題已經解決,問題是另一臺手機調整了系統字體大小導致。解決方法是設置WebView顯示為normal字體大小,代碼如下:
webSetting.setTextSize(WebSettings.TextSize.NORMAL);
webSetting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
提示“應用未安裝”
手機連接usb線的時候可以安裝,但是下載apk安裝卻提示“應用未安裝”,今天也發現支付寶出現了這個問題。原因是我們打包的apk不完整或路徑有問題導致,我這里發現的問題是在使用Gradle打包.so文件打包方式不對,最后參考http://blog.csdn.net/wulianghuan/article/details/44567001。
ListView中的CheckBox
若在ListView的Item中有CheckBox,而這個時候在Adapter中我們又設置了各個Item中OnCheckedChangeListener
,那么在ListView滑動過程中,或者加載過程中會不斷調用這個方法,正確的寫法是:
holder.cbItem.setOnCheckedChangeListener(null); //設置為空
if (mList.get(i).is_select()) { //設置其狀態
holder.cbItem.setChecked(true);
} else {
holder.cbItem.setChecked(false);
}
//設置狀態變化監聽事件
holder.cbItem.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mItemContentClickListener.selectGoods(i, isChecked);
}
});
需要注意的setOnCheckedChangeListener方法
該方法不僅在我們點擊的時候會調用,而且在調用setChecked
的時候也會被調用,正如其名字的意思,但是我們在開發中經常會忽略掉setChecked
會調用該方法的事情,導致系統出現Bug。
mSelectAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
showLog("setOnCheckedChangeListener");
}
});
如果只是需要在點擊的時候回調,那還是設置setOnClickListener
監聽吧。
Adapter里數據引用改變導致數據不改變的問題
我們通過初始化Adapter設置mGoodList數據在ListView中顯示:
GoodsListAdapter goodsListAdapter=new GoodsListAdapter(this,mGoodsList);
mListView.setAdapter(goodsListAdapter);
當我們數據改變時,容易犯一下錯誤:
mGoodsList=mOtherList;
goodsListAdapter.notifyDataSetChanged();
正確的應該是:
mGoodsList.clear();
mGoodsList.addAll(mOtherList);
goodsListAdapter.notifyDataSetChanged();
原因是在我們new GoodsListAdapter(...)
已將mGoodsList的引用傳遞給Adapter,如果mGoodsList=mOtherList
這種方法給mGoodsList賦值是不成功的,賦給mGoodsList的是新的引用,但Adapter卻還保留原來的引用。
SQLite里存儲INTEGER數據
在創建表時,將某一字段類型設置為INTEGER,如果存儲00311104035001這樣的數據,SQLite真正存儲的值會變為311104035001。若要避免這種錯誤,可選擇VARCHAR類型。
APP升級要留一條后路
即強制升級,因為開發中總會遇到這種需求;
浮點數或雙精度計算時要考慮保留小數點后的位數
之前做計算時沒有考慮這個,導致有些計算的結果是個無線循環小數,如:128.6999999...,以下是個方法:
public String getResult(double num){
BigDecimal input = new BigDecimal(num);
double result = input.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
return String.valueOf(result);
}
ListView設置setOnItemClickListener點擊沒反應
問題一般是由于ListView中的ItemView里有Button、Checkbox、ImageView等控件,導致點擊ItemView時焦點其他控件攔截了,要解決此問題,只需要在控件上設置android:focusable="false"。
DatePickerDialog的顯示的問題
我們輸入的對話框初始日期是2017-4-2,但是顯示的對話框卻是2017-5-2,而選出的日期是4月,這明顯會誤導用戶。所以我們需要做些處理,在初始的月份-1,在回調的結果里+1,這就能達到我們想要的效果。
int yearParam=2017;
int monthParam=4;
int dayParam=2;
new DatePickerDialog(MainActivity.this, new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
String result = year + "-" + (monthOfYear+1) + "-" + dayOfMonth;
textView.setText(result);
}
}, yearParam, monthParam-1, dayParam).show();
待續......