崩潰bug日志總結(jié)2

目錄介紹

  • 1.1 java.lang.ClassNotFoundException類找不到異常
  • 1.2 java.util.concurrent.TimeoutException連接超時崩潰
  • 1.3 java.lang.NumberFormatException格式轉(zhuǎn)化錯誤
  • 1.4 java.lang.IllegalStateException: Fragment not attached to Activity
  • 1.5 ArrayIndexOutOfBoundsException 角標(biāo)越界異常
  • 1.6 IllegalAccessException 方法中構(gòu)造方法權(quán)限異常
  • 1.7 android.view.WindowManager$BadTokenException,dialog彈窗異常
  • 1.8 java.lang.NoClassDefFoundError 找不到類異常
  • 1.9 Android出現(xiàn):Your project path contains non-ASCII characters.

好消息

  • 博客筆記大匯總【16年3月到至今】,包括Java基礎(chǔ)及深入知識點,Android技術(shù)博客,Python學(xué)習(xí)筆記等等,還包括平時開發(fā)中遇到的bug匯總,當(dāng)然也在工作之余收集了大量的面試題,長期更新維護并且修正,持續(xù)完善……開源的文件是markdown格式的!同時也開源了生活博客,從12年起,積累共計47篇[近20萬字],轉(zhuǎn)載請注明出處,謝謝!
  • 鏈接地址:https://github.com/yangchong211/YCBlogs
  • 如果覺得好,可以star一下,謝謝!當(dāng)然也歡迎提出建議,萬事起于忽微,量變引起質(zhì)變!

