Android Log (三) 利用UncaughtExceptionHandler捕捉异常写入SD卡

            在程序运行的过程中,有时候出现异常信息,比如运行时异常时,我们可以通过UncaughtExceptionHandler这个类捕捉到异常信息,并写入sd卡中,方便后期修改bug与调试。

首先自定义CatchErrorHandler实现UncaughtExceptionHandler接口,重写uncaughtException方法,当程序出现异常时会调用此方法。具体CatchErrorHandler类如下代码

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 异常处理,异常信息写入文件
 */
public class CatchErrorHandler implements UncaughtExceptionHandler {

	public static final String TAG = "CrashErrorHandler";
	private static CatchErrorHandler catchErrorHandler = null;
	private Context mContext;
	private UncaughtExceptionHandler mDefaultHandler;
	private Map<String, String> infos = new HashMap<String, String>();
	private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH_mm_ss");
	private static String logPath ;

	/**
	 * 单例模式,保证只实例化一次
	 * @return
     */
	public static CatchErrorHandler getInstance(Context context){
		if (catchErrorHandler ==null){
			synchronized (CatchErrorHandler.class){
				if (catchErrorHandler ==null)
					catchErrorHandler = new CatchErrorHandler(context);
			}
		}
		return catchErrorHandler;
	}

	private CatchErrorHandler(Context context){
		mContext = context;
		mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
		Thread.setDefaultUncaughtExceptionHandler(this);
		logPath = Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+mContext.getPackageName()+File.separator+"errorlog";
		File file = new File(logPath);
		if (!file.exists()){
			file.mkdirs();
		}
	}


	/**
	 * 当 UncaughtException 发生时会转入该函数来处理
	 */
	@Override
	public void uncaughtException(Thread thread, Throwable throwable) {
		if (!handleException(throwable) && mDefaultHandler != null) {
			mDefaultHandler.uncaughtException(thread, throwable);
		} else {
			//系统退出,kill进程
			android.os.Process.killProcess(android.os.Process.myPid());
			System.exit(1);
		}
	}

	/**
	 * 处理异常信息
	 * @param throwable
	 */
	private boolean handleException(Throwable throwable) {
		if (throwable == null) {
			return false;
		}
		// 保存日志文件
		saveErrorInfoToFile(throwable);
		return true;
	}

	/**
	 * 保存错误信息到sd中
	 * @param throwable
	 */
	private void saveErrorInfoToFile(Throwable throwable) {
		StringBuffer sb = new StringBuffer();
		for (Map.Entry<String, String> entry : infos.entrySet()) {
			String key = entry.getKey();
			String value = entry.getValue();
			sb.append(key + "=" + value + "\n");
		}
		Writer writer = new StringWriter();
		PrintWriter printWriter = new PrintWriter(writer);
		throwable.printStackTrace(printWriter);
		Throwable cause = throwable.getCause();
		while (cause != null) {
			cause.printStackTrace(printWriter);
			cause = cause.getCause();
		}
		printWriter.close();
		String result = writer.toString();
		sb.append(result);
		try {
			String time = formatter.format(new Date());
			String fileName =logPath +File.separator + "error-"+ time + ".txt";
			File f = new File(fileName);
			if(!f.getParentFile().exists() || !f.getParentFile().isDirectory()){
				f.getParentFile().mkdirs();
			}
			if (f.exists()) {
				f.delete();
			}
			f.createNewFile();
			FileOutputStream fos = new FileOutputStream(f);
			fos.write(sb.toString().getBytes());
			fos.close();
			fos.flush();
		} catch (Exception e) {
		}
	}
}
CatchApplication的oncreate方法中实例化CatchErrorHandler,

CatchErrorHandler.getInstance(this);
接下来,我们在MainActivity中进行测试,测试代码如下,点击Test按钮后,在sd卡的项目目录的errlog目录可看到相应错误txt文件。

public class MainActivity extends AppCompatActivity {

    private TextView textView = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.test).setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        textView.setText("catch erroe");
                    }
                }
        );


    }
}
原码下载地址,原码下载



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值