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