1,forceclose出现原因
forceclose,意为强行关闭,当前应用程序发生了冲突
NullPointExection(空指针),IndexOutOfBoundsException(角标越界)等等一系列未捕获异常
2,避免forceclose方案
首先是尽可能的保证程序不出这些异常,如果有些异常实在不可避免而又不想让程序弹出forceclose弹窗,可以使用UncaughtExceptionHandler。。当程序出现未捕获异常时会去调用UncaughtExctionHandler中的uncaughtException方法,我们要做的就是实现UncaughtExceptionHandler类,自行处理未捕获异常,代码如下:
- import java.lang.Thread.UncaughtExceptionHandler;
- import java.util.ArrayList;
- import java.util.List;
-
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Process;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.TextView;
-
-
- public class MainActivity extends Activity implements UncaughtExceptionHandler,
- OnClickListener{
-
-
- private List<String> mList = new ArrayList<String>();
- private TextView mTv;
-
- private int pid;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
-
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- Log.i("tag", "--->>onCreate");
-
- initView();
- Thread.setDefaultUncaughtExceptionHandler(this);
-
- }
-
- @Override
- protected void onStart() {
-
- super.onStart();
- Log.i("tag", "--->>onstart");
- }
-
- @Override
- protected void onRestart() {
-
- super.onRestart();
- Log.i("tag", "--->>onRestart");
- }
-
- @Override
- protected void onResume() {
-
- super.onResume();
- Log.i("tag", "--->>onresume");
- }
-
-
-
-
- private void initView() {
- mTv = (TextView) findViewById(R.id.tv);
- mTv.setOnClickListener(this);
-
- }
-
- @Override
- public void uncaughtException(Thread arg0, Throwable arg1) {
-
- Log.i("tag", "截获到forceclose,异常原因为:" + "\n" +
- arg1.toString());
- finish();
- }
-
- @Override
- public void onClick(View arg0) {
-
- switch (arg0.getId()) {
- case R.id.tv:
- mList.get(1) ;
- break;
-
- default:
- break;
- }
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- Log.i("tag", "--》onpause");
- }
-
- @Override
- protected void onStop() {
-
- super.onStop();
- Log.i("tag", "--->onstop");
- }
-
- @Override
- protected void onDestroy() {
-
- super.onDestroy();
- Log.i("tag", "-->ondestroy");
- }
- }
接下来,看log日志的结果:

成功捕获到了异常,而且activity也退出了,可是并不是安全退出,因为当你再次点击打开apk时,发现程序无响应,出现的错误log如下:

程序加载activity超时,这涉及到activity的启动过程,大家可以参考老罗的博客,里边儿介绍的很详细
为了解决上述问题,我在uncaughtException方法里将进程杀死,杀死进程有好多中方法,在此列举一个自杀式方法
修改如下:
- @Override
- protected void onStart() {
-
- super.onStart();
- pid = android.os.Process.myPid();
- Log.i("tag", "--->>onstart");
- }
- @Override
- public void uncaughtException(Thread arg0, Throwable arg1) {
-
- Log.i("tag", "截获到forceclose,异常原因为:" + "\n" +
- arg1.toString());
- Process.killProcess(pid);
-
-
- }
其他程序未变。。
3,我们不仅可以在主线程中这么做,还可以在子线程中进行:
- private class ChildThread implements Runnable, UncaughtExceptionHandler{
-
- @Override
- public void run() {
-
- Thread.setDefaultUncaughtExceptionHandler(this);
- }
-
- @Override
- public void uncaughtException(Thread arg0, Throwable arg1) {
-
- Log.i("tag", "childThread");
- }
-
- }
然后在activity的生命周期中开启子线程,监听未捕获异常的发生