摘要:項(xiàng)目中異常分析引發(fā)崩潰日志的流程分析解決辦法常見的出現(xiàn)場(chǎng)景狀態(tài)異常非法線程操作。引發(fā)崩潰日志的流程分析解釋如下所示,釋放與此位圖關(guān)聯(lián)的本機(jī)對(duì)象,并清除對(duì)像素?cái)?shù)據(jù)的引用。
目錄介紹
1.1 java.lang.UnsatisfiedLinkError找不到so庫異常
1.2 java.lang.IllegalStateException非法狀態(tài)異常
1.3 android.content.res.Resources$NotFoundException
1.4 java.lang.IllegalArgumentException參數(shù)不匹配異常
1.5 IllegalStateException:Can"t compress a recycled bitmap
1.6 java.lang.NullPointerException空指針異常
1.7 android.view.WindowManager$BadTokenException異常
1.8 java.lang.ClassCastException類轉(zhuǎn)化異常
1.9 1.9 Toast運(yùn)行在子線程問題,handler問題
好消息博客筆記大匯總【16年3月到至今】,包括Java基礎(chǔ)及深入知識(shí)點(diǎn),Android技術(shù)博客,Python學(xué)習(xí)筆記等等,還包括平時(shí)開發(fā)中遇到的bug匯總,當(dāng)然也在工作之余收集了大量的面試題,長(zhǎng)期更新維護(hù)并且修正,持續(xù)完善……開源的文件是markdown格式的!同時(shí)也開源了生活博客,從12年起,積累共計(jì)47篇[近20萬字],轉(zhuǎn)載請(qǐng)注明出處,謝謝!
鏈接地址:https://github.com/yangchong2...
如果覺得好,可以star一下,謝謝!當(dāng)然也歡迎提出建議,萬事起于忽微,量變引起質(zhì)變!
1.1 java.lang.UnsatisfiedLinkError
A.詳細(xì)崩潰日志信息
# main(1) java.lang.UnsatisfiedLinkError dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.paidian.hwmc-1/base.apk", dex file "/data/app/com.paidian.hwmc-1/base.apk"],nativeLibraryDirectories=[/data/app/com.paidian.hwmc-1/lib/arm64, /data/app/com.paidian.hwmc-1/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]]] couldn"t find "libijkffmpeg.so"
B.查看崩潰類信息
這個(gè)異常類的大意是:如果Java虛擬機(jī)找不到聲明為本機(jī)的方法的適當(dāng)本機(jī)語言定義,則引發(fā)。
public class UnsatisfiedLinkError extends LinkageError { private static final long serialVersionUID = -4019343241616879428L; public UnsatisfiedLinkError() { super(); } public UnsatisfiedLinkError(String s) { super(s); } }
C.項(xiàng)目中異常分析
根據(jù)實(shí)際項(xiàng)目可知,當(dāng)準(zhǔn)備播放視頻時(shí),找不到libijkffmpeg.so這個(gè)庫,導(dǎo)致直接崩潰。
D.引發(fā)崩潰日志的流程分析
F.解決辦法
報(bào)這個(gè)錯(cuò)誤通常是so庫加載失敗,或者找不到準(zhǔn)備執(zhí)行的JNI方法:
1.建議檢查so在安裝的過程中是否丟失,沒有放入指定的目錄下;
2.調(diào)用loadLibrary時(shí)檢查是否調(diào)用了正確的so文件名,并對(duì)其進(jìn)行捕獲,進(jìn)行相應(yīng)的處理,防止程序發(fā)生崩潰;
3.檢查下so的架構(gòu)是否跟設(shè)備架構(gòu)一至(如在64-bit架構(gòu)下調(diào)用32-bit的so)。
代碼展示
ndk { //根據(jù)需要 自行選擇添加的對(duì)應(yīng)cpu類型的.so庫。 //abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86", "mips" abiFilters "armeabi-v7a" } dependencies { compile fileTree(dir: "libs", include: ["*.jar"]) //這兩個(gè)是必須要加的,其它的可供選擇 compile "tv.danmaku.ijk.media:ijkplayer-java:0.8.4" compile "tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.4" //其他庫文件 //compile "tv.danmaku.ijk.media:ijkplayer-armv5:0.8.8" //compile "tv.danmaku.ijk.media:ijkplayer-arm64:0.8.8" //compile "tv.danmaku.ijk.media:ijkplayer-x86:0.8.8" //compile "tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.8" }1.2 java.lang.IllegalStateException非法狀態(tài)異常
A.詳細(xì)崩潰日志信息
onSaveInstanceState方法是在該Activity即將被銷毀前調(diào)用,來保存Activity數(shù)據(jù)的,如果在保存玩狀態(tài)后
再給它添加Fragment就會(huì)出錯(cuò)。
IllegalStateException: Can not perform this action after onSaveInstanceState:
B.查看崩潰類信息
在非法或不適當(dāng)?shù)臅r(shí)間調(diào)用方法的信號(hào)。換句話說,Java環(huán)境或Java應(yīng)用程序沒有處于請(qǐng)求操作的適當(dāng)狀態(tài)。
public class IllegalStateException extends RuntimeException { public IllegalStateException() { super(); } public IllegalStateException(String s) { super(s); } public IllegalStateException(String message, Throwable cause) { super(message, cause); } public IllegalStateException(Throwable cause) { super(cause); } static final long serialVersionUID = -1848914673093119416L; }
C.項(xiàng)目中異常分析
分析
D.引發(fā)崩潰日志的流程分析
F.解決辦法
解決辦法就是把commit()方法替換成 commitAllowingStateLoss()
G.其他延申
錯(cuò)誤類型大致為以下幾種:
java.lang.IllegalStateException:Can"t change tag of fragment d{e183845 #0 d{e183845}}: was d{e183845} now d{e183845 #0 d{e183845}} java.lang.IllegalStateException:Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 37 path $.data
第一種:我在顯示fragment的代碼中使用了:fragment.show(getSupportFragmentManager, fragment.toString());而這里是因?yàn)閮纱蝨oString()結(jié)果不同,導(dǎo)致不同的tag指向的是同一個(gè)fragment。獲取fragment的tag的正確方法應(yīng)該是使用其提供的fragment.getTag()方法。
第二種:該異常是由于服務(wù)器錯(cuò)誤返回的JSON字符串和服務(wù)器正常下時(shí)返回的JSON字符串結(jié)構(gòu)不同,導(dǎo)致利用Gson解析的時(shí)候報(bào)了一個(gè)異常:本該去解析集合卻強(qiáng)制去解析對(duì)象所致.解決辦法:在使用Gson解析JSON時(shí)try cash一下,不報(bào)錯(cuò)按照正常邏輯繼續(xù)解析,報(bào)異常則處理為請(qǐng)求失敗邏輯即可.
1.3 android.content.res.Resources$NotFoundException
A.詳細(xì)崩潰日志信息
Android資源不是可繪制的(顏色或路徑)
Resource is not a Drawable (color or path): TypedValue{t=0x2/d=0x7f040151 a=2} android.view.LayoutInflater.createView(LayoutInflater.java:620)
B.查看崩潰類信息
當(dāng)找不到請(qǐng)求的資源時(shí),資源API將引發(fā)此異常。
public static class NotFoundException extends RuntimeException { public NotFoundException() { } public NotFoundException(String name) { super(name); } public NotFoundException(String name, Exception cause) { super(name, cause); } }
C.項(xiàng)目中異常分析
由于將圖片資源拷貝到了drawable-land-xhdpi目錄下,本來應(yīng)該拷貝到drawable-xhdpi目錄下。
D.引發(fā)崩潰日志的流程分析
F.解決辦法
1.引用的資源ID 是否能匹配到R.java文件中定義的資源;
2.是否因?yàn)榫彺娴仍驅(qū)е戮幾gAPK時(shí)未把資源文件打包進(jìn)去,可以把APK反編譯檢查下;
3.是否使用了一個(gè)錯(cuò)誤的類型來引用了某個(gè)資源或者配置資源時(shí)存在錯(cuò)誤;
4.是否將Int等整型變量作為了參數(shù)傳給了View.setText調(diào)用,這種情況下該整型變量將被認(rèn)為是一個(gè)資源ID號(hào)去資源列表中查找對(duì)應(yīng)的資源,導(dǎo)致找不到對(duì)應(yīng)資源錯(cuò)誤;解決方法是做類型轉(zhuǎn)換View.setText(String.valueOf(Int id))。
1.4 java.lang.IllegalArgumentException參數(shù)不匹配異常A.詳細(xì)崩潰日志信息
B.查看崩潰類信息
參數(shù)不匹配異常,通常由于傳遞了不正確的參數(shù)導(dǎo)致。
public class IllegalArgumentException extends RuntimeException { public IllegalArgumentException() { super(); } public IllegalArgumentException(String s) { super(s); } public IllegalArgumentException(String message, Throwable cause) { super(message, cause); } public IllegalArgumentException(Throwable cause) { super(cause); } private static final long serialVersionUID = -5365630128856068164L; }
C.項(xiàng)目中異常分析
D.引發(fā)崩潰日志的流程分析
F.解決辦法
G.常見的出現(xiàn)場(chǎng)景
Activity、Service狀態(tài)異常;
非法URL;
UI線程操作。
Fragment中嵌套了子Fragment,F(xiàn)ragment被銷毀,而內(nèi)部Fragment未被銷毀,所以導(dǎo)致再次加載時(shí)重復(fù),在onDestroyView() 中將內(nèi)部Fragment銷毀即可
在請(qǐng)求網(wǎng)絡(luò)的回調(diào)中使用了glide.into(view),view已經(jīng)被銷毀會(huì)導(dǎo)致該錯(cuò)誤
1.5 IllegalStateException:Can"t compress a recycled bitmap
A.詳細(xì)崩潰日志信息
無法壓縮回收位圖
Can"t compress a recycled bitmap com.paidian.hwmc.utils.i.a(FileUtils.java:75)
B.查看崩潰類信息
如果位圖已被回收,則希望拋出異常的方法將調(diào)用此值。知道了崩潰的具體位置,就該分析具體的原因呢!
public boolean compress(CompressFormat format, int quality, OutputStream stream) { checkRecycled("Can"t compress a recycled bitmap"); //省略代碼 return result; } //如果位圖已被回收,則希望拋出異常的方法將調(diào)用此值。 private void checkRecycled(String errorMessage) { if (mRecycled) { throw new IllegalStateException(errorMessage); } }
C.項(xiàng)目中異常分析
使用了已經(jīng)被釋放過內(nèi)存的對(duì)象。對(duì)于Bitmap:Bitmap bitmap=一個(gè)bitmap對(duì)象。使用過程中調(diào)用bitmap.recycle(),之后再使用bitmap就會(huì)報(bào)錯(cuò)。
D.引發(fā)崩潰日志的流程分析
bitmap.recycle()解釋如下所示,釋放與此位圖關(guān)聯(lián)的本機(jī)對(duì)象,并清除對(duì)像素?cái)?shù)據(jù)的引用。這將不會(huì)同步釋放像素?cái)?shù)據(jù);它只允許在沒有其他引用的情況下對(duì)其進(jìn)行垃圾收集。位圖被標(biāo)記為“死”,這意味著如果調(diào)用getPixels()或setPixels(),它將拋出異常,而不會(huì)繪制任何內(nèi)容。此操作不能反轉(zhuǎn),因此只有在確定沒有進(jìn)一步使用位圖的情況下才應(yīng)調(diào)用該操作。這是一個(gè)高級(jí)調(diào)用,通常不需要調(diào)用,因?yàn)楫?dāng)沒有對(duì)此位圖的引用時(shí),普通GC進(jìn)程將釋放此內(nèi)存。
Free the native object associated with this bitmap, and clear the reference to the pixel data
F.解決辦法
第一種:在使用bitmap前增加判斷,if (mBitmap.isRecycled()) return null;
第二種:
1.6 java.lang.NullPointerException空指針異常
A.詳細(xì)崩潰日志信息
Please call the AutoSizeConfig#init() first com.paidian.hwmc.base.BaseApplication.initAutoSizeConfig(BaseApplication.java:386)
B.查看崩潰類信息
空指針異常,也是十分常見的一個(gè)異常
public class NullPointerException extends RuntimeException { private static final long serialVersionUID = 5162710183389028792L; public NullPointerException() { super(); } public NullPointerException(String s) { super(s); } }
C.項(xiàng)目中異常分析
空指針發(fā)生場(chǎng)景較多,是指某一個(gè)對(duì)象報(bào)null,這個(gè)使用去使用它的話就i會(huì)報(bào)該異常。
D.引發(fā)崩潰日志的流程分析
F.解決辦法
空指針最為常見,也最容易規(guī)避,使用的時(shí)候一定要進(jìn)行null check,采取不信任原則:
1.方法形參要判空后才使用;
2.全局變量容易被系統(tǒng)回收或者更改,使用全局變量前建議判空;
3.第三方接口的調(diào)用,對(duì)返回值進(jìn)行判空。
4.請(qǐng)注意線程安全
1.7 android.view.WindowManager$BadTokenException異常,Toast報(bào)錯(cuò)Unable to add window
A.詳細(xì)崩潰日志信息
報(bào)錯(cuò)日志,是不是有點(diǎn)眼熟呀?更多可以看我的開源項(xiàng)目:https://github.com/yangchong211
android.view.WindowManager$BadTokenException Unable to add window -- token android.os.BinderProxy@7f652b2 is not valid; is your activity running?
B.查看崩潰類信息
查詢報(bào)錯(cuò)日志是從哪里來的
C.項(xiàng)目中異常分析
D.引發(fā)崩潰日志的流程分析
這個(gè)異常發(fā)生在Toast顯示的時(shí)候,原因是因?yàn)閠oken失效。通常情況下,一般是不會(huì)出現(xiàn)這種異常。但是由于在某些情況下, Android進(jìn)程某個(gè)UI線程的某個(gè)消息阻塞。導(dǎo)致 TN 的 show 方法 post 出來 0 (顯示) 消息位于該消息之后,遲遲沒有執(zhí)行。這時(shí)候,NotificationManager 的超時(shí)檢測(cè)結(jié)束,刪除了 WMS 服務(wù)中的 token 記錄。刪除 token 發(fā)生在 Android 進(jìn)程 show 方法之前。這就導(dǎo)致了上面的異常。
測(cè)試代碼。模擬一下異常的發(fā)生場(chǎng)景,其實(shí)很容易,只需要這樣做就可以出現(xiàn)上面這個(gè)問題
Toast.makeText(this,"瀟湘劍雨-yc",Toast.LENGTH_SHORT).show(); try { Thread.sleep(20000); } catch (InterruptedException e) { e.printStackTrace(); }
F.解決辦法
目前見過好幾種,思考一下那種比較好……
第一種,既然是報(bào)is your activity running,那可以不可以在吐司之前先判斷一下activity是否running呢?
第二種,拋出異常增加try-catch,代碼如下所示,最后仍然無法解決問題
按照源碼分析,異常是發(fā)生在下一個(gè)UI線程消息中,因此在上一個(gè)ui線程消息中加入try-catch是沒有意義的。而且用到吐司地方這么多,這樣做也不方便啦!
第三種,那就是自定義類似吐司Toast的view控件。個(gè)人建議除非要求非常高,不然不要這樣做。畢竟發(fā)生這種異常還是比較少見的
G.哪些情況會(huì)發(fā)生該問題?
UI 線程執(zhí)行了一條非常耗時(shí)的操作,比如加載圖片等等,就類似上面用 sleep 模擬情況
進(jìn)程退后臺(tái)或者息屏了,系統(tǒng)為了減少電量或者某種原因,分配給進(jìn)程的cpu時(shí)間減少,導(dǎo)致進(jìn)程內(nèi)的指令并不能被及時(shí)執(zhí)行,這樣一樣會(huì)導(dǎo)致進(jìn)程看起來”卡頓”的現(xiàn)象
當(dāng)TN拋出消息的時(shí)候,前面有大量的 UI 線程消息等待執(zhí)行,而每個(gè) UI 線程消息雖然并不卡頓,但是總和如果超過了 NotificationManager 的超時(shí)時(shí)間,還是會(huì)出現(xiàn)問題
1.8 java.lang.ClassCastException類轉(zhuǎn)化異常
A.詳細(xì)崩潰日志信息
android.widget.FrameLayout cannot be cast to android.widget.RelativeLayout com.paidian.hwmc.goods.activity.GoodsDetailsActivity.initView(GoodsDetailsActivity.java:712)
B.查看崩潰類信息
拋出以指示代碼試圖將對(duì)象強(qiáng)制轉(zhuǎn)換為它不是實(shí)例的子類。
public class ClassCastException extends RuntimeException { private static final long serialVersionUID = -9223365651070458532L; public ClassCastException() { super(); } public ClassCastException(String s) { super(s); } }
C.項(xiàng)目中異常分析
該異常表示類型轉(zhuǎn)換異常,通常是因?yàn)橐粋€(gè)類對(duì)象轉(zhuǎn)換為其他不兼容類對(duì)象拋出的異常,檢查你要轉(zhuǎn)換的類對(duì)象類型。
D.引發(fā)崩潰日志的流程分析
F.解決辦法
一般在強(qiáng)制類型轉(zhuǎn)換時(shí)出現(xiàn),例如如果A向B轉(zhuǎn)換,而A不是B的父類時(shí),將產(chǎn)生java.lang.ClassCastException異常。一般建議做這時(shí)要使用instanceof做一下類型判斷,再做轉(zhuǎn)換。
該案例中,需要把FrameLayout更改成RelativeLayout就可以呢
1.9 Toast運(yùn)行在子線程問題,handler問題
A.詳細(xì)崩潰日志信息
先來看看問題代碼,會(huì)出現(xiàn)什么問題呢?
new Thread(new Runnable() { @Override public void run() { ToastUtils.showRoundRectToast("瀟湘劍雨-楊充"); } }).start();
報(bào)錯(cuò)日志如下所示:
然后找找報(bào)錯(cuò)日志從哪里來的
![image]()
子線程中吐司的正確做法,代碼如下所示
new Thread(new Runnable() { @Override public void run() { Looper.prepare(); ToastUtils.showRoundRectToast("瀟湘劍雨-楊充"); Looper.loop(); } }).start();
得出的結(jié)論
Toast也可以在子線程執(zhí)行,不過需要手動(dòng)提供Looper環(huán)境的。
Toast在調(diào)用show方法顯示的時(shí)候,內(nèi)部實(shí)現(xiàn)是通過Handler執(zhí)行的,因此自然是不阻塞Binder線程,另外,如果addView的線程不是Loop線程,執(zhí)行完就結(jié)束了,當(dāng)然就沒機(jī)會(huì)執(zhí)行后續(xù)的請(qǐng)求,這個(gè)是由Hanlder的構(gòu)造函數(shù)保證的。可以看看handler的構(gòu)造函數(shù),如果Looper==null就會(huì)報(bào)錯(cuò),而Toast對(duì)象在實(shí)例化的時(shí)候,也會(huì)為自己實(shí)例化一個(gè)Hanlder,這就是為什么說“一定要在主線程”,其實(shí)準(zhǔn)確的說應(yīng)該是 “一定要在Looper非空的線程”。
Handler的構(gòu)造函數(shù)如下所示:
關(guān)于其他內(nèi)容介紹 01.關(guān)于博客匯總鏈接1.技術(shù)博客匯總
2.開源項(xiàng)目匯總
3.生活博客匯總
4.喜馬拉雅音頻匯總
5.其他匯總
02.關(guān)于我的博客我的個(gè)人站點(diǎn):www.yczbj.org,www.ycbjie.cn
github:https://github.com/yangchong211
知乎:https://www.zhihu.com/people/...
簡(jiǎn)書:http://www.jianshu.com/u/b7b2...
csdn:http://my.csdn.net/m0_37700275
喜馬拉雅聽書:http://www.ximalaya.com/zhubo...
開源中國:https://my.oschina.net/zbj161...
泡在網(wǎng)上的日子:http://www.jcodecraeer.com/me...
郵箱:yangchong211@163.com
阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV
segmentfault頭條:https://segmentfault.com/u/xi...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/71828.html
摘要:詳細(xì)崩潰日志信息查看崩潰類信息當(dāng)調(diào)用或其變體之一失敗時(shí),會(huì)引發(fā)此異常,因?yàn)闊o法找到執(zhí)行給定意圖的活動(dòng)。引發(fā)崩潰日志的流程分析問題所在是方法。 目錄介紹 1.1 OnErrorNotImplementedException【 Cant create handler inside thread that has not called Looper.prepare()】 1.2 adb.e...
摘要:出現(xiàn)錯(cuò)誤引發(fā)崩潰日志的流程分析這個(gè)錯(cuò)誤是應(yīng)用的方法總數(shù)限制造成的。 目錄介紹 1.1 java.lang.ClassNotFoundException類找不到異常 1.2 java.util.concurrent.TimeoutException連接超時(shí)崩潰 1.3 java.lang.NumberFormatException格式轉(zhuǎn)化錯(cuò)誤 1.4 java.lang.Illegal...
摘要:換句話說,環(huán)境或應(yīng)用程序沒有處于請(qǐng)求操作的適當(dāng)狀態(tài)。項(xiàng)目中異常分析引發(fā)崩潰日志的流程分析解決辦法常見的出現(xiàn)場(chǎng)景狀態(tài)異常非法線程操作。導(dǎo)致的方法出來顯示消息位于該消息之后,遲遲沒有執(zhí)行。這時(shí)候,的超時(shí)檢測(cè)結(jié)束,刪除了服務(wù)中的記錄。 目錄介紹 1.1 java.lang.UnsatisfiedLinkError找不到so庫異常 1.2 java.lang.IllegalStateExce...
閱讀 2956·2021-11-22 14:45
閱讀 3117·2021-09-10 11:26
閱讀 3491·2021-09-07 10:18
閱讀 2362·2019-08-30 14:08
閱讀 777·2019-08-29 12:22
閱讀 1526·2019-08-26 13:48
閱讀 2801·2019-08-26 10:24
閱讀 1299·2019-08-23 18:35