Android 全局错误管理

package com.wlwl.yiyuan;

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

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.os.SystemClock;
import android.util.Log;
import android.widget.Toast;

import com.wlwl.common.Config;

import com.wlwl.tools.FileX;
import com.wlwl.tools.URLX;
import com.wlwl.tools.UtilX;



@SuppressLint("SimpleDateFormat")  
public class CrashHandler implements UncaughtExceptionHandler {  
 
   public static String TAG = "MyCrash";  
   // 系统默认的UncaughtException处理类  
   private Thread.UncaughtExceptionHandler mDefaultHandler;  
 
   private static CrashHandler instance = new CrashHandler();  
   private Context mContext;  
 
   // 用来存储设备信息和异常信息  
   private Map<String, String> infos = new HashMap<String, String>();  
 
   // 用于格式化日期,作为日志文件名的一部分  
   private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");  
 
   /** 保证只有一个CrashHandler实例 */  
   private CrashHandler() {  
   }  
 
   /** 获取CrashHandler实例 ,单例模式 */  
   public static CrashHandler getInstance() {  
       return instance;  
   }  
 
   /** 
    * 初始化 
    *  
    * @param context 
    */  
   public void init(Context context) {  
       mContext = context;  
       // 获取系统默认的UncaughtException处理器  
       mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();  
       // 设置该CrashHandler为程序的默认处理器  
       Thread.setDefaultUncaughtExceptionHandler(this);  
       autoClear(5);  
   }  
 
   /** 
    * 当UncaughtException发生时会转入该函数来处理 
    */  
   @Override  
   public void uncaughtException(Thread thread, Throwable ex) {  
       if (!handleException(ex) && mDefaultHandler != null) {  
           // 如果用户没有处理则让系统默认的异常处理器来处理  
           mDefaultHandler.uncaughtException(thread, ex);  
       } else {  
           SystemClock.sleep(3000);  
           // 退出程序  
           android.os.Process.killProcess(android.os.Process.myPid());  
           System.exit(1);  
       }  
   }  
 
   /** 
    * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 
    *  
    * @param ex 
    * @return true:如果处理了该异常信息; 否则返回false. 
    */  
   private boolean handleException(Throwable ex) {  
       if (ex == null)  
           return false;  
 
       try {  
           // 使用Toast来显示异常信息  
           new Thread() {  
 
               @Override  
               public void run() {  
                   Looper.prepare();  
                   Toast.makeText(mContext, "很抱歉,程序出现异常,即将重启.",  
                           Toast.LENGTH_LONG).show();  
                   Looper.loop();  
               }  
           }.start();  
           // 收集设备参数信息  
           collectDeviceInfo(mContext);  
           // 保存日志文件  
           saveCrashInfoFile(ex);  
           SystemClock.sleep(3000);  
       } catch (Exception e) {  
           e.printStackTrace();  
       }  
 
       return true;  
   }  
 
