[安卓开发基础]捕获崩溃日志方法

CrashHandler.java

package com.landicorp.android.factorytest;

import java.io.File;
import java.io.FileOutputStream;
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.SimpleDateFormat;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;

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.Looper;
import android.util.Log;
import android.widget.Toast;

public class CrashHandler implements UncaughtExceptionHandler {

public static final String CrashFilePath = "/sdcard/FTCrash.txt";
public static final int LogFileLimit = 10;

public static final String TAG = "CrashHandler";

//系统默认的UncaughtException处理类 
private Thread.UncaughtExceptionHandler mDefaultHandler;
//CrashHandler实例
private static CrashHandler mCrash= null;
//程序的Context对象
private Context mContext;
//用来存储设备信息和异常信息
private Map<String, String> infos = new HashMap<String, String>();

//用于格式化日期,作为日志文件名的一部分
private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
private Throwable mThrowable =null;
/** 保证只有一个CrashHandler实例 */
private CrashHandler() 
{
    
}

/** 获取CrashHandler实例 ,单例模式 */
public static CrashHandler getInstance() {
    
    if(mCrash==null)
    {
        mCrash = new CrashHandler();
    }
    return mCrash;
}

/**
 * 初始化
 * 
 * @param context
 */
public void init(Context context) {
    mContext = context;
    //获取系统默认的UncaughtException处理器
    mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
    //设置该CrashHandler为程序的默认处理器
    Thread.setDefaultUncaughtExceptionHandler(this);
}

/**
 * 当UncaughtException发生时会转入该函数来处理
 */
@Override
public void uncaughtException(Thread thread, Throwable ex) 
{
    //保存异常日志到文件
    saveCrashInfo2File(ex);
    new Thread() 
    {
        @Override
        public void run() 
        {
            Looper.prepare();
            Toast.makeText(mContext, "很抱歉,程序出现异常\r\n日志保存在:"+CrashFilePath, Toast.LENGTH_LONG).show();
            Looper.loop(); 
        }
    }.start();

    try 
    {
        Thread.sleep(2000);
    } catch (Exception e) {
        // TODO: handle exception
    }
   
    android.os.Process.killProcess(android.os.Process.myPid());
    System.exit(1);
}


/**
 * 收集设备参数信息
 * @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);
        }
    } 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  返回文件名称,便于将文件传送到服务器
 */
private int saveCrashInfo2File(Throwable ex) {

    //将设备信息变成string
    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");
    }

    //递归获取全部的exception信息
    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 {
        File logFile=new File(CrashFilePath);
        if(logFile.exists())
        {
            logFile.delete();
            logFile.createNewFile();
        }
        FileOutputStream fout=new FileOutputStream(logFile,true);
        fout.write("\r\n".getBytes());
        fout.write(sb.toString().getBytes(), 0, sb.toString().length());
        fout.write("\r\n".getBytes());
        fout.close();
    } catch (Exception e) {
        // TODO: handle exception
    }
  
    return 1;
}

Comparator<File> newfileFinder = new Comparator<File>(){

    @Override
    public int compare(File x, File y) {
        // TODO Auto-generated method stub
        if (x.lastModified()>y.lastModified()) return 1;
        if (x.lastModified()<y.lastModified()) return -1;
        else return 0;
    }

};

}

使用方法:CrashHandler.getInstance().init(getApplicationContext());

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
捕获 Android 应用程序的异常并重启应用程序,可以使用 Thread.UncaughtExceptionHandler 接口。该接口用于捕获捕获的异常,并在捕获异常后重启应用程序。 下面是一个简单的示例代码,用于设置应用程序的 UncaughtExceptionHandler: ``` public class MyApplication extends Application implements Thread.UncaughtExceptionHandler { @Override public void onCreate() { super.onCreate(); Thread.setDefaultUncaughtExceptionHandler(this); } @Override public void uncaughtException(Thread thread, Throwable ex) { // 捕获异常并重启应用程序 Intent intent = new Intent(getApplicationContext(), MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(getBaseContext(), 0, intent, PendingIntent.FLAG_ONE_SHOT); AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, pendingIntent); System.exit(2); } } ``` 在上述示例代码中,我们创建了一个自定义的 Application 类,并实现 Thread.UncaughtExceptionHandler 接口。在 onCreate() 方法中,我们将当前线程的默认 UncaughtExceptionHandler 设置为该应用程序的 UncaughtExceptionHandler。 当应用程序中有未捕获的异常时,会调用 uncaughtException() 方法。在该方法中,我们创建一个 Intent 对象,用于启动 MainActivity,然后使用 PendingIntent 将该 Intent 对象封装为一个闹钟事件,并在 1 秒钟后启动该事件。最后,我们调用 System.exit() 方法退出应用程序。 这样,当应用程序中发生未捕获的异常时,应用程序将自动重启。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值