Android Force Close 出现的异常原因分析及解决方法

Kita ·
更新时间:2024-11-10
· 933 次阅读

一、原因:

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 出现的异常原因分析及解决方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对软件开发网网站的支持!

您可能感兴趣的文章:C#判断字符串是否是数字(实例)C#自动判断Excel版本使用不同的连接字符串C#判断一个字符串是否包含另一个字符串的方法C#判断字符串是否存在字母及字符串中字符的替换实例C#实现判断字符串中是否包含中文的方法C#中判断、验证字符串是否为日期格式的实现代码C#中判断字符串是全角还是半角的实现代码c#中判断字符串是不是数字或字母的方法C# 判断字符串第一位是否为数字C# 判断字符串为空的几种办法asp.ent(C#)中判断空字符串的3种方法以及性能分析C#判断字符串是否是int/double(实例)



close 异常 FORCE 方法 Android

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章