在写Android程序时,经常碰到在模拟器和调试器中无法捕捉的exception。有时自己运行好好的程序到了其他机器上就出现了问题。虽然Google Play有错误堆栈上传功能,但是没有办法把整个运行的过程记录下来。为此我写了一个LogDog类来试图解决这个问题。


import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.HashSet;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.util.Log;public class LogDog implements UncaughtExceptionHandler {public static String           TAG = "LogDog";private static HashSet    _tags = new HashSet();private static boolean           _debug = false;static {// add tags to be captured_tags.add(PDFMaster.TAG);_tags.add(RecentlyUsedActivity.TAG);_tags.add(DB.TAG);}public static LogDog instance() {return _instance;}public static void i(String tag, String message) {if(_debug) {Log.i(tag, message);return;}PrintWriter writer = _instance.getWriter();if(writer != null && _tags.contains(tag)) {_instance._writer.println("i:" + tag + ":" + message);}}public static void e(String tag, String message) {if(_debug) {Log.i(tag, message);return;}PrintWriter writer = _instance.getWriter();if(writer != null && _tags.contains(tag)) {_instance._writer.println("e" + tag + ":" + message);}}public static void w(String tag, String message) {if(_debug) {Log.i(tag, message);return;}PrintWriter writer = _instance.getWriter();if(writer != null && _tags.contains(tag)) {_instance._writer.println("w" + tag + ":" + message);}}public void init(Context context) {_context = context;_fileName = _context.getString(R.string.app_name) + ".log";_defaultHandler = Thread.getDefaultUncaughtExceptionHandler();Thread.setDefaultUncaughtExceptionHandler(this);}public void close() {if(_writer != null) {_writer.close();_writer = null;}}// privateprivate static LogDog                    _instance = new LogDog();private static final String           PATH =Environment.getExternalStorageDirectory().getPath() + "/log";private Context                          _context;private String                         _fileName;private Thread.UncaughtExceptionHandler   _defaultHandler;private PrintWriter                     _writer = null;private LogDog() {}private PrintWriter getWriter() {if(_writer != null)return _writer;// check if we have SD cardif (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {//Log.w(TAG, "sdcard unmounted,skip dump exception");return null;}File dir = new File(PATH);if (!dir.exists()) {dir.mkdirs();}File file = new File(PATH + "/" + _fileName);try {_writer = new PrintWriter(new BufferedWriter(new FileWriter(file)));} catch (IOException e) {//Log.e(TAG, "Failed to open " + PATH + "/" + FILE_NAME);_writer = null;}return _writer;}@Overridepublic void uncaughtException(Thread thread, Throwable ex) {// first display a toast messagenew Thread() {@Overridepublic void run() {Looper.prepare();PDFMarkerApp.instance().showToast("Sorry for the trouble, dumping uncaught exeption to SD card");}}.start();try {dump(ex);} catch (Exception e) {//Log.e(TAG, "Failed to dump because " + e.getMessage());e.printStackTrace();}if (_defaultHandler != null) {  _defaultHandler.uncaughtException(thread, ex);  } else {// sleep so the toast can have time to displaytry {Thread.sleep(3000);} catch (InterruptedException e) {}android.os.Process.killProcess(android.os.Process.myPid());  }}private void dump(Throwable ex) throws IOException, NameNotFoundException {PrintWriter writer = _instance.getWriter();if(writer == null)return;long current = System.currentTimeMillis();String time = new SimpleDateFormat("yyyyMMdd.HHmmss").format(new Date(current));_writer.println(time);PackageManager pm = _context.getPackageManager();PackageInfo pi = pm.getPackageInfo(_context.getPackageName(), PackageManager.GET_ACTIVITIES);_writer.print("App Version: ");_writer.print(pi.versionName);_writer.print('_');_writer.println(pi.versionCode);  _writer.print("OS Version: ");_writer.print(Build.VERSION.RELEASE);_writer.print("_");_writer.println(Build.VERSION.SDK_INT);_writer.print("Vendor: ");_writer.println(Build.MANUFACTURER);_writer.print("Model: ");_writer.println(Build.MODEL);_writer.print("CPU ABI: ");_writer.println(Build.CPU_ABI);_writer.println();ex.printStackTrace(_writer);close();File file = new File(PATH + "/" + _fileName);File file2 = new File(PATH + "/" + _fileName + "." + time + ".txt");file.renameTo(file2);}}

在使用时所有的日志就全记录在一个文件中,直到最后的异常。每次异常都会单独被记录在一个文件中,连带所有需要知道的信息。要是正常运行,这个文件下次就被覆盖,不会造成空间问题。要是调试,只要把_debug改一下,所有日志就在LogCat中显示出来,非常方便。

转载于:https://blog.51cto.com/bluefeather/1606120

Android 之 LogDog相关推荐

  1. Unity5.6+ 导出Android 应用程序apk的环境配置及导出过程

    首先下载并安装安卓SDK和java的JDK 安卓sdk下载: http://www.android-studio.org/ 也可以在这下载: 链接:http://pan.baidu.com/s/1bp ...

  2. Android 的NDK的Makefile编写

    Android.mk 是google根据Linux GNU Makefile精简编译脚本.具体来说:这就是GNU Makefile的一小部分. 举一个简单例子: LOCAL_PATH := $(cal ...

  3. Android Animation (安卓动画)概念简介

    Android Animation Android 四种动画分别为逐帧动画和补间动画.属性动画.过渡动画: Frame Animation (逐帧动画) 实现方式:xml 和 Java代码 图片跳转的 ...

  4. 基于Android和SpringBoot的购物App

    (Shopping)购物应用商城 本软件使用Android和SpringBoot.JavaWeb技术实现:并结合百度LBS平台的SDK.支付宝App支付客户端SDK.MobTech的ShareSDK: ...

  5. Android数据持久化:SharePreference

    SharePreference:作为Android数据持久化的一种,具有一定的便捷性,适合存储一些体积小的数据. 存储数据方式:键值对的方式,类似于Map: 利用SharePreference.Edi ...

  6. Android数据持久化:文件存储

    数据持久化: 数据可分为瞬时数据和关键数据.保存在内存之中的数据是瞬时数据,而对于一些关键性数据,后期需要持续使用的,应当保存在存储设备中: 持久化保存方式: 文件存储.SharePreference ...

  7. Android Studio中RecycerView依赖库加载问题

    依赖包导入思考: 参考资料:recycleview导包问题 打开修改本项目中的build.gradle; 切勿着急添加包,应当提前查看其中的版本号(因为加载的v7包要和其版本保持一致性): 例如: 因 ...

  8. Android布局优化之include、merge、ViewStub

    include:引入重复使用的相同布局 merge:减少include布局的层级,将子元素直接添加到merge标签的parent中 ViewStub:其实就是一个宽高都为0的一个View,它默认是不可 ...

  9. Android动画之帧动画和补间动画

    Android系统提供三种动画:帧动画.补间动画和属性动画.这里先分析总结帧动画和补间动画. FrameAnimation 帧动画,通俗来说就是按照图片动作顺序依次播放来形成动画,创建帧动画可以用 x ...

最新文章

  1. Vim 项目重要维护者去世,Vim 之父以 Vim 9 悼念挚友
  2. 分享一个帮助你自定义标签并且兼容现代浏览器的javascript类库 : X-tag
  3. 《乐高EV3机器人搭建与编程》——2.2 颜色设计
  4. linux 开机提示 Kernel panic - not syncing: Attempted to kill init! 解决方案
  5. 搜索引擎大调整:百度出“惊雷算法”后360搜索又将上线“八戒算法”
  6. 【ABAP】根据Tcode查找后台IMG路径
  7. java 逗号运算符_Java 运算符
  8. 修改JBOSS服务器的端口号
  9. python pprint_【Python】输入和输出
  10. DataTable的计算功能(转)
  11. java点击图片发出声音_Java 中图片和声音文件的加载
  12. java 文件描述符_文件描述符了解一下
  13. 修改IP4属性时,针对闪退问题的解决方法
  14. iOS远程真机之iTunes与iPhone的通信协议usbmuxd解析
  15. 如何调换手机桌面位置_手机桌面很乱怎么整理?简单七招让你效率更高!
  16. InfoPath 2007 --来自microsoft.com
  17. C语言中格式输出二进制的两种方法
  18. Laravel Excel导出xls乱码
  19. 华三防火墙透明模式典型组网配置实例
  20. Xilinx Arch PCIE卡

热门文章

  1. vba查找数据并返回单元格地址_VBA积木代码中实现反向多值查找、LIKE模糊查找...
  2. 动态顺序字符串基本操作实验_掌握套路,你也会用动态规划
  3. html让下拉条消失,CSS 实现隐藏滚动条同时又可以滚动
  4. pytorch 常见报错
  5. python列表的append和extend
  6. 【BERT】BERT模型压缩技术概览
  7. 【NLP-NER】命名实体识别中最常用的两种深度学习模型
  8. 【AI不惑境】移动端高效网络,卷积拆分和分组的精髓
  9. 中国无碳复写纸行业竞争现状与运行态势研究报告2022年
  10. 全球及中国磁滑轮行业规模预测与供应规划研究报告2022版