美文网首页Android 开发Android开发经验谈Android技术知识
Android 常见崩溃问题分析及一般的解决方案

Android 常见崩溃问题分析及一般的解决方案

作者: BugFree张瑞 | 来源:发表于2019-02-23 16:51 被阅读0次

    一、java.lang.IllegalArgumentException

    解决方案:

    参数不匹配异常,通常由于传递了不正确的参数导致。

    常见于:

    1. Activity、Service 状态异常;
    2. 非法 URL;
    3. UI 线程操作;
    4. Fragment 中嵌套了子 Fragment,Fragment 被销毁,而内部 Fragment 未被销毁,所以导致再次加载时重复,在 onDestroyView() 中将内部Fragment 销毁即可
    5. 在请求网络的回调中使用了 glide.into(view),view 已经被销毁会导致该错误。

    二、java.lang.NullPointerException

    解决方案:

    该异常表示尝试去调用 virtual method,使用了一个空对象引用,建议您检查引用的对象是否为空。

    这种异常通常是调用一个对象的方法抛出的,凡是调用一个对象的方法之前,一定要进行判空或者进行 try-catch,这样基本可以规避大部分空指针异常。

    三、java.util.ConcurrentModificationException

    解决方案:

    该异常表示迭代器迭代过程中,迭代的对象发生了改变,如数据项增加或删除。

    由于迭代对象不是线程安全,在迭代的过程中,会检查 modCount 是否和初始 modCount 即 expectedModCount 一致,如果不一致,则认为数据有变化,迭代终止并抛出异常。常出现的场景是,两个线程同时对集合进行操作,线程1对集合进行遍历,而线程2对集合进行增加、删除操作,此时将会发生 ConcurrentModificationException 异常。

    具体方法:多线程访问时要增加同步锁,或者建议使用线程安全的集合:

    1. 使用 ConcurrentHashMap 替换 HashMap,CopyOnWriteArrayList 替换 ArrayList;
    2. 或者使用 Vector 替换 ArrayList,Vector 是线程安全的。Vector 的缺点:大量数据操作时,由于线程安全,性能比 ArrayList 低

    实战案例:
    https://blog.csdn.net/u011489043/article/details/84983322

    四、java.lang.IllegalStateException

    java.lang.IllegalStateException 异常产生的原因及解决办法

    错误类型大致为以下几种:
    java.lang.IllegalStateException:Cannot forward a response that is already committed
    IllegalStateException:response already commited
    IllegalStateException:getOutputStream() has already been called for this request

    =========================================================
    IllegalStateException: Can not perform this action after onSaveInstanceState:
    解决办法:onSaveInstanceState 方法是在该 Activity 即将被销毁前调用,来保存 Activity 数据的,如果在保存玩状态后再给它添加 Fragment 就会出错。解决办法就是把 commit() 方法替换成 commitAllowingStateLoss()
    =========================================================

    =====================================================
    补充另一种异常情况:
    java.lang.IllegalStateException
    Can't change tag of fragment d{e183845 #0 d{e183845}}: was d{e183845} now d{e183845 #0 d{e183845}}
    经查,我在显示 fragment 的代码中使用了:
    fragment.show(getSupportFragmentManager, fragment.toString());
    而这里是因为两次 toString() 结果不同,导致不同的 tag 指向的是同一个 fragment。获取 fragment 的 tag 的正确方法应该是使用其提供的 fragment.getTag() 方法。
    =====================================================

    =====================================================
    补充另一种异常情况:
    java.lang.IllegalStateException
    Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 37 path $.data
    错误原因:该异常是由于服务器错误返回的 JSON 字符串和服务器正常时返回的 JSON 字符串结构不同,导致利用 Gson 解析的时候报了一个异常:本该去解析集合却强制去解析对象所致。
    解决办法:在使用 Gson 解析 JSON 时 try cash 一下,不报错按照正常逻辑继续解析,报异常则处理为请求失败逻辑即可。
    ======================================================

    五、android.content.res.Resources$NotFoundException

    解决方案:

    该异常表示找不到字符串资源 ID,检查引用的字符串资源 ID 是否在 R.java 文件中定义,或者检查传递的 ID 参数是否正确。

    这种报错通常是因为将 int 等整型变量作为了参数传给了 View.setText() 调用,这种情况下该整型变量将被认为是一个资源ID号去资源列表中查找对应的资源,导致找不到对应资源错误。解决方法是把 int 型数据改成 String 类型,如 setText(Integer.toString(value)) 或 setText("" + value)。另外,建议在使用 inflate() 方法的时候,传入的布局资源最好使用 R.layout.xxx 来指定,这样可以降低出错的概率。

    相关文章

      网友评论

        本文标题:Android 常见崩溃问题分析及一般的解决方案

        本文链接:https://www.haomeiwen.com/subject/nfjpyqtx.html