1. 1,将运行时异常捕获并存到手机SD卡上
  1. 可以直接使用logcat 命令Runtime.getRuntime().exec("logcat -f "+ file.getAbsolutePath());指定文件路径就可以了
  1. package com.hai.logcat;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.DataInputStream;
  5. import java.io.File;
  6. import java.io.FileNotFoundException;
  7. import java.io.FileOutputStream;
  8. import java.io.IOException;
  9. import java.io.InputStream;
  10. import java.io.InputStreamReader;
  11. import java.util.List;
  12.  
  13. import android.app.ActivityManager;
  14. import android.app.ActivityManager.RunningAppProcessInfo;
  15. import android.app.Service;
  16. import android.content.Intent;
  17. import android.os.Environment;
  18. import android.os.IBinder;
  19. import android.os.Looper;
  20. import android.util.Log;
  21. import android.widget.Toast;
  22.  
  23. public class MyLogcat extends Service {
  24. Thread thread;
  25. boolean readlog = true;
  26.  
  27. @Override
  28. public IBinder onBind(Intent intent) {
  29. return null;
  30. }
  31.  
  32. @Override
  33. public void onCreate() {
  34. super.onCreate();
  35. Log.d("hhp", "onCreate");
  36. thread = new Thread(new Runnable() {
  37. @Override
  38. public void run() {
  39. log2();//个人觉得这个方法更实用
  40. }
  41. });
  42. }
  43.  
  44. @Override
  45. public void onStart(Intent intent, int startId) {
  46. thread.start();
  47. Log.d("hhp", "onStart");
  48. super.onStart(intent, startId);
  49. }
  50.  
  51. /**
  52. * 方法1
  53. */
  54. private void log2() {
  55. Log.d("hhp", "log2 start");
  56. String[] cmds = { "logcat", "-c" };
  57. String shellCmd = "logcat -v time -s *:W "; // adb logcat -v time *:W
  58. Process process = null;
  59. Runtime runtime = Runtime.getRuntime();
  60. BufferedReader reader = null;
  61. try {
  62. runtime.exec(cmds).waitFor();
  63. process = runtime.exec(shellCmd);
  64. reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
  65. String line = null;
  66. while ((line = reader.readLine()) != null) {
  67. if (line.contains(String.valueOf(android.os.Process.myPid()))) {
  68. // line = new String(line.getBytes("iso-8859-1"), "utf-8");
  69. writeTofile(line);
  70. }
  71. }
  72. } catch (Exception e) {
  73. e.printStackTrace();
  74. }
  75. Log.d("hhp", "log2 finished");
  76. }
  77.  
  78. /**
  79. * 方法2
  80. */
  81. private void log() {
  82. Log.d("hhp", "log start");
  83. String[] cmds = { "logcat", "-c" };
  84. String shellCmd = "logcat -v time -s *:W ";// //adb logcat -v time *:W
  85. Process process = null;
  86. InputStream is = null;
  87. DataInputStream dis = null;
  88. String line = "";
  89. Runtime runtime = Runtime.getRuntime();
  90. try {
  91. runtime.exec(cmds);
  92. process = runtime.exec(shellCmd);
  93. is = process.getInputStream();
  94. dis = new DataInputStream(is);
  95. // String filter = GetPid();
  96. String filter = android.os.Process.myPid() + "";
  97. while ((line = dis.readLine()) != null) { //这里如果输入流没断,会一直循环下去。
  98. line = new String(line.getBytes("iso-8859-1"), "utf-8");
  99. if (line.contains(filter)) {
  100. int pos = line.indexOf(":");
  101. Log.d("hhp2", line + "");
  102. writeTofile(line);
  103. }
  104. }
  105. } catch (Exception e) {
  106. }
  107. Log.d("hhp", "log finished");
  108. }
  109.  
  110. private void writeTofile(String line) {
  111. String content = line + "\r\n";
  112. File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
  113. + "/logcat/myLog.txt");
  114. if (!file.exists()) {
  115. try {
  116. file.createNewFile();
  117. } catch (Exception e) {
  118. e.printStackTrace();
  119. }
  120. }
  121. FileOutputStream fos;
  122. try {
  123. fos = new FileOutputStream(file, true);
  124. fos.write(content.getBytes());
  125. fos.flush();
  126. fos.close();
  127. } catch (Exception e) {
  128. e.printStackTrace();
  129. }
  130.  
  131. }
  132.  
  133. @Override
  134. public void onDestroy() {
  135. super.onDestroy();
  136. stopSelf();
  137. }
  138. }