1.1 java.lang.ClassNotFoundException類找不到異常

  • A.詳細(xì)崩潰日志信息
    Didn't find class "om.scwang.smartrefresh.layout.SmartRefreshLayout" on path: DexPathList[[zip file "/data/app/com.paidian.hwmc-EsIbVq6e0mFwE0-rPanqdg==/base.apk", zip file "/data/app/com.paidian.hwmc-EsIbVq6e0mFwE0-rPanqdg==/split_lib_dependencies_apk.apk", zip file "/data/app/com.paidian.hwmc-EsIbVq6e0mFwE0-rPanqdg==/split_lib_slice_0_apk.apk", zip file "/data/app/com.paidian.hwmc-EsIbVq6e0mFwE0-rPanqdg==/split_lib_slice_1_apk.apk", zip file "/data/app/com.paidian.hwmc-EsIbVq6e0mFwE0-rPanqdg==/split_lib_s
    com.paidian.hwmc.goods.activity.GoodsDetailsActivity.onCreate(GoodsDetailsActivity.java:209)
    
  • B.查看崩潰類信息
    • 當(dāng)應(yīng)用程序嘗試使用字符串名稱加載類時引發(fā):但無法找到具有指定名稱的類的定義。從1.4版開始,已對此異常進行了修改,以符合通用的異常鏈接機制。在構(gòu)建時提供并通過{@link#getException()}方法訪問的“在加載類時引發(fā)的可選異常”現(xiàn)在稱為<i>原因</i>,并且可以通過{@link Throwable#getCace()}方法以及前面提到的“遺留方法”進行訪問。
    public class ClassNotFoundException extends ReflectiveOperationException {
        private static final long serialVersionUID = 9176873029745254542L;
        private Throwable ex;
        public ClassNotFoundException() {
            super((Throwable)null);  // Disallow initCause
        }
        public ClassNotFoundException(String s) {
            super(s, null);  //  Disallow initCause
        }
        public ClassNotFoundException(String s, Throwable ex) {
            super(s, null);  //  Disallow initCause
            this.ex = ex;
        }
        public Throwable getException() {
            return ex;
        }
        public Throwable getCause() {
            return ex;
        }
    }
    
  • C.項目中異常分析
    • 該異常表示在路徑下,找不到指定類,通常是因為構(gòu)建路徑問題導(dǎo)致的。
  • D.引發(fā)崩潰日志的流程分析
  • F.解決辦法
    • 類名是以字符串形式標(biāo)識的,可信度比較低,在調(diào)用Class.forName(""),Class.findSystemClass(""),Class.loadClass("")等方法時,找不到類名時將會報錯。如果找不到的Class是系統(tǒng)Class,那么可能是系統(tǒng)版本兼容,廠家Rom兼容的問題,找到對應(yīng)的設(shè)備嘗試重現(xiàn),解決方法可以考慮更換Api,或用自己實現(xiàn)的Class替代。
    • 如果找不到的Class是應(yīng)用自由Class(含第三方SDK的Class),可以通過反編譯工具查看對應(yīng)apk中是否真的缺少該Class,再進行定位,這種往往發(fā)生在:
      • 1.要找的Class被混淆了,存在但名字變了;
      • 2.要找的Class未被打入Dex,確實不存在,可能是因為自己的疏忽,或編譯環(huán)境的沖突;
      • 3.要找的Class確實存在,但你的Classlorder找不到這個Class,往往因為這個Classloder是你自實現(xiàn)的(插件化應(yīng)用中常見)。
  • G.其他延申

1.2 java.util.concurrent.TimeoutException連接超時崩潰

  • A.詳細(xì)崩潰日志信息
    java.util.concurrent.TimeoutException: android.view.ThreadedRenderer.finalize() timed out after 10 seconds
    at android.view.ThreadedRenderer.nDeleteProxy(Native Method)
    at android.view.ThreadedRenderer.finalize(ThreadedRenderer.java:423) 
    
  • B.查看崩潰類信息
    • 當(dāng)阻塞操作超時引發(fā)的異常。指定超時的阻塞操作需要一種方法來指示已發(fā)生超時。對于許多此類操作,可以返回指示超時的值;如果不可能或不需要,則應(yīng)聲明并拋出{@code TimeoutException}。
    public class TimeoutException extends Exception {
        private static final long serialVersionUID = 1900926677490660714L;
        public TimeoutException() {}
        public TimeoutException(String message) {
            super(message);
        }
    }
    
  • C.項目中異常分析
  • D.引發(fā)崩潰日志的流程分析
  • F.解決辦法
    • 一般是系統(tǒng)在gc時,調(diào)用對象的finalize超時導(dǎo)致,解決辦法:
    • 1.檢查分析finalize的實現(xiàn)為什么耗時較高,修復(fù)它;
    • 2.檢查日志查看GC是否過于頻繁,導(dǎo)致超時,減少內(nèi)容開銷,防止內(nèi)存泄露。
  • G.其他延申

1.3 java.lang.NumberFormatException格式轉(zhuǎn)化錯誤

  • A.詳細(xì)崩潰日志信息
    Exception in thread "main" java.lang.NumberFormatException: For input string: "100 "
        at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
        at java.lang.Integer.parseInt(Integer.java:458)
        at java.lang.Integer.parseInt(Integer.java:499)
    
  • B.查看崩潰類信息
    • 引發(fā),以指示應(yīng)用程序試圖將字符串轉(zhuǎn)換為數(shù)字類型之一,但該字符串沒有適當(dāng)?shù)母袷健?/li>
    public class NumberFormatException extends IllegalArgumentException {
        static final long serialVersionUID = -2848938806368998894L;
    
        public NumberFormatException () {
            super();
        }
    
        public NumberFormatException (String s) {
            super (s);
        }
    
        static NumberFormatException forInputString(String s) {
            return new NumberFormatException("For input string: \"" + s + "\"");
        }
    }
    
  • C.項目中異常分析
    • 錯誤關(guān)鍵字 java.lang.NumberFormatException 這句話明確告訴了我們是數(shù)字格式異常,接著后面有 For input string: "100 " 提示,這就告訴我們,當(dāng)前想把 "100 " 轉(zhuǎn)換成數(shù)字類型時出錯了,這樣就很確切了。
  • D.引發(fā)崩潰日志的流程分析
  • F.解決辦法
    • 解決辦法很簡單,改成 Integer.parseInt(str.trim()),注意將字符串轉(zhuǎn)化成整數(shù)數(shù)據(jù)類型時,注意需要trim一下。
  • G.其他延申

1.4 java.lang.IllegalStateException: Fragment not attached to Activity

  • A.詳細(xì)崩潰日志信息
    java.lang.IllegalStateException: Fragment not attached to Activity
    
  • B.查看崩潰類信息
  • C.項目中異常分析
    • 出現(xiàn)該異常,是因為Fragment的還沒有Attach到Activity時,調(diào)用了如getResource()等,需要上下文Content的函數(shù)。
    • 出現(xiàn)該異常,是因為Fragment還沒有Attach到Activity時,調(diào)用了如getResource()等,需要上下文Context的函數(shù)。解決方法,就是等將調(diào)用的代碼寫在OnStart()中。
  • D.引發(fā)崩潰日志的流程分析
  • F.解決辦法
    • 將調(diào)用的代碼運行在Fragment Attached的生命周期內(nèi)。
    • 第一種:在調(diào)用需要Context的函數(shù)之前,增加一個判斷isAdded()
    if(isAdded()){//isAdded方法是Android系統(tǒng)提供的,只有在Fragment被添加到所屬的Activity后才返回true
        activity.getResourses().getString(...);
    }
    
    • 第二種:如下所示
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        activity = (MainActivity) context;
    }
    
    @Override
    public void onDetach() {
        super.onDetach();
        if (activity != null) {
            activity = null;
        }
    }
    
  • G.其他延申
    • 發(fā)生場景:該錯誤經(jīng)常發(fā)生在fragment的線程中執(zhí)行了一個耗時操作,線程在執(zhí)行完畢后會調(diào)用getResources來更新ui。如果在線程操作沒有完成,就調(diào)用getActivity().recreate()重新加載activity或屏幕旋轉(zhuǎn),這時就會出現(xiàn)Fragment not attached to Activity的錯誤

