Android Force Close 出现的异常原因分析及解决方法
一、原因:
forceclose,意为强行关闭,当前应用程序发生了冲突。
NullPointExection(空指针),IndexOutOfBoundsException(下标越界),就连AndroidAPI使用的顺序错误也可能导致(比如setContentView()之前进行了findViewById()操作)等等一系列未捕获异常
二、如何避免
如何避免弹出ForceClose窗口,可以实现Thread.UncaughtExceptionHandler接口的uncaughtException方法代码如下:
publicclassMainActivityextendsActivityimplementsThread.UncaughtExceptionHandler, View.OnClickListener{ privateList<String>mList=newArrayList<String>(); privateButtonbtn; privateintpid; @Override protectedvoidonCreate(BundlesavedInstanceState){ //TODOAuto-generatedmethodstub super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i("tag","--->>onCreate"); initView(); //设置处理异常的handler Thread.setDefaultUncaughtExceptionHandler(this); } /** *初始化控件 */ privatevoidinitView(){ btn=(Button)findViewById(R.id.main_btn); btn.setOnClickListener(this); } @Override publicvoiduncaughtException(Threadarg0,Throwablearg1){ //TODOAuto-generatedmethodstub Log.i("tag","截获到forceclose,异常原因为:"+"\n"+ arg1.toString()+"Thread:"+arg0.getId()); //finish();//结束当前activity android.os.Process.killProcess(android.os.Process.myPid()); } @Override publicvoidonClick(Viewarg0){ //TODOAuto-generatedmethodstub switch(arg0.getId()){ caseR.id.main_btn: mList.get(1);//产生异常 break; default: break; } } @Override protectedvoidonPause(){ super.onPause(); Log.i("tag","--》onpause"); } @Override protectedvoidonStop(){ //TODOAuto-generatedmethodstub super.onStop(); Log.i("tag","--->onstop"); } @Override protectedvoidonDestroy(){ //TODOAuto-generatedmethodstub super.onDestroy(); Log.i("tag","-->ondestroy"); } }
再补充一句,想要哪个线程可以处理未捕获异常,Thread.setDefaultUncaughtExceptionHandler(this);这句代码都要在那个线程中执行一次
在uncaughtException方法中,第一个参数是线程,第二个参数是异常。
publicvoiduncaughtException(Threadarg0,Throwablearg1){ //TODOAuto-generatedmethodstub 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 publicvoiduncaughtException(Threadarg0,Throwablearg1){ //TODOAuto-generatedmethodstub Log.i("tag","截获到forceclose,异常原因为:"+"\n"+ arg1.toString()); android.os.Process.killProcess(android.os.Process.myPid());// }
其他程序未变。。
3,我们不仅可以在主线程中这么做,还可以在子线程中进行:
然后在activity的生命周期中开启子线程,监听未捕获异常的发生。
classMyRunnableextendsThreadimplementsThread.UncaughtExceptionHandler{ @Override publicvoidrun(){ //TODOAuto-generatedmethodstub Thread.setDefaultUncaughtExceptionHandler(this); } @Override publicvoiduncaughtException(Threadarg0,Throwablearg1){ //TODOAuto-generatedmethodstub 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-0919:02:47.73414483-14483/example.com.force_anrI/tag:--->>onCreate 08-0919:02:51.30414483-14483/example.com.force_anrI/tag:childThread:截获到forceclose,异常原因为: java.lang.IndexOutOfBoundsException:Invalidindex1,sizeis0Thread->1本线程id->1main
4.解决第三步的问题
我们重写子线程:在子线程里设置异常,同时别忘把activity中的捕获异常的代码和发生异常的代码删除。
classMyRunnableextendsThreadimplementsThread.UncaughtExceptionHandler{ inta[]; @Override publicvoidrun(){ //TODOAuto-generatedmethodstub Thread.setDefaultUncaughtExceptionHandler(this); inti=a[0];//异常 } @Override publicvoiduncaughtException(Threadarg0,Throwablearg1){ //TODOAuto-generatedmethodstub 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-0919:08:20.12416308-16308/example.com.force_anrI/tag:--->>onCreate 08-0919:08:20.12416308-16341/example.com.force_anrI/tag:childThread:截获到forceclose,异常原因为: java.lang.NullPointerException:AttempttoreadfromnullarrayThread->44829本线程id->44829Thread-44829 08-0919:08:20.25416349-16349/example.com.force_anrI/tag:--->>onCreate 08-0919:08:20.35416376-16376/example.com.force_anrI/tag:--->>onCreate 08-0919:08:20.35416376-16411/example.com.force_anrI/tag:childThread:截获到forceclose,异常原因为: java.lang.NullPointerException:AttempttoreadfromnullarrayThread->44839本线程id->44839Thread-44839
好像是尝试启动了两次,看下Thread已经变了。所以在这个方法uncaughtException(Threadarg0,Throwablearg1)中的arg0指的是发生异常的那个Thread,而不一定是uncaughtException注册的Thread。
以上所述是小编给大家介绍的AndroidForceClose出现的异常原因分析及解决方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!