123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- package com.guangzhou.haochuan.jxtv.util;
- import android.content.Context;
- import android.content.pm.PackageInfo;
- import android.content.pm.PackageManager;
- import android.os.Build;
- import android.os.Looper;
- import android.util.Log;
- import com.guangzhou.haochuan.jxtv.viewModel.ErrorDataViewModel;
- import com.ystgame.sdk.billing.api.GameInterface;
- import java.io.BufferedReader;
- import java.io.FileOutputStream;
- import java.io.FileReader;
- import java.io.PrintWriter;
- import java.io.StringWriter;
- import java.io.Writer;
- 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;
- /**
- * Created by yunhaipiaodi on 2017/10/24.
- */
- public class CrashHandler implements Thread.UncaughtExceptionHandler {
- public static final String TAG = "CrashHandler";
- //系统默认的UncaughtException处理类
- private Thread.UncaughtExceptionHandler mDefaultHandler;
- //CrashHandler实例
- private static CrashHandler INSTANCE = new CrashHandler();
- //程序的Context对象
- private Context mContext;
- //用来存储设备信息和异常信息
- private Map<String, String> infos = new HashMap<String, String>();
- //用于格式化日期,作为日志文件名的一部分
- private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
- /** 保证只有一个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);
- }
- private String getImei(){
- /*TelephonyManager mTm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
- return mTm.getDeviceId();*/
- return "";
- }
- private String getModel(){
- return Build.MODEL;
- }
- private int getAndroidVersion(){
- return Build.VERSION.SDK_INT;
- }
- /**
- * 当UncaughtException发生时会转入该函数来处理
- */
- @Override
- public void uncaughtException(Thread thread, Throwable ex) {
- if (!handleException(ex) && mDefaultHandler != null) {
- //如果用户没有处理则让系统默认的异常处理器来处理
- mDefaultHandler.uncaughtException(thread, ex);
- } else {
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- Log.e(TAG, "error : ", e);
- }
- //退出程序
- android.os.Process.killProcess(android.os.Process.myPid());
- GameInterface.finishAllDialog();
- System.exit(0);
- }
- }
- /**
- * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
- *
- * @param ex
- * @return true:如果处理了该异常信息;否则返回false.
- */
- private boolean handleException(Throwable ex) {
- if (ex == null) {
- return false;
- }
- //使用Toast来显示异常信息
- new Thread() {
- @Override
- public void run() {
- Looper.prepare();
- //Toast.makeText(mContext, "很抱歉,程序出现异常", Toast.LENGTH_LONG).show();
- Looper.loop();
- }
- }.start();
- //收集设备参数信息
- collectDeviceInfo(mContext);
- //保存日志文件
- saveCrashInfo2File(ex);
- //保存错误信息到后台云端
- saveCrashInfoToWeb(ex);
- 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 == null ? "null" : pi.versionName;
- String versionCode = pi.versionCode + "";
- infos.put("versionName", versionName);
- infos.put("versionCode", versionCode);
- }
- infos.put("apiLevel",String.valueOf(Build.VERSION.SDK_INT));
- } catch (PackageManager.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());
- //Log.d(TAG, field.getName() + " : " + field.get(null));
- } catch (Exception e) {
- //Log.e(TAG, "an error occured when collect crash info", e);
- }
- }
- }
- /**
- * 保存错误信息到后台云端
- *
- */
- private void saveCrashInfoToWeb(Throwable ex){
- String cpuAbi = "";
- String cpuAbi2 = "";
- String versionName = "";
- String versionCode = "";
- String apiLevel = "";
- String errorMessage = "";
- String ramSize = ""; //内存大小
- ramSize = getTotalRam(mContext);
- for (Map.Entry<String, String> entry : infos.entrySet()) {
- String key = entry.getKey();
- String value = entry.getValue();
- if(key.equals("CPU_ABI")){
- cpuAbi = value;
- }else if(key.equals("CPU_ABI2")){
- cpuAbi2 = value;
- }
- else if(key.equals("versionName")){
- versionName = value;
- }
- else if(key.equals("versionCode")){
- versionCode = value;
- }
- else if(key.equals("apiLevel")){
- apiLevel = 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.close();
- String result = writer.toString();
- if(result.contains("android.os.TransactionTooLargeException" ) || result.contains("pthread_create")
- || result.contains("Duplicate key in ArrayMap") || result.contains("NullPointerException")){
- return;
- }
- new ErrorDataViewModel(cpuAbi,cpuAbi2,versionName,versionCode,apiLevel,result,ramSize);
- }
- public void saveCrashInfoToWeb(String msg){
- String cpuAbi = "";
- String cpuAbi2 = "";
- String versionName = "";
- String versionCode = "";
- String apiLevel = "";
- String errorMessage = "";
- String ramSize = ""; //内存大小
- collectDeviceInfo(mContext);
- ramSize = getTotalRam(mContext);
- for (Map.Entry<String, String> entry : infos.entrySet()) {
- String key = entry.getKey();
- String value = entry.getValue();
- if(key.equals("CPU_ABI")){
- cpuAbi = value;
- }else if(key.equals("CPU_ABI2")){
- cpuAbi2 = value;
- }
- else if(key.equals("versionName")){
- versionName = value;
- }
- else if(key.equals("versionCode")){
- versionCode = value;
- }
- else if(key.equals("apiLevel")){
- apiLevel = value;
- }
- }
- String result = msg;
- if(result.contains("android.os.TransactionTooLargeException" ) || result.contains("pthread_create")
- || result.contains("Duplicate key in ArrayMap") || result.contains("NullPointerException")){
- return;
- }
- new ErrorDataViewModel(cpuAbi,cpuAbi2,versionName,versionCode,apiLevel,result,ramSize);
- }
- //返回内存大小 GB
- public String getTotalRam(Context context){
- String path = "/proc/meminfo";
- String firstLine = null;
- int totalRam = 0 ;
- try{
- FileReader fileReader = new FileReader(path);
- BufferedReader br = new BufferedReader(fileReader,8192);
- firstLine = br.readLine().split("\\s+")[1];
- br.close();
- }catch (Exception e){
- e.printStackTrace();
- }
- if(firstLine != null){
- totalRam = (int)Math.ceil((new Float(Float.valueOf(firstLine) / (1024 * 1024)).doubleValue()));
- }
- return totalRam + "GB";//返回1GB/2GB/3GB/4GB
- }
- /**
- * 保存错误信息到文件中
- *
- * @param ex
- * @return 返回文件名称,便于将文件传送到服务器
- */
- private String saveCrashInfo2File(Throwable ex) {
- 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);
- ex.printStackTrace(printWriter);
- Throwable cause = ex.getCause();
- while (cause != null) {
- cause.printStackTrace(printWriter);
- cause = cause.getCause();
- }
- printWriter.close();
- String result = writer.toString();
- sb.append(result);
- try {
- long timestamp = System.currentTimeMillis();
- String time = formatter.format(new Date());
- String fileName = "crash-" + time + "-" + timestamp + ".log";
- String path = mContext.getExternalCacheDir().getAbsolutePath();
- FileOutputStream fos = new FileOutputStream(path + fileName);
- fos.write(sb.toString().getBytes());
- fos.close();
- return fileName;
- } catch (Exception e) {
- Log.e(TAG, "an error occured while writing file...", e);
- }
- return null;
- }
- }
|