1.5 ArrayIndexOutOfBoundsException 角標(biāo)越界異常

  • A.詳細(xì)崩潰日志信息
    • 該異常表示數(shù)組越界
    java.lang.ArrayIndexOutOfBoundsException: 0
        at com.example.mytest.CityAdapter.setDataNotify(CityAdapter.java:183)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    
  • B.查看崩潰類信息
    • 引發(fā),以指示已使用非法索引訪問數(shù)組。索引不是負(fù)的,就是大于或等于數(shù)組的大小。
    public class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException {
        private static final long serialVersionUID = -5116101128118950844L;
        public ArrayIndexOutOfBoundsException() {
            super();
        }
        public ArrayIndexOutOfBoundsException(int index) {
            super("Array index out of range: " + index);
        }
        public ArrayIndexOutOfBoundsException(String s) {
            super(s);
        }
        public ArrayIndexOutOfBoundsException(int sourceLength, int index) {
            super("length=" + sourceLength + "; index=" + index);
        }
        public ArrayIndexOutOfBoundsException(int sourceLength, int offset,
                int count) {
            super("length=" + sourceLength + "; regionStart=" + offset
                    + "; regionLength=" + count);
        }
    }
    
  • C.項目中異常分析
  • D.引發(fā)崩潰日志的流程分析
  • F.解決辦法
    • 這種情況一般要在數(shù)組循環(huán)前做好length判斷,index超出length上限和下限時都會報錯。舉例如下:一個數(shù)組int test[N],一共有N個元素分別是test[0]~test[N-1],如果調(diào)用test[N],將會報錯。建議讀取時,不要超過數(shù)組的長度(array.length)。
    • Android中一種常見情形就是上拉刷新中header也會作為listview的第0個位置,如果判斷失誤很容易造成越界。
  • G.其他延申

1.6 IllegalAccessException 方法中構(gòu)造方法權(quán)限異常

  • A.詳細(xì)崩潰日志信息
    Unable to instantiate application com.pedaily.yc.meblurry.App: java.lang.IllegalAccessException
    
  • B.查看崩潰類信息
    • 當(dāng)應(yīng)用程序試圖反射地創(chuàng)建實例(數(shù)組除外)、設(shè)置或獲取字段或調(diào)用方法時,將引發(fā)IllegalAccessException,但當(dāng)前執(zhí)行的方法無法訪問指定的類、字段、方法或構(gòu)造函數(shù)的定義。
    public class IllegalAccessException extends ReflectiveOperationException {
        private static final long serialVersionUID = 6616958222490762034L;
        public IllegalAccessException() {
            super();
        }
        public IllegalAccessException(String s) {
            super(s);
        }
    }
    
  • C.項目中異常分析
    • 錯誤提示是,構(gòu)造方法的權(quán)限不對
  • D.引發(fā)崩潰日志的流程分析
  • F.解決辦法
    • 檢查了整個Application,才發(fā)現(xiàn),原來有一個無參數(shù)的構(gòu)造方法,被設(shè)計成private。修改其為public即可。
  • G.其他延申
    • android BroadcastReceiver遇到j(luò)ava.lang.IllegalAccessException解決方法,錯誤原因主要是app中其他地方調(diào)用了默認(rèn)的構(gòu)造函數(shù),必須增加默認(rèn)構(gòu)造函數(shù)且訪問權(quán)限為public

