Android开发过程中遇到各种异常是不可避免的。透过详细的异常记录,我们不但能理解程序崩溃的原因,还能根据异常类型采取针对性的解决措施。以下为一些常见的Android异常和它们的特征:
一、Java异常
-
空指针 (NullPointException)
- 解决方案:检查对象是否为null,确保在调用方法或属性前已经初始化。
-
角标越界 (IndexOutOfBoundsException, StringIndexOutOfBoundsException, ArrayIndexOutOfBoundsException)
- 解决方案:检查数组和字符串的索引是否越界,确保索引在有效范围内。
-
调用一个空对象的方法 (Attempt to invoke virtual method on a null object reference)
- 解决方案:检查对象是否为null,确保在调用方法前已经初始化。
-
类型转换异常 (ClassCastException)
- 解决方案:检查对象类型是否正确,确保在进行类型转换时,对象实例与目标类型一致。
-
数字转换错误 (NumberFormatException)
- 解决方案:检查字符串是否可以转换为指定的数字类型,例如整数、浮点数等。
-
声明数组时长度为-1 (NegativeArraySizeException)
- 解决方案:确保数组的长度为非负整数。
-
遍历集合同时删除其中元素 (ConcurrentModificationException)
- 解决方案:使用迭代器的remove方法删除元素,避免在遍历过程中直接修改集合。
-
当除数为0 (java.lang.ArithmeticException: divide by zero)
- 解决方案:检查除数是否为0,并进行相应的异常处理。
-
类找不到 (ClassNotFoundException, NoClassDefFoundError)
- 解决方案:检查类路径是否正确,确保所需类文件已添加到项目中。
二、Activity异常
-
找不到Activity (android.content.ActivityNotFoundException)
- 解决方案:检查Intent的action、data等属性是否正确设置,确保有Activity能够处理该Intent。
-
不能实例化Activity (java.lang.RuntimeException)
- 解决方案:检查Activity的构造方法是否可见,确保Activity能够被系统实例化。
-
找不到Service (java.lang.RuntimeException)
- 解决方案:检查Service的声明是否正确,确保Service能够被系统实例化。
-
不能启动BroadcastReceiver (Unable to start receiver)
- 解决方案:检查BroadcastReceiver的声明和注册是否正确,确保能够接收相应的Intent。
-
startActkivity没有flag (android.util.AndroidRuntimeException)
- 解决方案:在调用startActivity时,添加FLAG_ACTIVITY_NEW_TASK标志。
-
startActivityForResult错误 (Failure delivering result ResultInfo)
- 解决方案:检查startActivityForResult的调用和onActivityResult的实现是否正确。
-
fragment未attach调用context (Fragment not attached to Activity)
- 解决方案:确保在调用Fragment相关方法时,Fragment已经与Activity建立关联。
三、序列化异常
-
实体对象不支持序列化 (Parcelable encountered IOException)
- 解决方案:检查实体类是否实现Parcelable接口,确保序列化过程正确。
-
序列化时未指定ClassLoader (BadParcelableException)
- 解决方案:在反序列化时指定正确的ClassLoader。
-
反序列化时发现类找不到 (Parcelable encountered ClassNotFoundException)
- 解决方案:检查ProGuard配置,确保所需类未被混淆。
-
反序列化时发现类找不到(传入畸形数据) (Parcelable encountered ClassNotFoundException)
- 解决方案:检查传入的数据是否正确,确保类名称与实际类一致。
-
反序列化时出错,数据太大 (Could not read input channel file descriptors from parcel)
- 解决方案:检查数据大小,确保不超过Parcel的最大容量。
四、窗体相关异常
-
窗口句柄泄露,dismiss前activity被销毁:
android.view.WindowLeaked: Activity xxx has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{xxxx}
- 解决方案:确保在Activity销毁前,所有Dialog等都要被dismiss,避免泄露。
-
窗体在不适当的时候获取了焦点,显示前获取了焦点:
java.lang.NullPointerException: android.widget.PopupWindow$PopupViewContainer.dispatchKeyEvent
- 解决方案:在弹出窗口前检查Activity的状态,确保窗体能在正确的时机显示。
-
token null is not for an application,AlertDialog的context是application:
android.view.WindowManager$BadTokenException: Unable to add window--token null is not for an application
- 解决方案:确保创建AlertDialog等窗体时,传入的Context来自一个Activity而非Application。
五、资源相关的异常
-
Resources NotFoundException setText给的int值错误 :
android.content.res.Resources$NotFoundException: String resource ID #0x1
-
解决方案:确保
setText()
传入的是正确的字符串或资源ID。
-
解决方案:确保
-
StackOverflowError,栈太多溢出:
StackOverflowError
- 解决方案:检查递归调用或过深的方法调用栈,优化代码结构,避免过深的嵌套。
-
UnsatisfiedLinkError,so文件没有加载到:
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/appname-1.apk"]...
-
解决方案:检查
.so
文件是否在正确的目录(jniLibs
)下,并确保有针对不同架构的版本。
-
解决方案:检查
-
InflateException之FileNotFoundException:
Caused by: android.view.InflateException: Binary XML file line #18: Error inflating class <unknown>
- 解决方案:确保布局XML文件中没有错误,所有类名和资源引用正确无误。
-
InflateException之缺少构造器:
android.view.InflateException: Binary XML file line #: Error inflating class com.example.activity1.TestButton
- 解决方案:自定义View需要实现至少一个接受Context参数的构造器。
-
InflateException之style与android:textStyle的区别:
android.view.InflateException: Binary XML file line #14: Error inflating class
-
解决方案:检查
style
属性引用的样式是否存在,并用正确的属性。
-
解决方案:检查
-
TransactionTooLargeException,Binder传递的数据大于1M:
android.view.InflateException: Binary XML file line #14: Error inflating class
- 解决方案:减少Intent或者IPC传递的数据大小,分批传输大数据。
六、系统碎片化相关的异常
-
NoSuchMethodError 方法在旧版本没有或被废弃:
java.lang.NoSuchMethodError
- 解决方案:兼容不同版本,条件判断系统版本,反射等方式避免调用不存在方法。
-
SecurityException之一:Intent中图片太大:
java.lang.SecurityException: Unable to find app for caller android.app.ApplicationThreadProxy when stopping service Intent { cmp=... }
- 解决方案:减少Intent中传递图片的大小,避免超过系统限制。
-
SecurityException之三:No permission to modify thread:
java.lang.SecurityException: No permission to modify given thread at
- 解决方案:确保应用拥有必要的权限来修改线程。
七、SQLite相关的异常
-
No transaction is active:
android.database.sqlite.SQLiteException: cannot commit–no transaction is active
- 解决方案:在数据库操作中正确开启、提交或回滚事务。
-
忘记关闭Cursor:
android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed.
- 解决方案:在数据操作完后,确保关闭Cursor来释放资源。
-
数据库被锁定:
android.database.sqlite.SQLiteDatabaseLockedException: database is locked
- 解决方案:使用同步或其他机制以防止数据库同时被多个实例或进程锁定。
-
试图再打开已经关闭的对象:
java.lang.IllegalStateException: attempt to re-open an already-closed object
- 解决方案:确保不去操作已经关闭的数据库或游标对象。
-
文件加密了或无数据库:
android.database.sqlite.SQLiteDatabaseCorruptException: file is encrypted or is not a database
- 解决方案:验证数据库文件的完整性,并确保正确地加密和解密。
-
WebView中SQLite缓存导致的崩溃:
SQLiteDiskIOException: disk I/O error
- 解决方案:优化SQLite操作,避免磁盘I/O错误。
-
android_metadata表不存在:
android.database.sqlite.SQLiteException: no such table: android_metadata
- 解决方案:确认创建数据库时是否已自动包含该表,该表通常由Android系统自动创建。
八、其他异常
-
内存溢出(OutOfMemoryException)
-
解决方案:优化内存管理,特别是图片加载管理,使用像
Glide
或Picasso
等库来帮助处理图片。
-
解决方案:优化内存管理,特别是图片加载管理,使用像
-
虚拟机发现了某种不一致或不兼容的字节码(VerifyError)
- 解决方案:确保编译的环境与运行环境一致,避免兼容性问题。
-
finalize方法执行超时
- 解决方案:避免在finalize方法内执行长时间的操作。
-
JSON解析异常(JSONException)
- 解决方案:正确处理JSON数据格式,异常捕捉并处理。
-
JSONArray初始化空指针异常(NullPointerException)
- 解决方案:确保传递的JSON字符串格式正确,且非空。
以上列出的Android开发中的异常与解决方案,旨在帮助开发者更高效地诊断并解决程序中的问题,从而提升应用的稳定性和用户体验。