Android程序员日常开发中异常总结

Posted by 夏敏的博客 on November 6, 2016

Java异常

在 Java 中,所有的异常都有一个共同的祖先 Throwable(可抛出)。Throwable 指定代码中可用异常传播机制通过 Java 应用程序传输的任何问题的共性。

Throwable: 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。异常和错误的区别是:异常能被程序本身可以处理,错误是可以补获的,但是不建议补获处理,因此建议不处理.

平时开发中遇到的java异常很多,因为引起原因一目了然,当然也有不好解决的,比如一个简单的空指针异常你可能始终无法找到其为空的原因,甚至使用前还做了空判断。也有可能一个类型强制转换异常被报了出来可是你始终无法找到为什么出错的原因。偶先几率极低,只能catch的来了事。

  1. NullPointerException空指针引用异常
  2. ClassCastException 类型强制转换异常
  3. IllegalArgumentException 传递非法参数异常
  4. ArithmeticException 算术运算异常
  5. ArrayStoreException 向数组中存放与声明类型不兼容对象异常
  6. IndexOutOfBoundsException 下标越界异常
  7. NegativeArraySizeException 创建一个大小为负数的数组错误异常
  8. umberFormatException 数字格式异常
  9. SecurityException 安全异常 10.UnsupportedOperationException 不支持的操作异常 CSDN上更多的java异常

Android自身特性异常

  • 异常:java.lang.NullPointerException

异常原因:另一种情况使用fragment时,fragment相关布局,必须给每个view设置id,否则通过activity获得fragment的实例时会出现以上异常 解决方法:为fragment布局的每个view设置ID

  • 异常:Android中引入第三方Jar包的方法(Java.lang.NoClassDefFoundError解决办法)

1、在工程下新建lib文件夹,将需要的第三方包拷贝进来。
2、将引用的第三方包,添加进工作的build path。选中jar包->Build Path
3、(关键的一步)将lib设为源文件夹。如果不设置,则程序编译可以通过,但运行的时候,会报:选中lib文件夹->source code
java.lang.NoClassDefFoundError
Android中引入第三方Jar包的方法(java.lang.NoClassDefFoundError解决办法)

  • 异常:Caused by: android.os.TransactionTooLargeException

    导致原因是:Binder传输的数据太大
    如果Binder的参数或返回值太大,不适合的事务缓冲区,然后调用将失败,并将被抛出TransactionTooLargeException。
    解决方法: 不要将大量数据传入Binder

  • 异常:android.database.CursorWindowAllocationException:Cursor window allocation of 2048 kb failed

    导致原因:主要原因是因为使用了SimpleCursorAdapter类,其中的Cursor参数需要我们手动关闭,否则就会出现以上异常。
    解决方法:cursor.close()

  • 异常:Excessive JNI global references错误的解决方案 GREF暴增

    导致原因:vm对jni层的reference有个数限制,过多很造成VM aborting。因此每次在GREF增加到2000以上的时候就直接aborting了
    解决方法:及时回收或关闭引用

  • 异常:android.view.WindowManager$BadTokenException: Unable to add window – token

    导致原因:使用getApplicationContext()获得的Context,而必须使用Activity,因为只有一个Activity才能添加一个窗体。
    解决方法:采用当前Activity的Context

  • 异常:android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file

    导致原因:重复安装软件,导致Sqlite3打开数据库异常
    解决方法:卸载相应软件,开关机,重新安装该软件,即可以解决相关异常。

  • 异常:java.util.ConcurrentModificationException(并发操作异常)

    异常原因:ArrayList是非线程安全的,当同时在遍历和修改ArrayList时,就会出现该异常
    解决方法:使用Vector替换ArrayList,Vector是线程安全的。Vector的缺点:大量数据操作时,由于线程安全,性能比ArrayList低

  • 异常:so库文件异常(JNI层异常)

    异常原因:在Android应用层开发中,我们经常会使用so库文件。当so库文件发生异常时,我们只能在adb log中发现fatal libc这样的异常信息,仅此而已,并不能发现异常调用的逻辑关系, 这是我们就需要查看so 库异常Log信息。在Android手机的/data/tombstones 的路径下就包含了so库文件发生异常的Log信息,开发者可以查看该路径下载Log文件发现异常调用的逻辑关系。

  • android.os.Parcel.readExceptio (AIDL时异常)

    ERROR/AndroidRuntime(9435): FATAL EXCEPTION: main ERROR/AndroidRuntime(9435): java.lang.NullPointerException ERROR/AndroidRuntime(9435): at android.os.Parcel.readException(Parcel.java:1328) ERROR/AndroidRuntime(9435): at android.os.Parcel.readException(Parcel.java:1276)

通常,我们编写运行Android时,该程序若在一个进程中。若程序有缺陷,如空指针,将会产生空指针异常。 当异常发生时,其调用堆栈将会输出到log中,通过查看调用堆栈,很快可以找到问题的根源,从而解决问题。

但当我们使用Service,通过AIDL跨进程调用(或直接编写Binder IPC的跨进程调用)时,需要使用Parcel跨进程传递数据。有时这种跨进程调用会产生异常,这时问题稍显复杂一些,这种异常看Log看不出来,其实是AIDL远程服务端发生空指针异常,调用者,报的时候,不会报该服务里面的空指针.而报AIDL生成的java文件的空指针.这时候要去远程服务端查原因.

  • java.lang.RuntimeException: Method called after release()-Camera引起的异常

    Camera realse掉后,还没有置空的时候, 若此时再去使用Camera, 会报出此异常.
    因为打开camera是耗时的, 因此我们会异步打开, 若不注意线程同步问题, 容易引起该偶现Crash

  • Looper停掉了导致的异常 IllegalStateException sending message to a Handler on a dead thread

    当一个handlerThread.quit();了.依赖于这个handlerThread的looper对象的handler使用就会报出该异常.

 04-05 14:22:22.201 1028-1028/com.avatar.dialog W/MessageQueue: Handler (android.os.Handler) {410c445} sending message to a Handler on a dead thread
 java.lang.IllegalStateException: Handler (android.os.Handler) {410c445} sending message to a Handler on a dead thread
     at android.os.MessageQueue.enqueueMessage(MessageQueue.java:543)
     at android.os.Handler.enqueueMessage(Handler.java:635)
     at android.os.Handler.sendMessageAtTime(Handler.java:604)
     at android.os.Handler.sendMessageDelayed(Handler.java:574)
     at android.os.Handler.post(Handler.java:326)
     at android.robot.speech.SpeechService$2.onVolumeChanged(SpeechService.java:224)
  • java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionVie

    在使用RecyclerView时,notifyItemRangeInserted通知某个范围内数据变化时,只要范围不对便会报出这个异常,检查start-end范围即可,不用看log里面的范围,log日的position不对

  • Java.lang.IllegalArgumentException: Called attach on a child which is not detached: ViewHolder{adb21588 position=0 id=-1, oldPos=-1, pLpos:-1}

    在使用RecyclerView时,若一个Item还没有出现在屏幕上,直接notifyItemChanged() 时,就会导致这个错误

  • java.lang.IllegalStateException: Fragment ** that does not belong to this FragmentManager!

    在使用不同的包的Fragment的时候,比如一个使用的是v4包,一个使用android系统的,就会出现这个问题


### 谢谢大家阅读,如有帮助,来个喜欢或者关注吧!


本文作者:Anderson/Jerey_Jobs

简书地址 : Anderson大码渣 CSDN地址 : Jerey_Jobs的专栏 github地址 : Jerey_Jobs

作者:Anderson大码渣,欢迎关注我的简书: Anderson大码渣