1.7 android.view.WindowManager$BadTokenException,dialog彈窗異常

  • A.詳細(xì)崩潰日志信息
    Unable to add window -- token android.os.BinderProxy@9a57804 is not valid; is your activity running?
    android.view.ViewRootImpl.setView(ViewRootImpl.java:907)
    
  • B.查看崩潰類信息
    • 在WindowManager中可以找到這個異常類,主要發(fā)生在嘗試添加視圖時引發(fā)的
    public static class BadTokenException extends RuntimeException {
        public BadTokenException() {
        }
    
        public BadTokenException(String name) {
            super(name);
        }
    }
    
  • C.項目中異常分析
    • 該異常表示不能添加窗口,通常是所要依附的view已經(jīng)不存在導(dǎo)致的。
  • D.引發(fā)崩潰日志的流程分析
  • F.解決辦法
    • 之前項目中有一個自定義彈窗,偶爾會報這個錯。解決辦法如下代碼所示
    • 主要邏輯是在彈窗show或者dismiss的時候,都增加了邏輯判斷,判斷宿主activity存在。
    /**
     * 展示加載窗
     * @param context               上下文
     * @param isCancel              是否可以取消
     */
    public static void show(Context context,  boolean isCancel) {
        if(context == null){
            return;
        }
        if (context instanceof Activity) {
            if (((Activity) context).isFinishing()) {
                return;
            }
        }
        if (loadDialog != null && loadDialog.isShowing()) {
            return;
        }
        loadDialog = new LoadLayoutDialog(context, isCancel);
        loadDialog.show();
    }
    
    /**
     * 銷毀加載窗
     * @param context               上下文
     */
    public static void dismiss(Context context) {
        if(context == null){
            return;
        }
        try {
            if (context instanceof Activity) {
                if (((Activity) context).isFinishing()) {
                    loadDialog = null;
                    return;
                }
            }
            if (loadDialog != null && loadDialog.isShowing()) {
                Context loadContext = loadDialog.getContext();
                if (loadContext instanceof Activity) {
                    if (((Activity) loadContext).isFinishing()) {
                        loadDialog = null;
                        return;
                    }
                }
                loadDialog.dismiss();
                loadDialog = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            loadDialog = null;
        }
    }
    
  • G.其他延申
    • Dialog&AlertDialog,Toast,WindowManager不能正確使用時,經(jīng)常會報出該異常,原因比較多,幾個常見的場景如下:
      • 1.上一個頁面沒有destroy的時候,之前的Activity已經(jīng)接收到了廣播。如果此時之前的Activity進行UI層面的操作處理,就會造成crash。UI層面的刷新,一定要注意時機,建議使用set_result來代替廣播的形式進行刷新操作,避免使用廣播的方式,代碼不直觀且容易出錯。
      • 2.Dialog在Actitivty退出后彈出。在Dialog調(diào)用show方法進行顯示時,必須要有一個Activity作為窗口的載體,如果Activity被銷毀,那么導(dǎo)致Dialog的窗口載體找不到。建議在Dialog調(diào)用show方法之前先判斷Activity是否已經(jīng)被銷毀。
      • 3.Service&Application彈出對話框或WindowManager添加view時,沒有設(shè)置window type為TYPE_SYSTEM_ALERT。需要在調(diào)用dialog.show()方法前添加dialog.getWindow().SetType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT)。
      • 4.6.0的系統(tǒng)上, (非定制 rom 行為)若沒有給予懸浮窗權(quán)限, 會彈出該問題, 可以通過Settings.canDrawOverlays來判斷是否有該權(quán)限.
      • 5.某些不穩(wěn)定的MIUI系統(tǒng)bug引起的權(quán)限問題,系統(tǒng)把Toast也當(dāng)成了系統(tǒng)級彈窗,android6.0的系統(tǒng)Dialog彈窗需要用戶手動授權(quán),若果app沒有加入SYSTEM_ALERT_WINDOW權(quán)限就會報這個錯。需要加入給app加系統(tǒng)Dialog彈窗權(quán)限,并動態(tài)申請權(quán)限,不滿足第一條會出現(xiàn)沒權(quán)限閃退,不滿足第二條會出現(xiàn)沒有Toast的情況。

