android生成错误日志文件,android Crash日志写入文件

在android开发中,在用户正常使用的情况下,需要定位到用户在使用过程中出现的崩溃原因,通常会将崩溃日志写入手机本地文件中,从而有利于发现并解决问题。

我们通常会实现Thread.UncaughtExceptionHandler接口来捕获到异常信息,将异常信息写入本地文件。

1.关于权限

2.通过传入参数application进行初始化

CrashHandler crashHandler = CrashHandler.getInstance();

crashHandler.init(this);

好了,不用管了。

FileConstant.java

/**

* 【说明】:文件操作常量

*

*/

public class FileConstant {

/**

* 应用基础文件夹名称

*/

public static final String APP_BASE_DIR_NAME = "AppNamexx";

/**

* 应用日志文件夹名称

*/

public static final String APP_LOG_DIR_NAME = "Log";

/**

* 应用崩溃日志文件夹名称

*/

public static final String APP_LOG_CRASH_DIR_NAME = "Crash";

}

FileUtil.java

/**

* 【说明】:文件及文件夹工具类

*/

public class FileUtil {

private static final String TAG = "FileUtil";

/**

* 【说明】:获取手机存储空间文件夹

*

* @param context 上下文

* @return File 文件夹(/storage/emulated/0或/data/user/0/(packageName))

*/

private static File getAppDir(Context context) {

String appDir = null;

if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {

//获取外部存储路径(SD卡,在/storage/emulated/0目录下)

appDir = Environment.getExternalStorageDirectory().getAbsolutePath();

} else {

//获取内部存储路径(默认在/date/user/0/(packageName)目录下)

appDir = context.getCacheDir().getAbsolutePath();

}

File appFile = new File(appDir);

if (!appFile.exists()) {

appFile.mkdirs();

}

return appFile;

}

/**

* 【说明】:获取应用基础文件夹(应用相关文件都会存储在该目录下)

*

* @param context 上下文

* @return File 文件夹(.../AppNamexx/)

*/

public static File getBaseDir(Context context) {

File baseFile = new File(getAppDir(context), FileConstant.APP_BASE_DIR_NAME);

if (!baseFile.exists()) {

baseFile.mkdirs();

}

return baseFile;

}

/**

* 【说明】:获取应用日志文件夹

*

* @param context 上下文

* @return File 文件夹(.../AppNamexx/Log/)

*/

public static File getLogDir(Context context) {

File logFile = new File(getBaseDir(context), FileConstant.APP_LOG_DIR_NAME);

if (!logFile.exists()) {

logFile.mkdirs();

}

return logFile;

}

/**

* 【说明】:获取应用崩溃日志文件夹

*

* @param context 上下文

* @return File 文件夹(.../AppNamexx/Log/Crash/)

*/

public static File getCrashDir(Context context) {

File crashFile = new File(getLogDir(context), FileConstant.APP_LOG_CRASH_DIR_NAME);

if (!crashFile.exists()) {

crashFile.mkdirs();

}

return crashFile;

}

}

CrashHandler.java

public class CrashHandler implements Thread.UncaughtExceptionHandler{

private static final String TAG = "CrashHandler";

/*系统默认的UncaughtException处理类*/

private Thread.UncaughtExceptionHandler defaultHandler;

private Context context;

private static CrashHandler instance = new CrashHandler();

/*用来存储设备信息和异常信息*/

private Map infos = new HashMap();

private CrashHandler() {

}

public static CrashHandler getInstance() {

return instance;

}

public void init(Context context) {

this.context = context;

//获取系统默认的UncaughtException处理器

this.defaultHandler = Thread.getDefaultUncaughtExceptionHandler();

//设置该CrashHandler为程序的默认处理器

Thread.setDefaultUncaughtExceptionHandler(this);

}

/**

* 【说明】:当UncaughtException发生时会转入该方法来处理

*

*/

@Override

public void uncaughtException(Thread thread, Throwable ex) {

if (!handleException(ex) && defaultHandler != null) {

//如果用户没有处理则让系统默认的异常处理器处理

defaultHandler.uncaughtException(thread, ex);

}

}

/**

* 【说明】:自定义错误处理(包括收集错误信息,生成错误日志文件)

*/

private boolean handleException(Throwable ex) {

if (ex == null) {

return false;

}

collectDeviceInfo(context);

saveCrashInfo2File(ex);

return true;

}

/**

* 【说明】:收集应用参数信息

*/

private 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 + "";

String packageName = pi.packageName;

infos.put("versionName", versionName);

infos.put("versionCode", versionCode);

infos.put("packageName", packageName);

infos.put("appName", ctx.getString(R.string.app_name));

}

} catch (PackageManager.NameNotFoundException e) {

Log.e(TAG, "an error occurred 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 (IllegalAccessException e) {

Log.e(TAG, "an error occurred when collect crash info...", e);

}

}

}

/**

* 【说明】:保存错误信息到指定文件中

*/

private String saveCrashInfo2File(Throwable ex) {

StringBuffer sbf = new StringBuffer();

for (Map.Entry entry : infos.entrySet()) {

String key = entry.getKey();

String value = entry.getValue();

sbf.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();

sbf.append(result);

try {

//格式化日期,作为文件名的一部分

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

String time = dateFormat.format(new Date());

long timestamp = System.currentTimeMillis();

String fileName = "crash-" + time + "-" + timestamp + ".log";

if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {

File dir = FileUtil.getCrashDir(context);

String filePath = dir.getAbsoluteFile() + File.separator + fileName;

FileOutputStream fos = new FileOutputStream(filePath);

Log.e(TAG, "log file path:" + filePath);

fos.write(sbf.toString().getBytes());

fos.close();

}

return fileName;

} catch (FileNotFoundException e) {

Log.e(TAG, "an error occurred while find file...", e);

} catch (IOException e) {

Log.e(TAG, "an error occurred while writing file...", e);

}

return null;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值