赞
踩
安卓5.0及以后的系统 在 UncaughtExceptionHandler 方法中 开启线程 有可能会 使线程中的 Runnable 不执行,原因据说uncaughtException方法执行完成后ART环境就shutdown了
真正原因如下:
调用网络发送部分的策略是启动一个新的Service
组件,读取持久化存储的数据,然后发送到服务端。至于为什么不直接开一个新的thread调用这个发送操作是有原因的。
ART
替代Dalvik
开始,在shutdown的过程中不能开新的thread,否则又会跑出异常java.lang.InternalError: Thread starting during runtime shutdown
。那么bugly 在5.0之后的系统也能正常使用,可能也是开启了新的上报进程来处理的。所以网上流传的那一套安卓UncaughtExceptionHandler 机制已经不再适用了。fuck
可参考:https://my.oschina.net/azard/blog/614843
什么是 ACRA? 请移步这里, 应该是一个 国外版的专注于Android APP的 bugly系统
https://github.com/ACRA/acra
===================================================================================================
问题描述与分析:
为了获取Crash日志,项目中实现了UncaughtExceptionHandler接口对未知异常进行捕获并上传到服务器中,同时停止App运行。在Android5.0以下系统一直未出现过问题,但是突然发现在Android 5.0以上的机器中这段代码出现了java.lang.InternalError: Thread starting during runtime shutdown(更多异常信息见最后部分的附录),在stackoverflow中得到了一些帮助:这个问题是因为线程开启的太晚了!
什么时候开启线程才算得上“太晚了”呢? 在我的项目中UncaughtExceptionHandler实现类捕获到异常时(也就是UncaughtExceptionHandler接口的uncaughtException方法执行时),开启了一个线程用于上传崩溃日志,而在线程中上传崩溃日志时创建了HttpClient发送网络请求。HttpClient创建时设置了ThreadSafeClientConnManager来管理连接,而在ThreadSafeClientConnManager的源码中又一次开启了线程!也就是说,uncaughtException方法执行时在开启的线程中又开启了新的线程,这样可能会导致uncaughtException方法在执行完成时,“线程中的线程”才start(),而据说uncaughtException方法执行完成后ART环境就shutdown了(uncaughtException方法结束时ART是否会真的shutdown,这一点有待考证,笔者也仅是从其他非官方资料中得知),这种情况下就会抛出java.lang.InternalError: Thread starting during runtime shutdown。
为了验证这个问题,编写了一段简单的代码:实现UncaughtExceptionHandler的uncaughtException方法,在uncaughtException方法中开启一个线程,在这个线程中再开一线程,同时在MainActivity中故意制造一个异常发生,此时果然会出现java.lang.InternalError: Thread starting during runtime shutdown(并不是每次都出现,因为如果uncaughtException方法执行结束之前,两个线程都完成start(),此问题就不会出现)。
解决方法:
避免在uncaughtException方法中出现线程嵌套:针对我的项目,不再去在线程中创建HttpClient(因为HttpClient创建时还会开启线程,这就造成了线程中再次开启线程),而是先创建HttpClient对象,再在线程中使用HttpClient对象。这样就可以确保uncaughtException方法结束之前HttpClient已经被创建,HttpClient中开启线程也就不会有问题。
附异常信息:
java.lang.InternalError: Thread starting during runtime shutdown at java.lang.Thread.nativeCreate(Native Method) at java.lang.Thread.start(Thread.java:1042) at org.apache.http.impl.conn.tsccm.AbstractConnPool.enableConnectionGC(AbstractConnPool.java:140) at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.createConnectionPool(ThreadSafeClientConnManager.java:120) at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.<init>(ThreadSafeClientConnManager.java:98) at
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。