崩溃bug日志总结2

目录介绍

  • 1.1 java.lang.ClassNotFoundException类找不到异常
  • 1.2 java.util.concurrent.TimeoutException链接超时崩溃
  • 1.3 java.lang.NumberFormatException格式转化错误
  • 1.4 java.lang.IllegalStateException: Fragment not attached to Activity
  • 1.5 ArrayIndexOutOfBoundsException 角标越界异常
  • 1.6 IllegalAccessException 方法中构造方法权限异常
  • 1.7 android.view.WindowManager$BadTokenException,dialog弹窗异常
  • 1.8 java.lang.NoClassDefFoundError 找不到类异常
  • 1.9 Android出现:Your project path contains non-ASCII characters.

好消息

  • 博客笔记大汇总【16年3月到至今】,包括Java基础及深刻知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,固然也在工做之余收集了大量的面试题,长期更新维护而且修正,持续完善……开源的文件是markdown格式的!同时也开源了生活博客,从12年起,积累共计47篇[近20万字],转载请注明出处,谢谢!
  • 连接地址:https://github.com/yangchong2...
  • 若是以为好,能够star一下,谢谢!固然也欢迎提出建议,万事起于忽微,量变引发质变!

1.1 java.lang.ClassNotFoundException类找不到异常

  • A.详细崩溃日志信息php

    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.查看崩溃类信息java

    • 当应用程序尝试使用字符串名称加载类时引起:但没法找到具备指定名称的类的定义。从1.4版开始,已对此异常进行了修改,以符合通用的异常连接机制。在构建时提供并经过{@link#getException()}方法访问的“在加载类时引起的可选异常”如今称为缘由,而且能够经过{@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.项目中异常分析android

    • 该异常表示在路径下,找不到指定类,一般是由于构建路径问题致使的。
  • D.引起崩溃日志的流程分析
  • F.解决办法git

    • 类名是以字符串形式标识的,可信度比较低,在调用Class.forName(""),Class.findSystemClass(""),Class.loadClass("")等方法时,找不到类名时将会报错。若是找不到的Class是系统Class,那么多是系统版本兼容,厂家Rom兼容的问题,找到对应的设备尝试重现,解决方法能够考虑更换Api,或用本身实现的Class替代。
    • 若是找不到的Class是应用自由Class(含第三方SDK的Class),能够经过反编译工具查看对应apk中是否真的缺乏该Class,再进行定位,这种每每发生在:github

      • 1.要找的Class被混淆了,存在但名字变了;
      • 2.要找的Class未被打入Dex,确实不存在,多是由于本身的疏忽,或编译环境的冲突;
      • 3.要找的Class确实存在,但你的Classlorder找不到这个Class,每每由于这个Classloder是你自实现的(插件化应用中常见)。
  • G.其余延申

1.2 java.util.concurrent.TimeoutException链接超时崩溃

  • A.详细崩溃日志信息面试

    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.查看崩溃类信息编程

    • 当阻塞操做超时引起的异常。指定超时的阻塞操做须要一种方法来指示已发生超时。对于许多此类操做,能够返回指示超时的值;若是不可能或不须要,则应声明并抛出{@code TimeoutException}。
    public class TimeoutException extends Exception {
        private static final long serialVersionUID = 1900926677490660714L;
        public TimeoutException() {}
        public TimeoutException(String message) {
            super(message);
        }
    }
  • C.项目中异常分析
  • D.引起崩溃日志的流程分析
  • F.解决办法segmentfault

    • 通常是系统在gc时,调用对象的finalize超时致使,解决办法:
    • 1.检查分析finalize的实现为何耗时较高,修复它;
    • 2.检查日志查看GC是否过于频繁,致使超时,减小内容开销,防止内存泄露。
  • G.其余延申

1.3 java.lang.NumberFormatException格式转化错误

  • A.详细崩溃日志信息数组

    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.查看崩溃类信息markdown

    • 引起,以指示应用程序试图将字符串转换为数字类型之一,但该字符串没有适当的格式。
    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.项目中异常分析

    • 错误关键字 java.lang.NumberFormatException 这句话明确告诉了咱们是数字格式异常,接着后面有 For input string: "100 " 提示,这就告诉咱们,当前想把 "100 " 转换成数字类型时出错了,这样就很确切了。
  • D.引起崩溃日志的流程分析
  • F.解决办法

    • 解决办法很简单,改为 Integer.parseInt(str.trim()),注意将字符串转化成整数数据类型时,注意须要trim一下。
  • G.其余延申

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

  • A.详细崩溃日志信息

    java.lang.IllegalStateException: Fragment not attached to Activity
  • B.查看崩溃类信息
  • C.项目中异常分析

    • 出现该异常,是由于Fragment的尚未Attach到Activity时,调用了如getResource()等,须要上下文Content的函数。
    • 出现该异常,是由于Fragment尚未Attach到Activity时,调用了如getResource()等,须要上下文Context的函数。解决方法,就是等将调用的代码写在OnStart()中。
  • D.引起崩溃日志的流程分析
  • F.解决办法

    • 将调用的代码运行在Fragment Attached的生命周期内。
    • 第一种:在调用须要Context的函数以前,增长一个判断isAdded()
    if(isAdded()){//isAdded方法是Android系统提供的,只有在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.其余延申

    • 发生场景:该错误常常发生在fragment的线程中执行了一个耗时操做,线程在执行完毕后会调用getResources来更新ui。若是在线程操做没有完成,就调用getActivity().recreate()从新加载activity或屏幕旋转,这时就会出现Fragment not attached to Activity的错误

1.5 ArrayIndexOutOfBoundsException 角标越界异常

  • A.详细崩溃日志信息

    • 该异常表示数组越界
    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.查看崩溃类信息

    • 引起,以指示已使用非法索引访问数组。索引不是负的,就是大于或等于数组的大小。
    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.解决办法

    • 这种状况通常要在数组循环前作好length判断,index超出length上限和下限时都会报错。举例以下:一个数组int test[N],一共有N个元素分别是test[0]~test[N-1],若是调用test[N],将会报错。建议读取时,不要超过数组的长度(array.length)。
    • Android中一种常见情形就是上拉刷新中header也会做为listview的第0个位置,若是判断失误很容易形成越界。
  • G.其余延申

1.6 IllegalAccessException 方法中构造方法权限异常

  • A.详细崩溃日志信息

    Unable to instantiate application com.pedaily.yc.meblurry.App: java.lang.IllegalAccessException
  • B.查看崩溃类信息

    • 当应用程序试图反射地建立实例(数组除外)、设置或获取字段或调用方法时,将引起IllegalAccessException,但当前执行的方法没法访问指定的类、字段、方法或构造函数的定义。
    public class IllegalAccessException extends ReflectiveOperationException {
        private static final long serialVersionUID = 6616958222490762034L;
        public IllegalAccessException() {
            super();
        }
        public IllegalAccessException(String s) {
            super(s);
        }
    }
  • C.项目中异常分析

    • 错误提示是,构造方法的权限不对
  • D.引起崩溃日志的流程分析
  • F.解决办法

    • 检查了整个Application,才发现,原来有一个无参数的构造方法,被设计成private。修改其为public便可。
  • G.其余延申

    • android BroadcastReceiver遇到java.lang.IllegalAccessException解决方法,错误缘由主要是app中其余地方调用了默认的构造函数,必须增长默认构造函数且访问权限为public

1.7 android.view.WindowManager$BadTokenException,dialog弹窗异常

  • A.详细崩溃日志信息

    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中能够找到这个异常类,主要发生在尝试添加视图时引起的
    public static class BadTokenException extends RuntimeException {
        public BadTokenException() {
        }
    
        public BadTokenException(String name) {
            super(name);
        }
    }
  • C.项目中异常分析

    • 该异常表示不能添加窗口,一般是所要依附的view已经不存在致使的。
  • D.引起崩溃日志的流程分析
  • 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不能正确使用时,常常会报出该异常,缘由比较多,几个常见的场景以下:

      • 1.上一个页面没有destroy的时候,以前的Activity已经接收到了广播。若是此时以前的Activity进行UI层面的操做处理,就会形成crash。UI层面的刷新,必定要注意时机,建议使用set_result来代替广播的形式进行刷新操做,避免使用广播的方式,代码不直观且容易出错。
      • 2.Dialog在Actitivty退出后弹出。在Dialog调用show方法进行显示时,必需要有一个Activity做为窗口的载体,若是Activity被销毁,那么致使Dialog的窗口载体找不到。建议在Dialog调用show方法以前先判断Activity是否已经被销毁。
      • 3.Service&Application弹出对话框或WindowManager添加view时,没有设置window type为TYPE_SYSTEM_ALERT。须要在调用dialog.show()方法前添加dialog.getWindow().SetType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT)。
      • 4.6.0的系统上, (非定制 rom 行为)若没有给予悬浮窗权限, 会弹出该问题, 能够经过Settings.canDrawOverlays来判断是否有该权限.
      • 5.某些不稳定的MIUI系统bug引发的权限问题,系统把Toast也当成了系统级弹窗,android6.0的系统Dialog弹窗须要用户手动受权,若果app没有加入SYSTEM_ALERT_WINDOW权限就会报这个错。须要加入给app加系统Dialog弹窗权限,并动态申请权限,不知足第一条会出现没权限闪退,不知足第二条会出现没有Toast的状况。

1.8 java.lang.NoClassDefFoundError 找不到类异常

  • A.详细崩溃日志信息
  • B.查看崩溃类信息

    • 若是Java虚拟机或ClassLoader实例试图加载类的定义(做为普通方法调用的一部分或使用新的表达式建立新实例的一部分),则抛出该类的定义。编译当前执行的类时存在搜索类定义,但没法再找到该定义。
    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.项目中异常分析

    • 问题的主要缘由:方法数超65536限制。因为实际开发当中的需求不断变动,开源框架愈来愈多,大多都用第三方SDK,致使方法数很容易超出65536限制。出现错误Java.lang.NoClassDefFoundError
  • D.引起崩溃日志的流程分析

    • 这个错误是Android应用的方法总数限制形成的。android平台的Java虚拟机Dalvik在执行DEX格式的Java应用程序时,使用原生类型short来索引DEX文件中的方法。这意味着单个DEX文件可被引用的方法总数被限制为65536。一般APK包含一个classes.dex文件,所以Android应用的方法总数不能超过这个数量,这包括Android框架、类库和你本身开发的代码。而Android 5.0和更高版本使用名为ART的运行时,它原生支持从APK文件加载多个DEX文件。在应用安装时,它会执行预编译,扫描classes(..N).dex文件而后将其编译成单个.oat文件用于执行. 通熟的讲,就是分包。
  • F.解决办法

    • 64k解决办法
  • G.其余延申

    • 该异常表示找不到类定义,当JVM或者ClassLoader实例尝试装载该类的定义(这一般是一个方法调用或者new表达式建立一个实例过程的一部分)而这个类定义并无找时所抛出的错误。
    • [解决方案]:NoClassDefFoundError异常通常出如今编译环境和运行环境不一致的状况下,就是说有可能在编译事后更改了Classpath或者jar包因此致使在运行的过程当中JVM或者ClassLoader没法找到这个类的定义。

      • 1.分dex包编程,若是依赖的dex包删除了指定的类,执行初始化方法时将会报错;
      • 2.使用第三方SDK或插件化编程时,动态加载或实例化类失败将会报错;
      • 3.系统资源紧张时,当大量class须要加载到内存的时候,处于竞争关系,部分calss竞争失败,致使加载不成功;
      • 4.装载并初始化一个类时失败(好比静态块抛 java.lang.ExceptionInInitializerError 异常),而后再次引用此类也会提示NoClassDefFoundErr 错误;
      • 5.手机系统版本或硬件设备不匹配(如ble设备只支持18以上SDK),程序引用的class在低版本中不存在,致使NoClassDefFoundErr 错误。
      • 6.so文件找不到,设备平台armeabi-v7a,可是个人so库是放在armeabi中的,解决方法新建一个armeabi-v7a包,而且把armeabi的文件拷贝过来.

1.9 Android出现:Your project path contains non-ASCII characters.

  • A.详细崩溃日志信息
  • B.查看崩溃类信息
  • C.项目中异常分析
  • D.引起崩溃日志的流程分析
  • F.解决办法

    • 很好解决啦,就是你的工程项目路径或者项目名称包含了中文,修改相关的名称就好
  • G.其余延申

关于其余内容介绍

01.关于博客汇总连接

02.关于个人博客

相关文章
相关标签/搜索