Android Force Close 出现的异常原因分析及解决方法
一、原因:
forceclose,意为强行关闭,当前应用程序发生了冲突。
nullpointexection(空指针),indexoutofboundsexception(下标越界),就连android api使用的顺序错误也可能导致(比如setcontentview()之前进行了findviewbyid()操作)等等一系列未捕获异常
二、如何避免
如何避免弹出force close窗口 ,可以实现thread.uncaughtexceptionhandler接口的uncaughtexception方法 代码如下:
public class mainactivity extends activity implements thread.uncaughtexceptionhandler, view.onclicklistener { private list<string> mlist = new arraylist<string>(); private button btn; private int pid; @override protected void oncreate(bundle savedinstancestate) { // todo auto-generated method stub super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); log.i("tag", "--->>oncreate"); initview(); //设置处理异常的handler thread.setdefaultuncaughtexceptionhandler(this); } /** * 初始化控件 */ private void initview() { btn = (button) findviewbyid(r.id.main_btn); btn.setonclicklistener(this); } @override public void uncaughtexception(thread arg0, throwable arg1) { // todo auto-generated method stub log.i("tag", "截获到forceclose,异常原因为:" + "\n" + arg1.tostring()+" thread:"+arg0.getid()); // finish();//结束当前activity android.os.process.killprocess(android.os.process.mypid()); } @override public void onclick(view arg0) { // todo auto-generated method stub switch (arg0.getid()) { case r.id.main_btn: mlist.get(1) ;//产生异常 break; default: break; } } @override protected void onpause() { super.onpause(); log.i("tag", "--》onpause"); } @override protected void onstop() { // todo auto-generated method stub super.onstop(); log.i("tag", "--->onstop"); } @override protected void ondestroy() { // todo auto-generated method stub super.ondestroy(); log.i("tag", "-->ondestroy"); } }
再补充一句,想要哪个线程可以处理未捕获异常,thread.setdefaultuncaughtexceptionhandler( this); 这句代码都要在那个线程中执行一次
在uncaughtexception方法中,第一个参数是线程,第二个参数是异常。
public void uncaughtexception(thread arg0, throwable arg1) { // todo auto-generated method stub log.i("tag", "截获到forceclose,异常原因为:" + "\n" + arg1.tostring()+" thread:"+arg0.getid()); // finish();//结束当前activity android.os.process.killprocess(android.os.process.mypid()); }
接下来,看log日志的结果:
08-0918:50:27.87410739-10739/example.com.force_anri/tag:--->>oncreate
08-0918:50:31.66410739-10739/example.com.force_anri/tag:截获到forceclose,异常原因为:
java.lang.indexoutofboundsexception:invalidindex1,sizeis0thread:1
成功捕获到了异常,而且activity也退出了,可是并不是安全退出,因为当你再次点击打开apk时,发现程序无响应。
为了解决上述问题,我在uncaughtexception方法里将进程杀死,杀死进程有好多中方法,在此列举一个自杀式方法
修改如下:
@override public void uncaughtexception(thread arg0, throwable arg1) { // todo auto-generated method stub log.i("tag", "截获到forceclose,异常原因为:" + "\n" + arg1.tostring()); android.os.process.killprocess(android.os.process.mypid()); // }
其他程序未变。。
3,我们不仅可以在主线程中这么做,还可以在子线程中进行:
然后在activity的生命周期中开启子线程,监听未捕获异常的发生。
class myrunnable extends thread implements thread.uncaughtexceptionhandler { @override public void run() { // todo auto-generated method stub thread.setdefaultuncaughtexceptionhandler(this); } @override public void uncaughtexception(thread arg0, throwable arg1) { // todo auto-generated method stub log.i("tag", "childthread:截获到forceclose,异常原因为:" + "\n" + arg1.tostring()+" thread->"+arg0.getid()+" 本线程id->"+thread.currentthread().getid()+" "+ thread.currentthread().getname()); android.os.process.killprocess(android.os.process.mypid()); } }
这里有个问题:我们明明是在子线程捕获的异常,但是怎么thread的id->1 本线程id->1,为什么线程是主线程!在下面探讨这个问题。
08-09 19:02:47.734 14483-14483/example.com.force_anr i/tag: --->>oncreate 08-09 19:02:51.304 14483-14483/example.com.force_anr i/tag: childthread:截获到forceclose,异常原因为: java.lang.indexoutofboundsexception: invalid index 1, size is 0 thread->1 本线程id->1 main
4.解决第三步的问题
我们重写子线程:在子线程里设置异常,同时别忘把activity中的捕获异常的代码和发生异常的代码删除。
class myrunnable extends thread implements thread.uncaughtexceptionhandler { int a[]; @override public void run() { // todo auto-generated method stub thread.setdefaultuncaughtexceptionhandler(this); int i = a[0];//异常 } @override public void uncaughtexception(thread arg0, throwable arg1) { // todo auto-generated method stub log.i("tag", "childthread:截获到forceclose,异常原因为:" + "\n" + arg1.tostring()+" thread->"+arg0.getid()+" 本线程id->"+thread.currentthread().getid()+" "+ thread.currentthread().getname()); android.os.process.killprocess(android.os.process.mypid()); } }
在启动程序看到下面的log:
08-09 19:08:20.124 16308-16308/example.com.force_anr i/tag: --->>oncreate 08-09 19:08:20.124 16308-16341/example.com.force_anr i/tag: childthread:截获到forceclose,异常原因为: java.lang.nullpointerexception: attempt to read from null array thread->44829 本线程id->44829 thread-44829 08-09 19:08:20.254 16349-16349/example.com.force_anr i/tag: --->>oncreate 08-09 19:08:20.354 16376-16376/example.com.force_anr i/tag: --->>oncreate 08-09 19:08:20.354 16376-16411/example.com.force_anr i/tag: childthread:截获到forceclose,异常原因为: java.lang.nullpointerexception: attempt to read from null array thread->44839 本线程id->44839 thread-44839
好像是尝试启动了两次,看下thread已经变了。所以在这个方法uncaughtexception(thread arg0, throwable arg1)中的arg0指的是发生异常的那个thread,而不一定是uncaughtexception注册的thread。
以上所述是小编给大家介绍的android force close 出现的异常原因分析及解决方法,希望对大家有所帮助
上一篇: 缓冲流(处理流)
下一篇: Java IO流之NIO和缓冲区
推荐阅读
-
Android Force Close 出现的异常原因分析及解决方法
-
Android Force Close 出现的异常原因分析及解决方法
-
win7系统检查设备管理出现PCI Device驱动未安装的原因分析及解决方法
-
总结Java中常见的异常,出现异常的原因及各种解决方法
-
电脑开机出现异常提示keyboard not found的故障原因及解决方法
-
MySQL 出现错误1418 的原因分析及解决方法
-
MySQL 出现错误1418 的原因分析及解决方法
-
win8.1系统开机出现花屏怎么办?win8.1系统开机出现花屏的故障原因分析及解决方法
-
Win10系统优酷播放器出现绿屏的两种原因分析及解决方法图文教程
-
win7系统电脑开机输入登录账号密码后出现黑屏的原因分析及两种解决方法