崩潰bug日誌總結1

目錄介紹

  • 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.詳細崩潰日誌信息php

    # 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

    • 這個異常類的大意是:若是Java虛擬機找不到聲明爲本機的方法的適當本機語言定義,則引起。
    public class UnsatisfiedLinkError extends LinkageError {
        private static final long serialVersionUID = -4019343241616879428L;
    
        public UnsatisfiedLinkError() {
            super();
        }
    
        public UnsatisfiedLinkError(String s) {
            super(s);
        }
    }
  • C.項目中異常分析android

    • 根據實際項目可知,當準備播放視頻時,找不到libijkffmpeg.so這個庫,致使直接崩潰。
  • D.引起崩潰日誌的流程分析
  • F.解決辦法git

    • 報這個錯誤一般是so庫加載失敗,或者找不到準備執行的JNI方法:github

      • 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就會出錯。segmentfault

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.詳細崩潰日誌信息

    android.view.WindowManager$BadTokenException
        Unable to add window -- token android.os.BinderProxy@7f652b2 is not valid; is your activity running?
  • B.查看崩潰類信息

    • 查詢報錯日誌是從哪裏來的
    • image
  • 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
  • 而後找找報錯日誌從哪裏來的

    • ![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的構造函數以下所示:
    • image
    • image

關於其餘內容介紹

01.關於博客彙總連接

02.關於個人博客

相關文章
相關標籤/搜索