天天看点

Android中常见的异常

#`android冲常见的异常大概分为以下几类:

一:空指针异常(java.lang.NullPointerException)

此异常表示调用Virtual method,使用了一个空对象引用。

[解决方案]:检查引用的对象是否为空。这种异常造成的原因通常是调用一个对象的方法造成的,调用一个对象的方法之前,一定要判断是否为空,或者进行try-catch,这样能避免大部分异常。

二:(下标越界异常)java.lang.IndexOutOfBoundsException 或者java.lang.ArrayIndexOutOfBoundsException该异常表示不合法的下标,通常是访问了list或者array不合法的位置。

[解决方案]:

1、检查数组是否越界,字符串集合前要遍历集合的长度。

2、操作数组,检查角标是否在允许范围之内。

3、ListView操作不当也会引起该异常,这种情况一般是list渲染的时候,外面的数据发生变化导致的。例如listview滚动刷新时会报此异常,解决方案listview滚动时将点击刷新置为不可点击。

三:数字格式化异常(java.lang.format.exception)。当字符串转化为数字类型时,该字符串不满足数字类型要求的格式时,抛出该异常(字符串不能为" ",或者为null);

四:找不到指定类异(java.lang.ClassNotFoundException)

该异常表示此路径下找不到指定类,通常是构建路径问题导致的。

[解决方案]:类名是以字符串形式标识的,可信度低,在调用Class.forName(""),Class.findSystemClass(""),Class.loadClass("")等方法时,找不到时将会报错。(1)如果找不到的类是系统的类,那么可能是系统兼容,厂家Rom兼容的问题。找到对应的设备尝试重现,解决方案可以考虑更换API或者考虑自己实现class。(二)如果找不到的类是应用自由Class(第三方Class)可以通过反编译工具查看对应apk中是否真的缺少Class,再进行定位,这种往往发生在:

1:要找的类被混淆了,存在但名称变了。

2:要找的类未被打入DEX,确实不存在,可能应为自己的疏忽,或编译器环境的问题。

3:要找的class确实存在,但你的ClassLorder找不到这个Class,往往是因为ClassLorder是你自己实现的(插件应用常见)。

五:并发修改异常(java.util.ConcurrentModificationException)该异常表示迭代器在迭代过程中,迭代的对象发生了改变,如数据的增加或者删除。

[解决方案]:由于迭代对象不是线程安全,迭代的过程中会检查modcount是否和当初的modcount即exceptionmodcount一致如果不一致,则认为数据有变化,迭代终止并抛出异常。出现的场景是两个线程同时对一个集合进行操作,线程一对集合进行遍历,线程二对集合进行增加删除操作此时会发生ConcurrentModificationException异常。

[解决方案]:多线程访问时要怎增加同步锁,或者建议使用线程安全的集合:

1.使用concurrentHashMap替换HashMap,CopyOnWriteArrayList替换ArrayList;

2.使用vector替换ArrayList,Vector是线程安全的,缺点是大量数据操作时,由于线程安全,性能比ArrayList低。

六:java.lang.OutOfMemoryError Count not allocate JNI Env

Out of Memory Error异常大概分为以下几类:

1:内存中加载的数据过大,如一次从数据库中取出过多的数据。

2:集合类中有对对象的引用,使用完后未清空,是的JVM不能回收;

3:代码中存在死循环或循环产生过多的重复的对象实体;

[解决方案]:加载数据过多的时候选择分页加载,不要在循环体中创建大量的对象。

OOM是常见的java错误,OOM主要有:

1:OOM fo heapjava.lang:OutOfMemoryError:java heap space此OOM是由于JVM中heap最大值不满足需要可将heap最大值调改高即可。

2:OOM for Perm:java.lang:outofMemoryError:java perm space,此OOM是由于JVM中的prem最大值不满足需求,将设置perm的最大值调高即可,参数样例为:-XX:MaxPermSize=512M;

3:OOM for GC=>例如:java.lang:outofMemoryError:GC overhead limit exceeded,此OOM是由于JVM在GC时,对象过多,导致内存溢出,建议调整GC策略。

4:OOM for native thread created:java.lang.OutOfMemoryError:unable to create new native thread,此OOM是由于进程空间不足,导致进程创建失败

5:oom for allocate huge array:Exception in thread “main”:java.lang.OutOfMemoryError:request array size exceed VM limit 试图分配一个大于堆大小的数组。

6:OOM for small swap:Exception in thread “main”:java.lang.OutOfmemoryError:requestbyte for.OutOf swap space?抛出这类错误是由于从native堆中分配内存失败,并且堆内存可能接近耗尽

7:OutOfMemoryErroy thrown while trying to throw OutOfMemoryError; no stack trace available,抛出这类错误一般是由于方法重复调用,死循环,直至内存消耗殆尽。

七:java.lang.illegalArgumentException [email protected][MainActivity] not attached to window mannager android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:647),该异常表示没有添加到窗口管理器,通常我们关闭对话框的时候,activity已经不存在了,建议不要在非UI线程操作对话框。

[解决方案]:常发生这类Exception的情景都是,有一个费时的线程操作,需要显示一个Dialog,在任务开始的时候显示Dialog,当任务完成时再关闭对话框,如果在此期间Activity因为某种原因被杀掉而又重新启动,当dialog调用dismiss的时候WindowManager检查会发现Dialog所属的Activity已经不存在,所以会报错。

要避免此Exception发生就要正确使用线程,正确使用线程:

1:不要在非UI线程线程中使用对话框的创建,现实和取消对话框。

2:尽量少用单独线程,耗时的操作采用线程,线程不要采用java式的匿名线程,除非单纯的线程,操作完不用做其他的事情。

3:如后是在fragment中发起异步网络回调中进行dialog的操作,那么在操作之前,需要判断isAdd(),避免fragmnet被回收了还要dialog或者dismiss

4:在Activity onDestroy中对Dialog提前进行关闭

八:类型转换异常(java.lang.ClassCastException)试图将一个类型转换成指定的类型。JVM在做类型转换的时候会按照如下规则进行检查。

对于普通对象,对象必须目标类的实例或者目标类子类的实例。如果目标类是接口,就会把它当成该接口的一个子类。

对于数组类型,目标类必须是数组类或者java.lang.Object、java.lang.Cloneable、java.io.Serializable.

[解决方案]:先用instanceof判断数据类型,再强制转换。

持续更新~~~

文章参考:https://blog.csdn.net/fishandbean/article/details/92768745