安卓程序运行中突然崩溃的时候打印日志到本地
来源:互联网 发布:手机淘宝货到付款骗局 编辑:程序博客网 时间:2024/06/01 07:24
转载自:http://blog.sina.com.cn/s/blog_6a528c550102vc1a.html Yocn博客
我们在开发android应用的时候经常有这样一个情景:程序用着用着在某个地方崩溃了,每次的情况都不尽相同,这时候我们没有在电脑旁边,有电脑的时候去看代码的时候总是觉着哪儿都不可能出错。这时候我们就想如果我们能得到异常退出时候的log信息就好了。
这时候下面这一段代码就可能相当有用了:
package com.test.application;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
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.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.util.Log;
import android.widget.Toast;
import com.duole.fm.utils.Constants;
public class CrashHandler implements UncaughtExceptionHandler {
// 系统默认的UncaughtException处理类private Thread.UncaughtExceptionHandler mDefaultHandler;// CrashHandler实例private static CrashHandler instance;// 程序的Context对象private Context mContext;// 用来存储设备信息和异常信息private Map infos = new HashMap();// 用于格式化日期,作为日志文件名的一部分private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");private CrashHandler() {}public static CrashHandler getInstance() { if (instance == null) instance = new CrashHandler(); return instance;}public void init(Context context) { mContext = context; Log.e(Constants.TAG, "error : "); // 获取系统默认的UncaughtException处理器 mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); // 设置该CrashHandler为程序的默认处理器 Thread.setDefaultUncaughtExceptionHandler(this);}@Overridepublic 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(Constants.TAG, "error : ", e); } // 退出程序 android.os.Process.killProcess(android.os.Process.myPid()); System.exit(1); }}private boolean handleException(Throwable ex) { if (ex == null) { return false; } // 收集设备参数信息 collectDeviceInfo(mContext); // 使用Toast来显示异常信息 new Thread() { @Override public void run() { Looper.prepare(); Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_SHORT).show(); Looper.loop(); } }.start(); // 保存日志文件 try { saveCatchInfo2File(ex); } catch (Exception e) { e.printStackTrace(); } return true;}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(Constants.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(Constants.TAG, field.getName() + " : " + field.get(null)); } catch (Exception e) { Log.e(Constants.TAG, "an error occured when collect crash info", e); } }}private String saveCatchInfo2File(Throwable ex) { StringBuffer sb = new StringBuffer(); for (Map.Entry 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"; if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { String path = Constants.SDPATH + "/crash/"; File dir = new File(path); if (!dir.exists()) { dir.mkdirs(); } FileOutputStream fos = new FileOutputStream(path + fileName); fos.write(sb.toString().getBytes()); // 发送给开发人员 sendCrashLog2PM(path + fileName); fos.close(); } return fileName; } catch (Exception e) { Log.e(Constants.TAG, "an error occured while writing file...", e); } return null;}private void sendCrashLog2PM(String fileName) { if (!new File(fileName).exists()) { Toast.makeText(mContext, "日志文件不存在!", Toast.LENGTH_SHORT).show(); return; } FileInputStream fis = null; BufferedReader reader = null; String s = null; try { fis = new FileInputStream(fileName); reader = new BufferedReader(new InputStreamReader(fis, "GBK")); while (true) { s = reader.readLine(); if (s == null) break; // 由于目前尚未确定以何种方式发送,所以先打出log日志。 Log.i("info", s.toString()); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 关闭流 try { reader.close(); fis.close(); } catch (IOException e) { e.printStackTrace(); } }}
}
在Application里面加上下面这句:
CrashHandler catchHandler = CrashHandler.getInstance();
catchHandler.init(getApplicationContext());
这样就可以随时得到crash时候的log信息了
- 安卓程序运行中突然崩溃的时候打印日志到本地
- 安卓程序崩溃时的错误信息log至本地
- 将程序运行信息打印到 系统日志
- 将崩溃日志存到本地
- android日志打印库,可以配置打印到本地,可以配置打印格式化的日志
- ListView重新可见的时候突然出现了崩溃了。。。。。
- 将运行信息打印日志到文件中
- 在开发系统时候运行程序突然报出“WebDev.WebServer40.exe已停止工作”的错误
- 安卓(android)崩溃日志的抓取
- android 错误日志打印到本地
- android 错误日志打印到本地
- 在vs中用tesseract进行ocr的时候运行到init时崩溃问题
- 【安卓笔记】崩溃日志收集
- 安卓模拟器中运行C程序
- Android 异常崩溃日志,捕捉并保存到本地
- 当程序崩溃的时候怎么办 iphone
- 当程序崩溃的时候怎么办 iphone
- 当程序崩溃的时候怎么办 iphone
- node与ES6系列4——class
- jdk配置正确但是tomcat服务器启动时一闪而过
- 从Java回调机制分析Android动态加载布局过程中出现的IllgalStateException
- socat的安装与使用
- What happens when you run a container?
- 安卓程序运行中突然崩溃的时候打印日志到本地
- windows DLL动态连接库文件的实现和应用
- 基于 intel MKL 的对称矩阵特征值求解器
- 《java从入门到精通》-笔记
- linux 设置用户id
- 了解Java中的线程
- 圆形图片CircleImageView
- Tomcat域名或IP地址访问方式配置方法
- gdb调试时的问题Missing separate debuginfos, use: debuginfo-install glibc-XXX