Android异常总结

异常

概述

Java程序在运行过程中出现的错误

分类

Error:服务器宏机,数据库崩溃等
Exception
编译时异常:Java程序必须显示处理,否则程序会发生错误,无法通过编译,如:IOException,SQLException等
当函数中存在抛出检查型异常的操作时该函数的函数声明中必须包含throws语句。调用改函数的函数也必须对该异常进行处理,如不进行处理则必须在调用函数上声明throws语句
运行时异常:可抛出显示让程序停止,可捕获继续运行,如:NullPointException,ClassCastException 等
与编译时异常对比,运行时异常可以不在函数声明中添加throws语句,调用函数上也不需要强制处理

继承体系

Throwable
Error
Exception
RuntimeException 运行时异常

注意事项

1 子类方法需抛出和父类相同的异常或父类异常的子类
2 如父类抛出多个异常,子类只能抛出相同的异常或父类异常的子集
3 如被重写方法没有抛出异常,子类重写方法也不能抛出异常,如果子类发生异常,只能捕获

异常捕获:try…catch…finally

try 检测异常
catch 捕获异常
finally 释放资源
catch
如catch中有return语句,return语句依旧会在finally后执行
finally
被finally控制的语句体一定会执行,用于释放资源,在IO流操作和数据库操作中会见到
如果finally代码块之前方法返回了结果,finally代码块依然会执行,并且会在return语句之前执行;如果finally代码块之前JVM退出了finally代码块中的代码不会执行;如果执行finally代码块时,线程突然结束,也不会执行
final,finally和finalize区别
final 修饰类,不能被继承;修饰方法,不能被重写,修饰变量 变量变常量
finally 是try语句中的一个语句体,不能单独使用,用来释放资源
finalize 是一个方法
throw
概述:在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出
throw与throws区别
throw
用在方法体内,跟的是异常对象名
只能抛出一个异常对象名
表示抛出异常,由方法体内的语句处理
throws
用在方法声明后面,跟的是异常类名
可以跟多个异常类名,用逗号隔开
表示抛出异常,由该方法的调用者来处理

异常处理——ANR

ANR(Application Not Responding):程序无响应。会造成ANR弹框

原因

主线程被IO操作(从4.0之后网络IO不允许在主线程中)阻塞
主线程存在耗时的操作

Android系统中在UI线程的常见操作

1、Activity的所有生命周期,阻塞5s会造成ANR
2、Service默认是执行在主线程的,IntentService默认执行在子线程,阻塞20s会造成ANR
3、BroadcastReceiver的onReceiver回调,阻塞10s会造成ANR
4、没有使用子线程的Looper的Handler的handleMessage,post(Runnable)
5、AsyncTask的回调除了doInBackground,其他都是在主线程

解决

1、使用AsyncTask处理耗时操作
2、使用Thread或HandlerThread提高优先级
3、使用Handler来处理工作线程的耗时任务
4、Activity的onCreate()和onResume()回调函数中尽量避免耗时操作

异常处理——OOM

当前占用的内存加上我们申请的内存资源超过了Dalvik虚拟机的最大内存限制就会抛出Out Of Memory异常
内存溢出
OOM异常。当前占用的内存加上我们申请的内存资源超过了Dalvik虚拟机的最大内存限制就会抛出Out Of Memory异常
内存抖动
内存抖动是由于短时间内有大量对象进出Young Generiation区导致的,它伴随着频繁的GC
内存泄漏
指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果

原因

1、加载对象过大|
2、响应资源过多,来不及释放
3、Adapter没有使用缓存的convertView
4、Android虚拟机Dalvik,最大堆大小为16M,有的机器为24M

解决

1、Bitmap的优化
2、ListView的优化/LRU(最近最少使用机制)
3、避免在onDraw方法里面执行对象的创建
4、谨慎使用多进程
5、关闭资源
6、堆内存自定义大小和优化Dalvik虚拟机对内存分配

​ Dalvik虚拟机堆内存分配优化setTargetHeapUtilization;自定义堆内存大小setMinimumHeapSize

问题

OOm是否可以try catch
可以,通过确认并释放掉导致OOM的对象来继续执行剩余语句。

为什么不要重载finazlie()方法
会影响JVM的对象分配与回收速度
在分配该对象时,JVM需要在垃圾回收器上注册该对象,以便在回收时能够执行该重载方法;在该方法的执行时需要消耗CPU时间且在执行完该方法后才会重新执行回收操作,即至少需要垃圾回收器对该对象执行两次GC
可能造成该对象的再次“复活”
在finalize()方法中,如果有其它的强引用再次持有该对象,则会导致对象的状态由“收集阶段”又重新变为“应用阶段”。这个已经破坏了Java对象的生命周期进程,且“复活”的对象不利用后续的代码管理

你可能感兴趣的:(Android,Android基础)