Android開(kāi)發(fā)過(guò)程中遇到各種異常是不可避免的洪碳。透過(guò)詳細(xì)的異常記錄苇羡,我們不但能理解程序崩潰的原因感局,還能根據(jù)異常類型采取針對(duì)性的解決措施扫茅。以下為一些常見(jiàn)的Android異常和它們的特征:
一、Java異常
-
空指針 (NullPointException)
- 解決方案:檢查對(duì)象是否為null逗嫡,確保在調(diào)用方法或?qū)傩郧耙呀?jīng)初始化青自。
-
角標(biāo)越界 (IndexOutOfBoundsException, StringIndexOutOfBoundsException, ArrayIndexOutOfBoundsException)
- 解決方案:檢查數(shù)組和字符串的索引是否越界,確保索引在有效范圍內(nèi)驱证。
-
調(diào)用一個(gè)空對(duì)象的方法 (Attempt to invoke virtual method on a null object reference)
- 解決方案:檢查對(duì)象是否為null延窜,確保在調(diào)用方法前已經(jīng)初始化。
-
類型轉(zhuǎn)換異常 (ClassCastException)
- 解決方案:檢查對(duì)象類型是否正確抹锄,確保在進(jìn)行類型轉(zhuǎn)換時(shí)逆瑞,對(duì)象實(shí)例與目標(biāo)類型一致。
-
數(shù)字轉(zhuǎn)換錯(cuò)誤 (NumberFormatException)
- 解決方案:檢查字符串是否可以轉(zhuǎn)換為指定的數(shù)字類型伙单,例如整數(shù)获高、浮點(diǎn)數(shù)等。
-
聲明數(shù)組時(shí)長(zhǎng)度為-1 (NegativeArraySizeException)
- 解決方案:確保數(shù)組的長(zhǎng)度為非負(fù)整數(shù)吻育。
-
遍歷集合同時(shí)刪除其中元素 (ConcurrentModificationException)
- 解決方案:使用迭代器的remove方法刪除元素念秧,避免在遍歷過(guò)程中直接修改集合。
-
當(dāng)除數(shù)為0 (java.lang.ArithmeticException: divide by zero)
- 解決方案:檢查除數(shù)是否為0布疼,并進(jìn)行相應(yīng)的異常處理摊趾。
-
類找不到 (ClassNotFoundException, NoClassDefFoundError)
- 解決方案:檢查類路徑是否正確,確保所需類文件已添加到項(xiàng)目中缎除。
二严就、Activity異常
-
找不到Activity (android.content.ActivityNotFoundException)
- 解決方案:檢查Intent的action总寻、data等屬性是否正確設(shè)置器罐,確保有Activity能夠處理該Intent。
-
不能實(shí)例化Activity (java.lang.RuntimeException)
- 解決方案:檢查Activity的構(gòu)造方法是否可見(jiàn)渐行,確保Activity能夠被系統(tǒng)實(shí)例化轰坊。
-
找不到Service (java.lang.RuntimeException)
- 解決方案:檢查Service的聲明是否正確,確保Service能夠被系統(tǒng)實(shí)例化祟印。
-
不能啟動(dòng)BroadcastReceiver (Unable to start receiver)
- 解決方案:檢查BroadcastReceiver的聲明和注冊(cè)是否正確肴沫,確保能夠接收相應(yīng)的Intent。
-
startActkivity沒(méi)有flag (android.util.AndroidRuntimeException)
- 解決方案:在調(diào)用startActivity時(shí)蕴忆,添加FLAG_ACTIVITY_NEW_TASK標(biāo)志颤芬。
-
startActivityForResult錯(cuò)誤 (Failure delivering result ResultInfo)
- 解決方案:檢查startActivityForResult的調(diào)用和onActivityResult的實(shí)現(xiàn)是否正確。
-
fragment未attach調(diào)用context (Fragment not attached to Activity)
- 解決方案:確保在調(diào)用Fragment相關(guān)方法時(shí),F(xiàn)ragment已經(jīng)與Activity建立關(guān)聯(lián)站蝠。
三汰具、序列化異常
-
實(shí)體對(duì)象不支持序列化 (Parcelable encountered IOException)
- 解決方案:檢查實(shí)體類是否實(shí)現(xiàn)Parcelable接口,確保序列化過(guò)程正確菱魔。
-
序列化時(shí)未指定ClassLoader (BadParcelableException)
- 解決方案:在反序列化時(shí)指定正確的ClassLoader留荔。
-
反序列化時(shí)發(fā)現(xiàn)類找不到 (Parcelable encountered ClassNotFoundException)
- 解決方案:檢查ProGuard配置,確保所需類未被混淆澜倦。
-
反序列化時(shí)發(fā)現(xiàn)類找不到(傳入畸形數(shù)據(jù)) (Parcelable encountered ClassNotFoundException)
- 解決方案:檢查傳入的數(shù)據(jù)是否正確聚蝶,確保類名稱與實(shí)際類一致。
-
反序列化時(shí)出錯(cuò)藻治,數(shù)據(jù)太大 (Could not read input channel file descriptors from parcel)
- 解決方案:檢查數(shù)據(jù)大小碘勉,確保不超過(guò)Parcel的最大容量。
四桩卵、窗體相關(guān)異常
-
窗口句柄泄露,dismiss前activity被銷毀:
android.view.WindowLeaked: Activity xxx has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{xxxx}
- 解決方案:確保在Activity銷毀前恰聘,所有Dialog等都要被dismiss,避免泄露吸占。
-
窗體在不適當(dāng)?shù)臅r(shí)候獲取了焦點(diǎn)晴叨,顯示前獲取了焦點(diǎn):
java.lang.NullPointerException: android.widget.PopupWindow$PopupViewContainer.dispatchKeyEvent
- 解決方案:在彈出窗口前檢查Activity的狀態(tài),確保窗體能在正確的時(shí)機(jī)顯示矾屯。
-
token null is not for an application兼蕊,AlertDialog的context是application:
android.view.WindowManager$BadTokenException: Unable to add window--token null is not for an application
- 解決方案:確保創(chuàng)建AlertDialog等窗體時(shí),傳入的Context來(lái)自一個(gè)Activity而非Application件蚕。
五孙技、資源相關(guān)的異常
-
Resources NotFoundException setText給的int值錯(cuò)誤 :
android.content.res.Resources$NotFoundException: String resource ID #0x1
-
解決方案:確保
setText()
傳入的是正確的字符串或資源ID。
-
解決方案:確保
-
StackOverflowError排作,棧太多溢出:
StackOverflowError
- 解決方案:檢查遞歸調(diào)用或過(guò)深的方法調(diào)用棧牵啦,優(yōu)化代碼結(jié)構(gòu),避免過(guò)深的嵌套妄痪。
-
UnsatisfiedLinkError哈雏,so文件沒(méi)有加載到:
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/appname-1.apk"]...
-
解決方案:檢查
.so
文件是否在正確的目錄(jniLibs
)下,并確保有針對(duì)不同架構(gòu)的版本衫生。
-
解決方案:檢查
-
InflateException之FileNotFoundException:
Caused by: android.view.InflateException: Binary XML file line #18: Error inflating class <unknown>
- 解決方案:確保布局XML文件中沒(méi)有錯(cuò)誤裳瘪,所有類名和資源引用正確無(wú)誤。
-
InflateException之缺少構(gòu)造器:
android.view.InflateException: Binary XML file line #: Error inflating class com.example.activity1.TestButton
- 解決方案:自定義View需要實(shí)現(xiàn)至少一個(gè)接受Context參數(shù)的構(gòu)造器罪针。
-
InflateException之style與android:textStyle的區(qū)別:
android.view.InflateException: Binary XML file line #14: Error inflating class
-
解決方案:檢查
style
屬性引用的樣式是否存在彭羹,并用正確的屬性。
-
解決方案:檢查
-
TransactionTooLargeException泪酱,Binder傳遞的數(shù)據(jù)大于1M:
android.view.InflateException: Binary XML file line #14: Error inflating class
- 解決方案:減少Intent或者IPC傳遞的數(shù)據(jù)大小派殷,分批傳輸大數(shù)據(jù)还最。
六、系統(tǒng)碎片化相關(guān)的異常
-
NoSuchMethodError 方法在舊版本沒(méi)有或被廢棄:
java.lang.NoSuchMethodError
- 解決方案:兼容不同版本毡惜,條件判斷系統(tǒng)版本憋活,反射等方式避免調(diào)用不存在方法。
-
SecurityException之一:Intent中圖片太大:
java.lang.SecurityException: Unable to find app for caller android.app.ApplicationThreadProxy when stopping service Intent { cmp=... }
- 解決方案:減少Intent中傳遞圖片的大小虱黄,避免超過(guò)系統(tǒng)限制悦即。
-
SecurityException之三:No permission to modify thread:
java.lang.SecurityException: No permission to modify given thread at
- 解決方案:確保應(yīng)用擁有必要的權(quán)限來(lái)修改線程。
七橱乱、SQLite相關(guān)的異常
-
No transaction is active:
android.database.sqlite.SQLiteException: cannot commit–no transaction is active
- 解決方案:在數(shù)據(jù)庫(kù)操作中正確開(kāi)啟辜梳、提交或回滾事務(wù)。
-
忘記關(guān)閉Cursor:
android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed.
- 解決方案:在數(shù)據(jù)操作完后泳叠,確保關(guān)閉Cursor來(lái)釋放資源作瞄。
-
數(shù)據(jù)庫(kù)被鎖定:
android.database.sqlite.SQLiteDatabaseLockedException: database is locked
- 解決方案:使用同步或其他機(jī)制以防止數(shù)據(jù)庫(kù)同時(shí)被多個(gè)實(shí)例或進(jìn)程鎖定。
-
試圖再打開(kāi)已經(jīng)關(guān)閉的對(duì)象:
java.lang.IllegalStateException: attempt to re-open an already-closed object
- 解決方案:確保不去操作已經(jīng)關(guān)閉的數(shù)據(jù)庫(kù)或游標(biāo)對(duì)象危纫。
-
文件加密了或無(wú)數(shù)據(jù)庫(kù):
android.database.sqlite.SQLiteDatabaseCorruptException: file is encrypted or is not a database
- 解決方案:驗(yàn)證數(shù)據(jù)庫(kù)文件的完整性宗挥,并確保正確地加密和解密。
-
WebView中SQLite緩存導(dǎo)致的崩潰:
SQLiteDiskIOException: disk I/O error
- 解決方案:優(yōu)化SQLite操作种蝶,避免磁盤I/O錯(cuò)誤契耿。
-
android_metadata表不存在:
android.database.sqlite.SQLiteException: no such table: android_metadata
- 解決方案:確認(rèn)創(chuàng)建數(shù)據(jù)庫(kù)時(shí)是否已自動(dòng)包含該表,該表通常由Android系統(tǒng)自動(dòng)創(chuàng)建螃征。
八搪桂、其他異常
-
內(nèi)存溢出(OutOfMemoryException)
-
解決方案:優(yōu)化內(nèi)存管理,特別是圖片加載管理盯滚,使用像
Glide
或Picasso
等庫(kù)來(lái)幫助處理圖片踢械。
-
解決方案:優(yōu)化內(nèi)存管理,特別是圖片加載管理盯滚,使用像
-
虛擬機(jī)發(fā)現(xiàn)了某種不一致或不兼容的字節(jié)碼(VerifyError)
- 解決方案:確保編譯的環(huán)境與運(yùn)行環(huán)境一致,避免兼容性問(wèn)題魄藕。
-
finalize方法執(zhí)行超時(shí)
- 解決方案:避免在finalize方法內(nèi)執(zhí)行長(zhǎng)時(shí)間的操作内列。
-
JSON解析異常(JSONException)
- 解決方案:正確處理JSON數(shù)據(jù)格式,異常捕捉并處理背率。
-
JSONArray初始化空指針異常(NullPointerException)
- 解決方案:確保傳遞的JSON字符串格式正確话瞧,且非空。
以上列出的Android開(kāi)發(fā)中的異常與解決方案退渗,旨在幫助開(kāi)發(fā)者更高效地診斷并解決程序中的問(wèn)題移稳,從而提升應(yīng)用的穩(wěn)定性和用戶體驗(yàn)蕴纳。