|
|
@@ -1,210 +0,0 @@
|
|
|
-package com.kfzs.duanduan.services;
|
|
|
-
|
|
|
-import android.content.Context;
|
|
|
-import android.os.Environment;
|
|
|
-import android.os.Looper;
|
|
|
-import android.util.Log;
|
|
|
-import android.view.Gravity;
|
|
|
-import android.widget.Toast;
|
|
|
-
|
|
|
-import com.kfzs.duanduan.KFZSApp;
|
|
|
-import com.umeng.analytics.MobclickAgent;
|
|
|
-
|
|
|
-import java.io.File;
|
|
|
-import java.io.PrintWriter;
|
|
|
-import java.io.RandomAccessFile;
|
|
|
-import java.io.StringWriter;
|
|
|
-import java.io.Writer;
|
|
|
-import java.lang.Thread.UncaughtExceptionHandler;
|
|
|
-
|
|
|
-public class CrashHandler implements UncaughtExceptionHandler {
|
|
|
-
|
|
|
- /**
|
|
|
- * Debug Log tag
|
|
|
- */
|
|
|
- public static final String TAG = "CrashHandler";
|
|
|
-
|
|
|
- public static final boolean DEBUG = false;
|
|
|
- /**
|
|
|
- * 系统默认的UncaughtException处理类
|
|
|
- */
|
|
|
- private UncaughtExceptionHandler mDefaultHandler;
|
|
|
- /**
|
|
|
- * CrashHandler实例
|
|
|
- */
|
|
|
- private static CrashHandler INSTANCE;
|
|
|
- /**
|
|
|
- * 程序的Context对象
|
|
|
- */
|
|
|
- private Context mContext;
|
|
|
-
|
|
|
- /** 保证只有一个CrashHandler实例 */
|
|
|
-// private CrashHandler() {
|
|
|
-// }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static CrashHandler getInstance(Context ctx) {
|
|
|
- if (INSTANCE == null) {
|
|
|
- INSTANCE = new CrashHandler(ctx);
|
|
|
- }
|
|
|
- return INSTANCE;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- private CrashHandler(Context ctx) {
|
|
|
- super();
|
|
|
- this.mContext = ctx;
|
|
|
- mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
|
|
|
- Thread.setDefaultUncaughtExceptionHandler(this);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 初始化,注册Context对象, 获取系统默认的UncaughtException处理器, 设置该CrashHandler为程序的默认处理器
|
|
|
- *
|
|
|
- */
|
|
|
- public void init() {
|
|
|
- mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
|
|
|
- Thread.setDefaultUncaughtExceptionHandler(this);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 当UncaughtException发生时会转入该函数来处理
|
|
|
- */
|
|
|
- @Override
|
|
|
- public void uncaughtException(Thread thread, Throwable ex) {
|
|
|
- Log.e(TAG, ex.getMessage(), ex);
|
|
|
- if (!handleException(ex) && mDefaultHandler != null) {
|
|
|
- // 如果用户没有处理则让系统默认的异常处理器来处理
|
|
|
- mDefaultHandler.uncaughtException(thread, ex);
|
|
|
- } else {
|
|
|
- // Sleep一会后结束程序
|
|
|
- try {
|
|
|
- Thread.sleep(2000);
|
|
|
- } catch (InterruptedException e) {
|
|
|
- Log.e(TAG, "Error : ", e);
|
|
|
- }
|
|
|
-// android.os.Process.killProcess(android.os.Process.myPid());
|
|
|
-// System.exit(10);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑
|
|
|
- *
|
|
|
- * @param ex
|
|
|
- * @return true:如果处理了该异常信息;否则返回false
|
|
|
- */
|
|
|
- private boolean handleException(Throwable ex) {
|
|
|
- if (ex == null) {
|
|
|
- Log.w(TAG, "handleException --- ex==null");
|
|
|
- return true;
|
|
|
- }
|
|
|
- final String msg = ex.getLocalizedMessage();
|
|
|
- if (msg == null) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- // 使用Toast来显示异常信息
|
|
|
- new Thread() {
|
|
|
- @Override
|
|
|
- public void run() {
|
|
|
- Looper.prepare();
|
|
|
- String errorMsg = "程序出错,即将退出:\r\n" + msg;
|
|
|
- if (!KFZSApp.DEBUG) {
|
|
|
- MobclickAgent.reportError(mContext, errorMsg);
|
|
|
- }
|
|
|
- Toast toast = Toast.makeText(mContext, errorMsg, Toast.LENGTH_LONG);
|
|
|
- toast.setGravity(Gravity.CENTER, 0, 0);
|
|
|
- toast.show();
|
|
|
- Looper.loop();
|
|
|
- }
|
|
|
- }.start();
|
|
|
- // 保存错误报告文件
|
|
|
- saveCrashInfoToFile(ex);
|
|
|
- // 发送错误报告到服务器
|
|
|
- sendCrashReportsToServer(mContext);
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 在程序启动时候, 可以调用该函数来发送以前没有发送的报告
|
|
|
- */
|
|
|
- public void sendPreviousReportsToServer() {
|
|
|
- sendCrashReportsToServer(mContext);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 把错误报告发送给服务器,包含新产生的和以前没发送的.
|
|
|
- *
|
|
|
- * @param ctx
|
|
|
- */
|
|
|
- private void sendCrashReportsToServer(Context ctx) {
|
|
|
-// String msg = SharedPreferencesHelper.getValue(ctx, C.CONFIG_FILENAME, Context.MODE_PRIVATE, "exmsg");
|
|
|
-// if(msg ==null || "".equals(msg)){
|
|
|
-//
|
|
|
-// }else{
|
|
|
-//
|
|
|
-// }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 错误信息通过SharedPreferencesHelper保存到文件中
|
|
|
- *
|
|
|
- * @param ex
|
|
|
- * @return
|
|
|
- */
|
|
|
- private String saveCrashInfoToFile(Throwable ex) {
|
|
|
- Writer info = new StringWriter();
|
|
|
- PrintWriter printWriter = new PrintWriter(info);
|
|
|
- ex.printStackTrace(printWriter);
|
|
|
- Throwable cause = ex.getCause();
|
|
|
- while (cause != null) {
|
|
|
- cause.printStackTrace(printWriter);
|
|
|
- cause = cause.getCause();
|
|
|
- }
|
|
|
- String re = info.toString();
|
|
|
- printWriter.close();
|
|
|
-
|
|
|
- long timestamp = System.currentTimeMillis();
|
|
|
- String time = String.valueOf(timestamp).substring(0, String.valueOf(timestamp).length() - 3);
|
|
|
- String result = "[" + re + "#" + time + "]";
|
|
|
- String fileDir = getCacheFileDir();
|
|
|
- String fileName = "Crash_" +time +".log";
|
|
|
- String filePath = fileDir +"/" + fileName;
|
|
|
- Log.d(TAG , filePath);
|
|
|
- File file = new File(filePath);
|
|
|
- try {
|
|
|
- file.createNewFile();
|
|
|
- RandomAccessFile raf = new RandomAccessFile(file, "rwd");
|
|
|
- raf.seek(file.length());
|
|
|
- raf.write(result.getBytes());
|
|
|
- raf.close();
|
|
|
- } catch (Exception e) {
|
|
|
-
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- private String getCacheFileDir(){
|
|
|
- String cachePath = "";
|
|
|
- if (Environment.MEDIA_MOUNTED.equals(Environment
|
|
|
- .getExternalStorageState())
|
|
|
- || !Environment.isExternalStorageRemovable()) {
|
|
|
- cachePath = mContext.getExternalCacheDir().getPath();
|
|
|
- } else {
|
|
|
- cachePath = mContext.getCacheDir().getPath();
|
|
|
- }
|
|
|
-
|
|
|
- return cachePath;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-}
|