android 通过UncaughtExceptionHandler处理和上传错误日志


首先 重写CrashHandler 继承自UncaughtExceptionHandler 


import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.client.HttpRequest.HttpMethod;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;


public class CrashHandler implements UncaughtExceptionHandler {
	
	public static final String TAG = "CrashHandler";
	public static final boolean DEBUG = true;
	private static CrashHandler INSTANCE;
	private Context mContext;
	private Thread.UncaughtExceptionHandler mDefaultHandler;
	private CrashHandler() {
	}
	public static CrashHandler getInstance() {
		if (INSTANCE == null)
			INSTANCE = new CrashHandler();
		return INSTANCE;
	}

	
	public void init(Context ctx) {
		mContext = ctx;
		mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
		Thread.setDefaultUncaughtExceptionHandler(this);
	}

	
	@Override
	public void uncaughtException(Thread thread, Throwable ex) {
		if (!handleException(ex) && mDefaultHandler != null) {
			// 如果用户没有处理则让系统默认的异常处理器来处理
			mDefaultHandler.uncaughtException(thread, ex);
		} else {
			

		}
	}


	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HHmmss",
			Locale.CHINA);

	/**
	 * 保存崩溃异常日志
	 * 
	 * @Title: saveExceptionInfo
	 * @TODO
	 * @since 2015-10-14
	 * @param ex
	 */
	private void saveExceptionInfo(Throwable ex) {
		File filesFile = new File(YuntiTools.LOCAL_EXCEPTION_URL);
		if (!filesFile.exists() && !filesFile.isDirectory()) {
			filesFile.mkdir();
		}
		File[] files = filesFile.listFiles();
		for (int i = 0; i < files.length; i++) {
			if (files[i].getName().contains(".log")) {
				files[i].delete();
			}
		}
		File file = new File(YuntiTools.LOCAL_EXCEPTION_URL + "/"
				+ YuntiTools.getUserName(mContext) + "_exit_"
				+ sdf.format(new Date()) + ".log");
		try {
			file.createNewFile();
			StringWriter sw = new StringWriter();

			ex.printStackTrace(new PrintWriter(sw, true));
			PackageManager packageManager = mContext.getPackageManager();
			// getPackageName()是你当前类的包名,0代表是获取版本信息
			PackageInfo packInfo;
			packInfo = packageManager.getPackageInfo(mContext.getPackageName(),
					0);
			String version = packInfo.versionName;//获取版本号
			String str = sw.toString();
			wirteString(file, "崩溃异常:异常版本" + version + "\n" + str);
			uploadLog(file);
			android.os.Process.killProcess(android.os.Process.myPid());
			System.exit(0);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 往文件写入字符串
	 * 
	 * @Title: wirteString
	 * @TODO
	 * @since 2015-10-14
	 * @param file
	 * @param context
	 */
	private void wirteString(File file, String context) {

		try {
			
			FileWriter fileWriter = new FileWriter(file);
			BufferedWriter writer = new BufferedWriter(fileWriter);
			writer.write(context);
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 上传log文件
	 * 
	 * @param f
	 *            log文件
	 */
	private void uploadLog(final File f) {
		RequestParams params = new RequestParams();
		params.addBodyParameter("logFile", f);

		HttpUtils http = new HttpUtils();
		http.send(HttpMethod.POST, URL // 上传日志的接口
				, params, null);
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		f.delete();
	}

	// add end
	/**
	 * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.  可以自定义异常处理逻辑
	 * 
	 * @param ex
	 * @return true:如果处理了该异常信息;否则返回false
	 */
	private boolean handleException(Throwable ex) {
		if (ex == null) {
			return true;
		}
	

		saveExceptionInfo(ex);
		new Thread() {
			@Override
			public void run() {
				Looper.prepare();
				Toast.makeText(mContext, "程序出错,即将重启", Toast.LENGTH_LONG)
						.show();
				Looper.loop();
			}
		}.start();

		return true;
	}
}


在application中要注册此handler


public class App extends Application {
	public void onCreate() {
	

		CrashHandler crashHandler = CrashHandler.getInstance();
	
		crashHandler.init(getApplicationContext());
	
	}
}




你可能感兴趣的:(android学习)