2,如果出现运行时异常,可以有一个友好的提示避免直接推出应用,还可以获取异常信息

  1. package com.hai.logcat;
  2.  
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import java.io.PrintWriter;
  6. import java.io.StringWriter;
  7. import java.io.Writer;
  8. import java.lang.Thread.UncaughtExceptionHandler;
  9. import java.lang.reflect.Field;
  10. import java.text.DateFormat;
  11. import java.text.SimpleDateFormat;
  12. import java.util.Date;
  13. import java.util.HashMap;
  14. import java.util.Map;
  15.  
  16. import android.content.Context;
  17. import android.content.pm.PackageInfo;
  18. import android.content.pm.PackageManager;
  19. import android.content.pm.PackageManager.NameNotFoundException;
  20. import android.os.Build;
  21. import android.os.Environment;
  22. import android.os.Looper;
  23. import android.util.Log;
  24. import android.widget.Toast;
  25.  
  26. public class CrashHandler implements UncaughtExceptionHandler {
  27.  
  28. public static final String TAG = "CrashHandler";
  29.  
  30. // 系统默认的UncaughtException处理类
  31. private Thread.UncaughtExceptionHandler mDefaultHandler;
  32. // CrashHandler实例
  33. private static CrashHandler INSTANCE = new CrashHandler();
  34. // 程序的Context对象
  35. private Context mContext;
  36. // 用来存储设备信息和异常信息
  37. private Map<String, String> infos = new HashMap<String, String>();
  38.  
  39. // 用于格式化日期,作为日志文件名的一部分
  40. private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ");
  41.  
  42. /** 保证只有一个CrashHandler实例 */
  43. private CrashHandler() {
  44. }
  45.  
  46. /** 获取CrashHandler实例 ,单例模式 */
  47. public static CrashHandler getInstance() {
  48. return INSTANCE;
  49. }
  50.  
  51. /**
  52. * 初始化
  53. *
  54. * @param context
  55. */
  56. public void init(Context context) {
  57. mContext = context;
  58. // 获取系统默认的UncaughtException处理器
  59. mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
  60. // 设置该CrashHandler为程序的默认处理器
  61. Thread.setDefaultUncaughtExceptionHandler(this);
  62. }
  63.  
  64. /**
  65. * 当UncaughtException发生时会转入该函数来处理
  66. */
  67. @Override
  68. public void uncaughtException(Thread thread, Throwable ex) {
  69. if (!handleException(ex) && mDefaultHandler != null) {
  70. // 如果用户没有处理则让系统默认的异常处理器来处理
  71. mDefaultHandler.uncaughtException(thread, ex);
  72. } else {
  73. try {
  74. Thread.sleep(3000);
  75. } catch (InterruptedException e) {
  76. Log.e(TAG, "error : ", e);
  77. }
  78. // 退出程序
  79. android.os.Process.killProcess(android.os.Process.myPid());
  80. System.exit(1);
  81. }
  82. }
  83.  
  84. /**
  85. * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
  86. *
  87. * @param ex
  88. * @return true:如果处理了该异常信息;否则返回false.
  89. */
  90. private boolean handleException(final Throwable ex) {
  91. if (ex == null) {
  92. return false;
  93. }
  94. // 使用Toast来显示异常信息
  95. new Thread() {
  96. @Override
  97. public void run() {
  98. Looper.prepare();
  99. ex.printStackTrace();
  100. Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_LONG).show();
  101. Looper.loop();
  102. }
  103. }.start();
  104. // 收集设备参数信息
  105. collectDeviceInfo(mContext);
  106. // 保存日志文件
  107. saveCrashInfo2File(ex);
  108. return true;
  109. }
  110.  
  111. /**
  112. * 收集设备参数信息
  113. *
  114. * @param ctx
  115. */
  116. public void collectDeviceInfo(Context ctx) {
  117. try {
  118. PackageManager pm = ctx.getPackageManager();
  119. PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
  120. if (pi != null) {
  121. String versionName = pi.versionName == null ? "null" : pi.versionName;
  122. String versionCode = pi.versionCode + "";
  123. infos.put("versionName", versionName);
  124. infos.put("versionCode", versionCode);
  125. }
  126. } catch (NameNotFoundException e) {
  127. Log.e(TAG, "an error occured when collect package info", e);
  128. }
  129. Field[] fields = Build.class.getDeclaredFields();
  130. for (Field field : fields) {
  131. try {
  132. field.setAccessible(true);
  133. infos.put(field.getName(), field.get(null).toString());
  134. Log.d(TAG, field.getName() + " : " + field.get(null));
  135. } catch (Exception e) {
  136. Log.e(TAG, "an error occured when collect crash info", e);
  137. }
  138. }
  139. }
  140.  
  141. /**
  142. * 保存错误信息到文件中
  143. *
  144. * @param ex
  145. * @return 返回文件名称,便于将文件传送到服务器
  146. */
  147. private String saveCrashInfo2File(Throwable ex) {
  148. StringBuffer sb = new StringBuffer();
  149. for (Map.Entry<String, String> entry : infos.entrySet()) {
  150. String key = entry.getKey();
  151. String value = entry.getValue();
  152. sb.append(key + "=" + value + "\n");
  153. }
  154.  
  155. Writer writer = new StringWriter();
  156. PrintWriter printWriter = new PrintWriter(writer);
  157. ex.printStackTrace(printWriter);
  158. Throwable cause = ex.getCause();
  159. while (cause != null) {
  160. cause.printStackTrace(printWriter);
  161. cause = cause.getCause();
  162. }
  163. printWriter.close();
  164. String result = writer.toString();
  165. String time = formatter.format(new Date());
  166. sb.append(time + result);
  167. try {
  168. long timestamp = System.currentTimeMillis();
  169. String fileName = "crash.log";
  170. if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
  171. String path =Environment.getExternalStorageDirectory().getAbsolutePath()+ "/logcat/";
  172. File dir = new File(path);
  173. if (!dir.exists()) {
  174. dir.mkdirs();
  175. }
  176. FileOutputStream fos = new FileOutputStream(path + fileName, true);
  177. fos.write((sb.toString()).getBytes());
  178. fos.close();
  179. }
  180. return fileName;
  181. } catch (Exception e) {
  182. Log.e(TAG, "an error occured while writing file...", e);
  183. }
  184. return null;
  185. }
  186. }

