summerain0的技术专栏 Android and Java Coder

自定义全局异常捕捉

2019-10-12

阅读:



可以捕捉所有的异常。

UnCatchHandler.java

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.util.Log;
import com.summerain0.music.xj.MyApplication;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/*
 * 全局异常处理器
 * class UnCatchHandler
 * author summerain0
 * email 2351602624@qq.com
 * date 2019-9-7
 */
public class UnCatchHandler implements Thread.UncaughtExceptionHandler
{
    public static final String TAG = "UnCatchHandler";
	// 单例
	private static UnCatchHandler mUnCrashHandler;
    // 上下文
	private Context mContext;

	// 私有化
    private UnCatchHandler(Context context)
	{
        mContext = context;
    }

	// 获取单例
    public static synchronized UnCatchHandler getInstance(Context context)
	{
        if (null == mUnCrashHandler)
		{
            mUnCrashHandler = new UnCatchHandler(context);
        }
        return mUnCrashHandler;
    }

	// 事件处理
	public void uncaughtException(Thread thread, Throwable throwable)
	{
		Map<String,String> map = new HashMap<String,String>();
		// 获取版本信息
		try
		{  
            PackageManager pm = mContext.getPackageManager();  
            PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);  
            if (pi != null)
			{  
                String versionName = pi.versionName == null ? "null" : pi.versionName;  
                String versionCode = pi.versionCode + "";  
                map.put("•versionName", versionName);  
                map.put("•versionCode", versionCode);  
            }  
        }
		catch (Exception e)
		{  
            map.put(TAG, "an error occured when collect package info" + e.getMessage());  
        }  

		// 记录时间
		SimpleDateFormat simple = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss.SSS");
		map.put("•time", simple.format(new Date()));

		// 设备信息
		Field[] fields = Build.class.getDeclaredFields();  
        for (Field field : fields)
		{  
            try
			{  
                field.setAccessible(true);
				// 数组处理
				Object obj = field.get(null);
				if (obj instanceof String[])
				{
					String[] list = (String[])obj;
					ArrayList<String> array = new ArrayList<String>();
					for (String str : list)
					{
						array.add(str);
					}
					map.put(field.getName(), array.toString());
				}
				else
				{
					map.put(field.getName(), obj.toString()); 
				}
                Log.d(TAG, field.getName() + " : " + field.get(null));  
            }
			catch (Exception e)
			{
                map.put(TAG, "an error occured when collect crash info" + e.getMessage());  
            }
        }  

		StringBuffer sb = new StringBuffer();  
        for (Map.Entry<String, String> entry : map.entrySet())
		{  
            String key = entry.getKey();  
            String value = entry.getValue();  
            sb.append(key + "=" + value + "\n");  
        }  

		sb.append("\n=================\n\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();  
		// 
		sb.append(writer.toString());
		//
		sb.append("\n\n========LOG========\n\n");

		ArrayList<String> array = MyApplication.getInstance().getLogArray();
		for (String str : array)
		{
			sb.append(str);
			sb.append("\n");
		}

		// 记录信息

		try
		{ 
			FileOutputStream fos = new FileOutputStream("/sdcard/1.txt");  
			fos.write(sb.toString().getBytes());  
			fos.close();
		}
		catch (Exception e)
		{}  

    }
}

MyApplication.java

public class MyApplication extends Application
{
    public static final String TAG = "MyApplication";

	// 单例
	private static MyApplication mMyApplication = null;
	// Log记录
	private ArrayList<String> mLogArray = new ArrayList<String>();
	// log模板
	private String mLogFormat = "%s\t%s\t\t%s\t\t\t\t\t%s";

	// 获取单例
    public static synchronized MyApplication getInstance()
	{
        return mMyApplication;
    }

	@Override
	public void onCreate()
	{
		super.onCreate();
		// 单例
		mMyApplication = MyApplication.this;
		// 初始化异常处理器
		UnCatchHandler handler = UnCatchHandler.getInstance(MyApplication.this);
		handler.init();
		Loger.d(TAG,"onCreate() end");
	}
	
	// 添加日志
	public void addLog(String type, String tag, String msg)
	{
		SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		String date = simple.format(new Date());
		String result = String.format(mLogFormat, date, type, tag, msg);
		mLogArray.add(result);
	}

	// 获取日志
	public ArrayList<String> getLogArray()
	{
		return mLogArray;
	}
	
}

AndroidManifest.xml

	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
	<uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <application
	...	
    android:name=".MyApplication"
...
>

Similar Posts

Comments