日常代码的编写中,你遇到的程序崩溃肯定不会少。
空指针、转型失败、数组越界之类的,你应该都有碰到。当你碰到这些的时候,你代码中已经有写了try-catch,但是它并没有把这可能的异常捕获处理。
你也只能看着界面上跳出的“.....已停止运行”,这对你来说,你知道问题所在,但如果是一个用户角度来说,他应该就觉得,这程序好烂。
有办法捕获这种异常,并处理吗?android提供了UncaughtExceptionHandler,用于处理这个。
UncaughtExceptionHandler接口的实现
其实,实现很简单:
package com.example.uncaughtexceptionhandler_csdn;
import java.lang.Thread.UncaughtExceptionHandler;
import android.util.Log;
public class UnCaughtExecptionImp implements UncaughtExceptionHandler{
@Override
public void uncaughtException(Thread thread, Throwable ex) {
// TODO Auto-generated method stub
Log.e("tag", "error thread id is:"+thread.getId());
Log.e("tag", "Exception:"+"Name="+ex.getClass().getName()+",Message="+ex.getMessage());
}
}
我们简单实现了这个接口,并打印出当前的线程ID以及错误信息。
实现接口后,怎么应用呢?
UncaughtExceptionHandler应用
简单点的处理,就直接在程序开始执行时,比如onCreate中加入:
Thread.setDefaultUncaughtExceptionHandler(new UnCaughtExecptionImp());
这个的参数,就是UncaughtExceptionHandler接口的实现。
那你可能会问,这个设置在本界面,那其他界面出现这种未捕获的错误,这个能起效吗?
这里,我们新建一个Activity:
package com.example.uncaughtexceptionhandler_csdn;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.app.Activity;
public class OtherActivity extends Activity implements OnClickListener{
Button btnButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.other_main);
btnButton=(Button)findViewById(R.id.test2);
btnButton.setOnClickListener(this);
}
private void task() {
new Thread(new TaskRun()).start();
}
class TaskRun implements Runnable
{
@Override
public void run() {
// TODO Auto-generated method stub
//Thread.currentThread().setUncaughtExceptionHandler(new UnCaughtExecptionImp());
int f=Integer.parseInt("8");
Log.i("tag", "f="+f);
int g=Integer.parseInt("yy");
Log.i("tag", "g="+g);
int h=Integer.parseInt("10");
Log.i("tag", "h="+h);
}
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.test2:
task();
break;
default:
break;
}
}
}
我们再首界面上,设置了
Thread.setDefaultUncaughtExceptionHandler(new UnCaughtExecptionImp());
然后,点击按钮跳到OtherActivity,并且关闭MainActivity。
Intent intent=new Intent(MainActivity.this, OtherActivity.class);
startActivity(intent);
MainActivity.this.finish();
在OtherActivity中,故意放个转型错误,试试看是否崩溃。
结果表明,这个是不会崩溃的。捕获的错误会到UncaughtExceptionHandler接口的实现类中,打印出错误信息。
那如果只要这接口在特定的线程中起效,要怎么写呢?如下:
Thread.currentThread().setUncaughtExceptionHandler(new UnCaughtExecptionImp());
UncaughtExceptionHandler的细致应用
通过以上的方法,其实我们已经可以有效的避免了崩溃。那么,就这么写感觉是比较单薄的,因为我们还可以处理的更好。
1、我们可以对出问题的线程进行分辨,如果是主线程,那么我们给出友好提示,关闭或者重启主线程;
2、如果是子线程,我们其实可以只关闭子线程。主线程继续运行。这样就不必关闭程序;
3、捕获实现的设置,你可以统一放在一个全局中实现;
4、你还可以在捕获的实现中,设置好日志的详细记录,本地保存,远程发送等等;
其他的,各人根据自身的不同来做定制即可。
源码
以下是测试源码的地址:
http://download.youkuaiyun.com/detail/yangzhaomuma/9365751