   /** 
    * 收集设备参数信息 
    *  
    * @param ctx 
    */  
   public void collectDeviceInfo(Context ctx) {  
       try {  
           PackageManager pm = ctx.getPackageManager();  
           PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),  
                   PackageManager.GET_ACTIVITIES);  
           if (pi != null) {  
               String versionName = pi.versionName + "";  
               String versionCode = pi.versionCode + "";  
               infos.put("版本名称", versionName);  
               infos.put("版本号", versionCode);  
           }  
       } catch (NameNotFoundException e) {  
           Log.e(TAG, "an error occured when collect package info", e);  
       }  
       Field[] fields = Build.class.getDeclaredFields();  
       for (Field field : fields) {  
           try {  
               field.setAccessible(true);  
               infos.put(field.getName(), field.get(null).toString());  
           } catch (Exception e) {  
               Log.e(TAG, "an error occured when collect crash info", e);  
           }  
       }  
   }  
 
   /** 
    * 保存错误信息到文件中 
    * @param ex 
    * @return 返回文件名称,便于将文件传送到服务器 
    * @throws Exception 
    */  
   private String saveCrashInfoFile(Throwable ex) throws Exception {  
       StringBuffer sb = new StringBuffer();  
       try {  
           SimpleDateFormat sDateFormat = new SimpleDateFormat(  
                   "yyyy-MM-dd HH:mm:ss");  
           String date = sDateFormat.format(new java.util.Date());  
           sb.append("
" + date + "
");  
           for (Map.Entry<String, String> entry : infos.entrySet()) {  
               String key = entry.getKey();  
               String value = entry.getValue();  
               sb.append(key + "=" + value + "
");  
           }  
 
           Writer writer = new StringWriter();  
           PrintWriter printWriter = new PrintWriter(writer);  
           ex.printStackTrace(printWriter);  
           Throwable cause = ex.getCause();  
           while (cause != null) {  
               cause.printStackTrace(printWriter);  
               cause = cause.getCause();  
           }  
           printWriter.flush();  
           printWriter.close();  
           String result = writer.toString();  
           sb.append(result);  
 
           String fileName = writeFile(sb.toString());  
           return fileName;  
       } catch (Exception e) {  
           Log.e(TAG, "an error occured while writing file...", e);  
           sb.append("an error occured while writing file...
");  
           writeFile(sb.toString());  
       }  
       return null;  
   }  
 
   private String writeFile(String sb) throws Exception {  
       String time = formatter.format(new Date());  
       String fileName = "crash-" + time + "";  
       
       FileX.Write_Log(sb.toString(),true,fileName);  //保存日志      
       
       int verCode = UtilX.getVerCode(mContext);
       String verName = UtilX.getVerName(mContext);
       		
		String QueryStringName = "?action=seterror";
		
		Map<String,String> params = new HashMap<String,String>(); 
		params.put("error", sb.toString());
		params.put("verCode", verCode+"");
		params.put("verName", verName.toString());
		
		
		String Url = Config.URL_SetPhone + QueryStringName;
		Log.i("SetError URL ", Url);
		String aaa = URLX.submitPostData(Url, params, "utf-8");
		Log.i("SetError", aaa);
       
       
       return fileName;  
   }  
   
   
   
   
 
   public static String getGlobalpath() {  
       return Environment.getExternalStorageDirectory().getAbsolutePath()  
               + File.separator + "crash" + File.separator;  
   }  
     
   public static void setTag(String tag) {  
       TAG = tag;  
   }  
     
   /** 
    * 文件删除 
    * @param day 文件保存天数 
    */  
   public void autoClear(final int autoClearDay) {  
//       FileUtil.delete(getGlobalpath(), new FilenameFilter() {  
// 
//           @Override  
//           public boolean accept(File file, String filename) {  
//               String s = FileUtil.getFileNameWithoutExtension(filename);  
//               int day = autoClearDay < 0 ? autoClearDay : -1 * autoClearDay;  
//               String date = "crash-" + DateUtil.getOtherDay(day);  
//               return date.compareTo(s) >= 0;  
//           }  
//       });  
         
   }  
   
   
   
  
 
}  

  

package com.wlwl.yiyuan;


import com.baidu.mapapi.SDKInitializer;

import com.wlwl.tools.LocationService;

import cn.jpush.android.api.JPushInterface;
import android.app.Application;
import android.app.Service;
import android.os.Vibrator;
import android.util.Log;


/**
 * For developer startup JPush SDK
 * 
 * 一般建议在自定义 Application 类里初始化。也可以在主 Activity 里。
 */
public class MyApplication extends Application {
	
	 private static final String TAG = "JPush";
	 public LocationService locationService;
	    public Vibrator mVibrator;
	    @Override
	    public void onCreate() {    	     
	    	 
	         super.onCreate();
	         
	         try {
	        	  JPushInterface.setDebugMode(true); 	// 设置开启日志,发布时请关闭日志
	 	         JPushInterface.init(this);     		// 初始化 JPush
	 	         
	 	         locationService = new LocationService(getApplicationContext());
	 	         mVibrator =(Vibrator)getApplicationContext().getSystemService(Service.VIBRATOR_SERVICE);

	 	        CrashHandler.getInstance().init(this);   //全局错误捕捉  
	 	        
			} catch (Exception e) {
				// TODO: handle exception
			}
	         
	       
	    }
}

  

原文地址:https://www.cnblogs.com/ainidewen/p/6295641.html