在Appliction 中的使用

  1. package com.hai;
  2.  
  3. import android.app.Application;
  4.  
  5. import com.hai.logcat.CrashHandler;
  6.  
  7. public class MyApplication extends Application {
  8. CrashHandler handler = null;
  9.  
  10. @Override
  11. public void onCreate() {
  12. super.onCreate();
  13. handler = CrashHandler.getInstance();
  14. handler.init(getApplicationContext());
  15. }
  16. }
  1.  

android 运行时异常捕获的更多相关文章

  1. Android运行时异常“Binary XML file line # : Error inflating class”

    http://blog.csdn.net/huangxiaohu_coder/article/details/8497286 在原生Android下编译APK,编译没有问题,但是在运行的时候经常出现如 ...

  2. Android(java)学习笔记152:Android运行时异常“Binary XML file line # : Error inflating class”

    在原生Android下编译APK,编译没有问题,但是在运行的时候经常出现如标题所描述的异常:"Binary XML file line # : Error inflating class&q ...

  3. Android(java)学习笔记95:Android运行时异常"Binary XML file line # : Error inflating class"

    在原生Android下编译APK,编译没有问题,但是在运行的时候经常出现如标题所描述的异常:"Binary XML file line # : Error inflating class&q ...

  4. java 检查抛出的异常是否是要捕获的检查性异常或运行时异常或错误

    /** * Return whether the given throwable is a checked exception: * that is, neither a RuntimeExcepti ...

  5. 运行时异常RuntimeException捕获的小测试

    public class ExceptionTest { public static void main(String[] args) throws InterruptedException { ne ...

  6. Java软件工程师面试题:Java运行时异常与一般异常有什么不一样?

    异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误.java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕 ...

  7. Effective Java 第三版——70. 对可恢复条件使用检查异常,对编程错误使用运行时异常

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...

  8. Exception、Error、运行时异常与一般异常有何异同

    转自博客  https://blog.csdn.net/m0_37531231/article/details/79502778 一.开场白 对于程序运行过程中的可能出现异常情况,java语言使用一种 ...

  9. java 运行时异常与非运行时异常理解

    参考:https://blog.csdn.net/lan12334321234/article/details/70049446 所谓的异常就是阻止当前程序或方法继续执行的问题 java异常分为两种: ...

随机推荐

  1. hadoop新增kerberos租户

    第一步 在kerberos服务器所在主机 通过kadmin.local,也可以通过kadmin 输入用户密码登录 kadmin.local: addprinc -randkey it1@STARYEA ...

  2. Android中Activity.this,getApplicationContext(),getBaseContext()和this详解

    转自:http://android.tgbus.com/Android/tutorial/201103/346236.shtml 在使用Android上下文参数的时候经常分不清Activity.thi ...

  3. MyBatis延迟加载和缓存

    一.延迟加载 1.主对象的加载: 根本没有延迟的概念,都是直接加载. 2.关联对象的加载时机: 01.直接加载: 访问主对象,关联对象也要加载 02.侵入式延迟: 访问主对象,并不加载关联对象 访问主 ...

  4. 关于一道面试题【字符串 '1 + (5 - 2) * 3',怎么算出结果为10,'eval'除外】

    最近徘徊在找工作和继续留任的纠结之中,在朋友的怂恿下去参加了一次面试,最后一道题目是: 写一个函数,输入一个字符串的运算式,返回计算之后的结果.例如这样的: '1 + (5 - 2) * 3',计算出 ...

  5. 【Unity与23种设计模式】原型模式(Prototype)

    GoF中定义: "使用原型对象来产生指定类的对象,所以产生对象时,是使用复制原型对象来完成." Unity中 开发者可以组装游戏对象 它可以包括复杂的组件 组装好了之后,就可以将其 ...

  6. zabbix添加自定义监控项

    zabbix添加自定义监控项 author:headsen  chen   2017-10-16  17:23:17 个人原创,转载请注明作者,出处,否则依法追究法律责任 主机端配置: 首先安装好za ...

  7. webpack打包不识别es6语法的坑

    今天Vue项目npm run build 后webpack,报错uglifyjs,自己研究了一下,翻译过来,意思是不识别项目中写的高级语法,这里要把项目里es6语法转es5让浏览器识别, 也就是web ...

  8. org.hibernate.PersistentObjectException: detached entity passed to persist

    简单地来看,将一个游离的对象要被持久化(save)时报错. 我们知道要持久化对象时候,通常Hibernate会根据ID生成策略自动生成ID值,但是这个对象ID已经有值,所有抛错.这个错误会出现在配置如 ...

  9. JS基础二

    JS的实现: 核心:ECMAScript ECMAScript 并不与任何具体浏览器相绑定,实际上,它也没有提到用于任何用户输入输出的方法(这点与 C 这类语言不同,它需要依赖外部的库来完成这类任务) ...

  10. 利用github协作开发步骤

    项目使用IDEA开发,IDEA上可以加载很多的插件(而且下载很快),安装github插件,安装git 首先一个成员需要创建好代码库,这个代码库存放项目,所有的开发提交代码都是向这个库提交,在githu ...