1.8 java.lang.NoClassDefFoundError 找不到類異常

  • A.詳細(xì)崩潰日志信息
  • B.查看崩潰類信息
    • 如果Java虛擬機或<code>ClassLoader</code>實例試圖加載類的定義(作為普通方法調(diào)用的一部分或使用<code>新的</code>表達(dá)式創(chuàng)建新實例的一部分),則拋出該類的定義。編譯當(dāng)前執(zhí)行的類時存在搜索類定義,但無法再找到該定義。
    public class NoClassDefFoundError extends LinkageError {
        private static final long serialVersionUID = 9095859863287012458L;
        public NoClassDefFoundError() {
            super();
        }
        public NoClassDefFoundError(String s) {
            super(s);
        }
        private NoClassDefFoundError(String detailMessage, Throwable throwable) {
            super(detailMessage, throwable);
        }
    }
    
  • C.項目中異常分析
    • 問題的主要原因:方法數(shù)超65536限制。由于實際開發(fā)當(dāng)中的需求不斷變更,開源框架越來越多,大多都用第三方SDK,導(dǎo)致方法數(shù)很容易超出65536限制。出現(xiàn)錯誤Java.lang.NoClassDefFoundError
  • D.引發(fā)崩潰日志的流程分析
    • 這個錯誤是Android應(yīng)用的方法總數(shù)限制造成的。android平臺的Java虛擬機Dalvik在執(zhí)行DEX格式的Java應(yīng)用程序時,使用原生類型short來索引DEX文件中的方法。這意味著單個DEX文件可被引用的方法總數(shù)被限制為65536。通常APK包含一個classes.dex文件,因此Android應(yīng)用的方法總數(shù)不能超過這個數(shù)量,這包括Android框架、類庫和你自己開發(fā)的代碼。而Android 5.0和更高版本使用名為ART的運行時,它原生支持從APK文件加載多個DEX文件。在應(yīng)用安裝時,它會執(zhí)行預(yù)編譯,掃描classes(..N).dex文件然后將其編譯成單個.oat文件用于執(zhí)行. 通熟的講,就是分包。
  • F.解決辦法
    • 64k解決辦法
  • G.其他延申
    • 該異常表示找不到類定義,當(dāng)JVM或者ClassLoader實例嘗試裝載該類的定義(這通常是一個方法調(diào)用或者new表達(dá)式創(chuàng)建一個實例過程的一部分)而這個類定義并沒有找時所拋出的錯誤。
    • [解決方案]:NoClassDefFoundError異常一般出現(xiàn)在編譯環(huán)境和運行環(huán)境不一致的情況下,就是說有可能在編譯過后更改了Classpath或者jar包所以導(dǎo)致在運行的過程中JVM或者ClassLoader無法找到這個類的定義。
      • 1.分dex包編程,如果依賴的dex包刪除了指定的類,執(zhí)行初始化方法時將會報錯;
      • 2.使用第三方SDK或插件化編程時,動態(tài)加載或?qū)嵗愂箦e;
      • 3.系統(tǒng)資源緊張時,當(dāng)大量class需要加載到內(nèi)存的時候,處于競爭關(guān)系,部分calss競爭失敗,導(dǎo)致加載不成功;
      • 4.裝載并初始化一個類時失敗(比如靜態(tài)塊拋 java.lang.ExceptionInInitializerError 異常),然后再次引用此類也會提示NoClassDefFoundErr 錯誤;
      • 5.手機系統(tǒng)版本或硬件設(shè)備不匹配(如ble設(shè)備只支持18以上SDK),程序引用的class在低版本中不存在,導(dǎo)致NoClassDefFoundErr 錯誤。
      • 6.so文件找不到,設(shè)備平臺armeabi-v7a,但是我的so庫是放在armeabi中的,解決方法新建一個armeabi-v7a包,并且把armeabi的文件拷貝過來.

1.9 Android出現(xiàn):Your project path contains non-ASCII characters.

  • A.詳細(xì)崩潰日志信息
  • B.查看崩潰類信息
  • C.項目中異常分析
  • D.引發(fā)崩潰日志的流程分析
  • F.解決辦法
    • 很好解決啦,就是你的工程項目路徑或者項目名稱包含了中文,修改相關(guān)的名稱就好
  • G.其他延申

關(guān)于其他內(nèi)容介紹

01.關(guān)于博客匯總鏈接

02.關(guān)于我的博客

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,837評論 18 139
  • 目錄介紹 1.1 java.lang.UnsatisfiedLinkError找不到so庫異常 1.2 java....
    楊充211閱讀 1,017評論 0 2
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,739評論 18 399
  • 條件是數(shù)組中可能出現(xiàn)重復(fù)的數(shù)字,很容易就會想到折半查找,但是對于重復(fù)元素怎么處理? 解決方法一:最先想到的就是二分...
    cp3_1dbc閱讀 325評論 0 1
  • 漫步西湖畔 垂柳新枝招展 細(xì)雨微濛 你笑靨如花 眼波柔若春水 輕輕道 這是你夢里的江南 有烏云纏卷 潑墨般暈染 淅...
    宋予嶼閱讀 442評論 1 10