最近博客寫的少了,以后還得經常更新才行。
------------------------------------------------------------
1.特定業務需求下try cath 異常需要catch可能的RuntimeException,否則可能出現catch不全導致的意外問題(如app崩潰)。
之所以將此問題放在第一位,是因為前陣子中項目中出現了此類情況,並且這種情況很容易不注意或遺忘,但其錯誤卻是致命的。
在Java/Android開發中,當調用一個函數時,此函數拋出一個A類型的異常,很自然的,在調用的地方我們會try.. catch此異常,並且絕大多數情況下,捕獲異常是由Eclispe自動提示並生成的,函數拋出A異常,則調用的地方catch A,實際上,我們最好必須在catch A后再加上一個catch(Exception ex){}。原因在於防范於某些不可確定發生的問題而導致可能拋出的其他異常類型(實際上是特定的RuntimeException異常/unchecked異常,編碼時本不推薦catch RuntimeException,但在移動開發特定業務場景中加上對其捕獲可以有效防止App意外崩潰)。
上次就遇到了在接收推送消息時,new JSONObject()時,很自然的只catch了JSONException,而沒有進一步的catch Exception,而實際上由於服務端傳過來的數據格式錯誤后導致其拋出了java.lang.NumberFormatException,一步步跟蹤代碼后發現在源代碼中確實存在可能拋出此異常的情形,而沒被catch到,直接將導致app崩潰。此后謹記!
2.因so文件目錄引起的UnsatisfiedLinkError: … :findLibrary returned null問題。
Android開發中,不可避免的可能會引用到外部so文件,設置一個項目中可能需要引用多個不同的外部so文件。因為不同的引入庫中so文件的目錄可能不同,導致打包后生成的項目lib目錄中的目錄結構是不同的外部so文件目錄的合集。可能會出現armabi/armeabi-v7a/x86/mips等,一般情況下,armabi應該是有的,當此三個目錄下的文件可能不同時,在某些特定機型下很可能會出現如上錯誤。原因在於不同的機型CPU結構不同導致搜尋不同的目錄下面的包,而由於外部庫不同的so文件目錄可能armabi下還有a、b so文件,而x86下可能只含有a,此時解決方案如下:
直接刪除其他目錄(如armabi-v7a/mips/x86等),只保持armabi目錄即可,當不存在x86目錄時,相應機型也自然會取armabi目錄下搜尋相應so文件。
3.Can't create handler inside thread that has not called Looper.prepare。
這個問題其實也比較經典了,原因在於,Android中的非UI線程不能進行修改UI操作(當然,嚴格意義上來說SurfaceView和TextureView除外),一般常見於在子線程中執行了如 Toast.makeText 等操作。一般借助於子線程和主線程消息通信機制來解決。
常見解決方法如:
1).Handler - Message方式;
2).Handler - postDelay方式;
3).activity.runOnUiThread(runnable)方式等。
4.RadioGroup中的RadioButton check()方法調用引發的onCheckedChanged()多次回調問題。
RadioGroup-RadioButton非常適合於多個選項中只選擇一個的情形,對其默認樣式進行改變可以方便的用於導航菜單的選項卡等需求中。setOnCheckedChangeListener()為其內部的單選按鈕check狀態的改變提供了方便實用的回調。編碼中,如果直接寫成radioGroup.check(xxx),其中參數為RadioButton的id,經常會發現onCheckedChanged()回到被執行了多次。通過查看源碼發現,當執行check()方法時,RadioGroup對單選前后不同的狀態都進行了回調。實際邏輯中,一般的都是希望只回調當前選中的單選按鈕即可。
可以通過如下方式解決:radioButton.setChecked(true);其中,radioButton為當前選中的radioGroup。
5.Notification傳參覆蓋問題
在App中,當顯示多個Notification時,notification id作為當前App內Notification標識,具有不同的Notification id表示通知欄中可以同時顯示此應用中多個不同的Notification。當用戶點擊各個Notification時,通過此Notification設置的pendingIntent響應用戶的點擊操作,在設置pendingIntent時,尤其需要注意其中的參數傳參問題。
當有多個通知時,如果后面的通知點擊后獲取的參數值都是第一個通知的參數值,則是沒有正確設置pendingIntent的flags參數。一般應該設置成PendingIntent.FLAG_UPDATE_CURRENT, 設置此參數后,則會形成相反的情形,前面的通知獲取的參數值都變成了最后一個通知傳遞的參數值,此時則是因為沒有正確設置requestCode參數。將requestCode參數設置成Notification id相同的值即可。
6.從AndroidManifest.xml中獲取channel出現錯誤提示:Key xx expected String but value was a java.lang.Integer. The default value <null> was reurned。
對於AndroidManifest.xml配置channel名稱時,當直接使用數字字符串時,會出現如上所示,獲取到的channel值為null。
修正如下:
1 public String getChannel() { 2 String channel = null; 3 try { 4 ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA); 5 channel = ai.metaData.getString("UMENG_CHANNEL"); 6 if (channel == null) { 7 channel = String.valueOf(ai.metaData.getInt("UMENG_CHANNEL")); 8 } 9 } catch (NameNotFoundException e) { 10 e.printStackTrace(); 11 } 12
13 return channel; 14 }
或者說,並不建議使用數字字符串直接作為渠道名稱。