【Android应用开发】 Android 崩溃日志 本地存储 与 远程保存

举报
韩曙亮 发表于 2022/01/11 01:38:55 2022/01/11
【摘要】 示例代码下载 : http://download.csdn.net/detail/han1202012/8638801; 一. 崩溃日志本地存储 1. 保存原理解析 崩溃信息本地保存步骤 :  -- 1. 自定义类实现 UncaughtExceptionHandler : p...


示例代码下载http://download.csdn.net/detail/han1202012/8638801;



一. 崩溃日志本地存储



1. 保存原理解析


崩溃信息本地保存步骤

-- 1. 自定义类实现 UncaughtExceptionHandler : public class CrashHandler implements UncaughtExceptionHandler;

-- 2. 设置该自定义的 CrashHandler 类为单例模式


  
  1. // 单例模式
  2. private static CrashHandler INSTANCE = new CrashHandler();
  3. private CrashHandler() {
  4. }
  5. public static CrashHandler getInstance() {
  6. return INSTANCE;
  7. }
重写 uncaughtException 方法


  
  1. @Override
  2. public void uncaughtException(Thread thread, Throwable ex)
自定义 handleException 方法处理异常信息


(1) UncaughtExceptionHandler 类解析


UncaughtExceptionHandler 作用 : 该类处理以下情况, 如果有未捕获的异常发生, 出现了程序崩溃闪退的情况, 此时会回调该类的 uncaughtException 方法;


(2) 线程相关


线程相关 : 每个线程都对应有响应的默认的未捕获异常处理器;

-- 获取线程默认的未捕获异常处理器 : Thread.getDefaultUncaughtExceptionHandler();

-- 设置线程默认的未捕获异常处理器 : Thread.setDefaultUncaughtExceptionHandler(this);


(3) uncaughtException 方法


uncaughtException 方法解析

-- 回调时机 : 出现未定义的异常时;

-- 回调参数 : 回调时会传入 线程对象 和 要抛出的异常信息, 我们可以在程序中拿到这两个信息;

public void uncaughtException(Thread thread, Throwable ex)
 


(4) 手机设备信息


手机设备信息手机步骤

-- 1. 获取包信息


  
  1. //获取包管理器
  2. PackageManager pm = ctx.getPackageManager();
  3. //获取包信息
  4. PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),
  5. PackageManager.GET_ACTIVITIES);
2. 获取版本号信息


  
  1. if (pi != null) {
  2. //版本号
  3. String versionName = pi.versionName == null ? "null"
  4. : pi.versionName;
  5. //版本代码
  6. String versionCode = pi.versionCode + "";
  7. //将版本信息存放到 成员变量 Map<String, String> mInfos 中
  8. this.mInfos.put("versionName", versionName);
  9. this.mInfos.put("versionCode", versionCode);
  10. }

3. 使用反射获取 Build 类成员变量变量 , 并遍历获取这些变量内容


  
  1. //获取 Build 中定义的变量, 使用反射方式获取, 该类中定义了设备相关的变量信息
  2. Field[] fields = Build.class.getDeclaredFields();
  3. //遍历获取额变量, 将这些信息存放到成员变量 Map<String, String> mInfos 中
  4. for (Field field : fields) {
  5. try {
  6. //设置 Build 成员变量可访问
  7. field.setAccessible(true);
  8. //将 设备相关的信息存放到 mInfos 成员变量中
  9. mInfos.put(field.getName(), field.get(null).toString());
  10. Log.d(TAG, field.getName() + " : " + field.get(null));
  11. } catch (Exception e) {
  12. Log.e(TAG, "an error occured when collect crash info", e);
  13. }
  14. }


(4) 保存崩溃信息到文件


保存文件步骤 : 这些步骤就很简单了, 使用 IO流即可;

-- 1. 将之前获取的 Build 设备信息, 版本信息, 崩溃信息转为字符串


  
  1. //存储相关的字符串信息
  2. StringBuffer sb = new StringBuffer();
  3. //将成员变量 Map<String, String> mInfos 中的数据 存储到 StringBuffer sb 中
  4. for (Map.Entry<String, String> entry : this.mInfos.entrySet()) {
  5. String key = entry.getKey();
  6. String value = entry.getValue();
  7. sb.append(key + "=" + value + "\n");
  8. }
2. 在 Logcat 中打印崩溃信息


  
  1. //将 StringBuffer sb 中的字符串写出到文件中
  2. Writer writer = new StringWriter();
  3. PrintWriter printWriter = new PrintWriter(writer);
  4. ex.printStackTrace(printWriter);
  5. Throwable cause = ex.getCause();
  6. while (cause != null) {
  7. cause.printStackTrace(printWriter);
  8. cause = cause.getCause();
  9. }
  10. printWriter.close();
3. 写出数据到文件中


  
  1. String result = writer.toString();
  2. sb.append(result);
  3. try {
  4. long timestamp = System.currentTimeMillis();
  5. String time = formatter.format(new Date());
  6. String fileName = "crash-" + time + "-" + timestamp + ".txt";
  7. if (Environment.getExternalStorageState().equals(
  8. Environment.MEDIA_MOUNTED)) {
  9. //获取文件输出路径
  10. String path = Environment.getExternalStorageDirectory()
  11. + "/crashinfo/";
  12. //创建文件夹和文件
  13. File dir = new File(path);
  14. if (!dir.exists()) {
  15. dir.mkdirs();
  16. }
  17. //创建输出流
  18. FileOutputStream fos = new FileOutputStream(path + fileName);
  19. //向文件中写出数据
  20. fos.write(sb.toString().getBytes());
  21. fos.close();
  22. }
  23. return fileName;
  24. } catch (Exception e) {
  25. Log.e(TAG, "an error occured while writing file...", e);
  26. }



2. 代码及示例



(1) 相关代码示例


故意发生错误的代码


  
  1. public class MainActivity extends Activity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_main);
  6. }
  7. public void onClick(View view) {
  8. int i = 3;
  9. i = i / 0;
  10. }
  11. }


CrashHandler 注册代码 : 在 Activity 或者 Application 中注册该代码;

CrashHandler.getInstance().init(getApplicationContext());
 


CrashHandler 代码


  
  1. package cn.org.octpus.crash;
  2. import java.io.File;
  3. import java.io.FileOutputStream;
  4. import java.io.PrintWriter;
  5. import java.io.StringWriter;
  6. import java.io.Writer;
  7. import java.lang.Thread.UncaughtExceptionHandler;
  8. import java.lang.reflect.Field;
  9. import java.text.DateFormat;
  10. import java.text.SimpleDateFormat;
  11. import java.util.Date;
  12. import java.util.HashMap;
  13. import java.util.Map;
  14. import android.content.Context;
  15. import android.content.pm.PackageInfo;
  16. import android.content.pm.PackageManager;
  17. import android.content.pm.PackageManager.NameNotFoundException;
  18. import android.os.Build;
  19. import android.os.Environment;
  20. import android.os.Looper;
  21. import android.util.Log;
  22. import android.widget.Toast;
  23. /**
  24. * UncaughtExceptionHanlder 作用 : 处理 线程被未捕获的异常终止 的情况, 一旦出现了未捕获异常崩溃, 系统就会回调该类的
  25. * uncaughtException 方法;
  26. */
  27. public class CrashHandler implements UncaughtExceptionHandler {
  28. // 用于打印日志的 TAG 标识符
  29. public static final String TAG = "octopus.CrashHandler";
  30. // 系统默认的UncaughtException处理类
  31. private Thread.UncaughtExceptionHandler mDefaultHandler;
  32. // 程序的Context对象
  33. private Context mContext;
  34. // 用来存储设备信息和异常信息
  35. private Map<String, String> mInfos = new HashMap<String, String>();
  36. // 用于格式化日期,作为日志文件名的一部分
  37. private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
  38. // 单例模式
  39. private static CrashHandler INSTANCE = new CrashHandler();
  40. private CrashHandler() {
  41. }
  42. public static CrashHandler getInstance() {
  43. return INSTANCE;
  44. }
  45. /**
  46. * 初始化该类, 向系统中注册
  47. * @param context
  48. */
  49. public void init(Context context) {
  50. mContext = context;
  51. // 获取系统默认的 UncaughtException 处理器
  52. mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
  53. // 设置该 CrashHandler 为程序的默认处理器
  54. Thread.setDefaultUncaughtExceptionHandler(this);
  55. }
  56. /*
  57. * 出现未捕获的异常时, 会自动回调该方法
  58. * (non-Javadoc)
  59. * @see java.lang.Thread.UncaughtExceptionHandler#uncaughtException(java.lang.Thread, java.lang.Throwable)
  60. */
  61. @Override
  62. public void uncaughtException(Thread thread, Throwable ex) {
  63. /*
  64. * 调用 handleException() 方法处理该线程
  65. * 如果返回 true 说明处理成功, 如果返回 false 则调用默认的异常处理器来处理
  66. * 一般情况下该方法都会成功处理
  67. */
  68. if (!handleException(ex) && mDefaultHandler != null) {
  69. // 如果用户没有处理则让系统默认的异常处理器来处理
  70. mDefaultHandler.uncaughtException(thread, ex);
  71. } else {
  72. try {
  73. Thread.sleep(3000);
  74. } catch (InterruptedException e) {
  75. Log.e(TAG, "error : ", e);
  76. }
  77. // 退出程序
  78. android.os.Process.killProcess(android.os.Process.myPid());
  79. System.exit(1);
  80. }
  81. }
  82. /**
  83. * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
  84. * @param ex
  85. * 异常信息
  86. * @return
  87. * true:如果处理了该异常信息;否则返回false.
  88. */
  89. private boolean handleException(Throwable ex) {
  90. if (ex == null) {
  91. return false;
  92. }
  93. /*
  94. * 使用Toast来显示异常信息,
  95. * 由于在主线程会阻塞,
  96. * 不能实时出现 Toast 信息,
  97. * 这里我们在子线程中处理 Toast 信息
  98. */
  99. new Thread() {
  100. @Override
  101. public void run() {
  102. Looper.prepare();
  103. Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_LONG)
  104. .show();
  105. Looper.loop();
  106. }
  107. }.start();
  108. // 收集设备参数信息
  109. collectDeviceInfo(mContext);
  110. // 保存日志文件
  111. saveCrashInfo2File(ex);
  112. return true;
  113. }
  114. /**
  115. * 收集设备参数信息, 将手机到的信息存储到
  116. * @param ctx
  117. * 上下文对象
  118. */
  119. public void collectDeviceInfo(Context ctx) {
  120. try {
  121. //获取包管理器
  122. PackageManager pm = ctx.getPackageManager();
  123. //获取包信息
  124. PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),
  125. PackageManager.GET_ACTIVITIES);
  126. if (pi != null) {
  127. //版本号
  128. String versionName = pi.versionName == null ? "null"
  129. : pi.versionName;
  130. //版本代码
  131. String versionCode = pi.versionCode + "";
  132. //将版本信息存放到 成员变量 Map<String, String> mInfos 中
  133. this.mInfos.put("versionName", versionName);
  134. this.mInfos.put("versionCode", versionCode);
  135. }
  136. } catch (NameNotFoundException e) {
  137. Log.e(TAG, "an error occured when collect package info", e);
  138. }
  139. //获取 Build 中定义的变量, 使用反射方式获取, 该类中定义了设备相关的变量信息
  140. Field[] fields = Build.class.getDeclaredFields();
  141. //遍历获取额变量, 将这些信息存放到成员变量 Map<String, String> mInfos 中
  142. for (Field field : fields) {
  143. try {
  144. //设置 Build 成员变量可访问
  145. field.setAccessible(true);
  146. //将 设备相关的信息存放到 mInfos 成员变量中
  147. mInfos.put(field.getName(), field.get(null).toString());
  148. Log.d(TAG, field.getName() + " : " + field.get(null));
  149. } catch (Exception e) {
  150. Log.e(TAG, "an error occured when collect crash info", e);
  151. }
  152. }
  153. }
  154. /**
  155. * 保存错误信息到文件中
  156. * @param ex
  157. * @return 返回文件名称,便于将文件传送到服务器
  158. */
  159. private String saveCrashInfo2File(Throwable ex) {
  160. //存储相关的字符串信息
  161. StringBuffer sb = new StringBuffer();
  162. //将成员变量 Map<String, String> mInfos 中的数据 存储到 StringBuffer sb 中
  163. for (Map.Entry<String, String> entry : this.mInfos.entrySet()) {
  164. String key = entry.getKey();
  165. String value = entry.getValue();
  166. sb.append(key + "=" + value + "\n");
  167. }
  168. //将 StringBuffer sb 中的字符串写出到文件中
  169. Writer writer = new StringWriter();
  170. PrintWriter printWriter = new PrintWriter(writer);
  171. ex.printStackTrace(printWriter);
  172. Throwable cause = ex.getCause();
  173. while (cause != null) {
  174. cause.printStackTrace(printWriter);
  175. cause = cause.getCause();
  176. }
  177. printWriter.close();
  178. String result = writer.toString();
  179. sb.append(result);
  180. try {
  181. long timestamp = System.currentTimeMillis();
  182. String time = formatter.format(new Date());
  183. String fileName = "crash-" + time + "-" + timestamp + ".txt";
  184. if (Environment.getExternalStorageState().equals(
  185. Environment.MEDIA_MOUNTED)) {
  186. //获取文件输出路径
  187. String path = Environment.getExternalStorageDirectory()
  188. + "/crashinfo/";
  189. //创建文件夹和文件
  190. File dir = new File(path);
  191. if (!dir.exists()) {
  192. dir.mkdirs();
  193. }
  194. //创建输出流
  195. FileOutputStream fos = new FileOutputStream(path + fileName);
  196. //向文件中写出数据
  197. fos.write(sb.toString().getBytes());
  198. fos.close();
  199. }
  200. return fileName;
  201. } catch (Exception e) {
  202. Log.e(TAG, "an error occured while writing file...", e);
  203. }
  204. return null;
  205. }
  206. }


(2) 结果示例



崩溃日志存放文件路径 : /storage/sdcard0/crashinfo/crash-2015-04-27-19-31-41-1430134301642.txt;

-- 说明 : 其中 /storage/sdcard0/ 是系统默认的 SD 卡路径, crashinfo/crash-2015-04-27-19-31-41-1430134301642.txt 是我们创建的文件;


崩溃日志内容

1430134301642.txt                                                             <
HARDWARE=pxa1088
RADIO=unknown
versionCode=1
HOST=SWDA2601
TAGS=release-keys
ID=JDQ39
MANUFACTURER=samsung
TYPE=user
IS_TRANSLATION_ASSISTANT_ENABLED=false
IS_SECURE=false
TIME=1416298944000
FINGERPRINT=samsung/wilcoxdszn/wilcoxds:4.2.2/JDQ39/G3812ZNUANK1:user/release-keys
UNKNOWN=unknown
BOARD=PXA1088
PRODUCT=wilcoxdszn
versionName=1.0
DISPLAY=JDQ39.G3812ZNUANK1
USER=se.infra
DEVICE=wilcoxds
MODEL=SM-G3812
BOOTLOADER=unknown
CPU_ABI=armeabi-v7a
CPU_ABI2=armeabi
IS_SYSTEM_SECURE=false
IS_DEBUGGABLE=false
SERIAL=5202889565301100
BRAND=samsung
java.lang.IllegalStateException: Could not execute method of the activity
	at android.view.View$1.onClick(View.java:3804)
	at android.view.View.performClick(View.java:4439)
	at android.widget.Button.performClick(Button.java:142)
	at android.view.View$PerformClick.run(View.java:18395)
	at android.os.Handler.handleCallback(Handler.java:725)
	at android.os.Handler.dispatchMessage(Handler.java:92)
	at android.os.Looper.loop(Looper.java:176)
	at android.app.ActivityThread.main(ActivityThread.java:5319)
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:511)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
	at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:511)
	at android.view.View$1.onClick(View.java:3799)
	... 12 more
Caused by: java.lang.ArithmeticException: divide by zero
	at cn.org.octpus.crash.MainActivity.onClick(MainActivity.java:20)
	... 15 more
java.lang.reflect.InvocationTargetException
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:511)
	at android.view.View$1.onClick(View.java:3799)
	at android.view.View.performClick(View.java:4439)
	at android.widget.Button.performClick(Button.java:142)
	at android.view.View$PerformClick.run(View.java:18395)
	at android.os.Handler.handleCallback(Handler.java:725)
	at android.os.Handler.dispatchMessage(Handler.java:92)
	at android.os.Looper.loop(Looper.java:176)
	at android.app.ActivityThread.main(ActivityThread.java:5319)
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:511)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
	at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ArithmeticException: divide by zero
	at cn.org.octpus.crash.MainActivity.onClick(MainActivity.java:20)
	... 15 more
java.lang.ArithmeticException: divide by zero
	at cn.org.octpus.crash.MainActivity.onClick(MainActivity.java:20)
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:511)
	at android.view.View$1.onClick(View.java:3799)
	at android.view.View.performClick(View.java:4439)
	at android.widget.Button.performClick(Button.java:142)
	at android.view.View$PerformClick.run(View.java:18395)
	at android.os.Handler.handleCallback(Handler.java:725)
	at android.os.Handler.dispatchMessage(Handler.java:92)
	at android.os.Looper.loop(Looper.java:176)
	at android.app.ActivityThread.main(ActivityThread.java:5319)
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:511)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
	at dalvik.system.NativeStart.main(Native Method)




二. 崩溃日志保存到远程服务器



实现途径

-- 1. 自己开发服务器端 : 在上面的保存文件的基础上, 在开发一个服务器端, 使用网络编程接口将打印到文件的内容上传到服务器端;

-- 2. 使用第三方服务 : 使用 Testin 的崩溃大师, 地址 http://crash.testin.cn/app?scnavbar ;


1. 集成崩溃大师步骤



(1) 创建应用 获取 key 值


创建应用步骤

-- 1. 创建界面 http://crash.testin.cn/apm/task/create ;

-- 2. 填写一个应用信息


-- 3. 获取 key : 点击"提交并获取 Appkey" 按钮, 获取到了 AppKey "0da6263ca1f5b84a2dd405b07227f483";



(2) 设置类型


第二步设置类型, 选择默认的应用即可



(3) 下载 jar 包


jar 包简介 : 集成崩溃大师, 只需要集成一个 jar 包即可, 点击如下按钮即可下载 该 jar 包;

-- jar 包内容 : 下载后解压, jar 包名称是 testinagent.jar ;



(4) 导入 SDK 


导入 SDK : 在应用下 创建一个 libs 目录, 将jar 包拷贝进去即可;




(5) 配置 AndroidManifest.xml 文件 


在配置文件中添加如下用户权限即可


  
  1. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  2. <uses-permission android:name="android.permission.INTERNET" />
  3. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  4. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  5. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  6. <uses-permission android:name="android.permission.READ_LOGS" />
  7. <uses-permission android:name="android.permission.GET_TASKS" />


(6) 初始化设置


在代码中注册


  
  1. //初始化 Testin 崩溃大师
  2. TestinAgent.init(getApplicationContext(), "0da6263ca1f5b84a2dd405b07227f483", "octopus");




2. 测试示例



(1) 日志信息


测试成功会打印如下信息


  
  1. 04-27 20:11:40.890: E/TestinAgent(16432): ****************************************
  2. 04-27 20:11:40.890: E/TestinAgent(16432): A Java crash caught by TestinAgent, pkg=cn.org.octpus.crash
  3. 04-27 20:11:40.890: E/TestinAgent(16432): ----------------------------------------
  4. 04-27 20:11:40.890: E/TestinAgent(16432): reason: java.lang.IllegalStateException: Could not execute method of the activity
  5. 04-27 20:11:40.890: E/TestinAgent(16432): ----------------------------------------
  6. 04-27 20:11:40.890: E/TestinAgent(16432): stacktrace:
  7. 04-27 20:11:40.890: E/TestinAgent(16432): at android.view.View$1.onClick(View.java:3804)
  8. 04-27 20:11:40.890: E/TestinAgent(16432): at android.view.View.performClick(View.java:4439)
  9. 04-27 20:11:40.890: E/TestinAgent(16432): at android.widget.Button.performClick(Button.java:142)
  10. 04-27 20:11:40.890: E/TestinAgent(16432): at android.view.View$PerformClick.run(View.java:18395)
  11. 04-27 20:11:40.890: E/TestinAgent(16432): at android.os.Handler.handleCallback(Handler.java:725)
  12. 04-27 20:11:40.890: E/TestinAgent(16432): at android.os.Handler.dispatchMessage(Handler.java:92)
  13. 04-27 20:11:40.890: E/TestinAgent(16432): at android.os.Looper.loop(Looper.java:176)
  14. 04-27 20:11:40.890: E/TestinAgent(16432): at android.app.ActivityThread.main(ActivityThread.java:5319)
  15. 04-27 20:11:40.890: E/TestinAgent(16432): at java.lang.reflect.Method.invokeNative(Native Method)
  16. 04-27 20:11:40.890: E/TestinAgent(16432): at java.lang.reflect.Method.invoke(Method.java:511)
  17. 04-27 20:11:40.890: E/TestinAgent(16432): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
  18. 04-27 20:11:40.890: E/TestinAgent(16432): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
  19. 04-27 20:11:40.890: E/TestinAgent(16432): at dalvik.system.NativeStart.main(Native Method)
  20. 04-27 20:11:40.890: E/TestinAgent(16432): Caused by: java.lang.reflect.InvocationTargetException
  21. 04-27 20:11:40.890: E/TestinAgent(16432): at java.lang.reflect.Method.invokeNative(Native Method)
  22. 04-27 20:11:40.890: E/TestinAgent(16432): at java.lang.reflect.Method.invoke(Method.java:511)
  23. 04-27 20:11:40.890: E/TestinAgent(16432): at android.view.View$1.onClick(View.java:3799)
  24. 04-27 20:11:40.890: E/TestinAgent(16432): ... 12 more
  25. 04-27 20:11:40.890: E/TestinAgent(16432): Caused by: java.lang.ArithmeticException: divide by zero
  26. 04-27 20:11:40.890: E/TestinAgent(16432): at cn.org.octpus.crash.MainActivity.onClick(MainActivity.java:20)
  27. 04-27 20:11:40.890: E/TestinAgent(16432): ... 15 more
  28. 04-27 20:11:40.890: E/TestinAgent(16432): ----------------------------------------
  29. 04-27 20:11:40.890: E/TestinAgent(16432): deviceinfo:
  30. 04-27 20:11:40.890: E/TestinAgent(16432): Device: samsung/SM-G3812
  31. 04-27 20:11:40.890: E/TestinAgent(16432): OS: 4.2.2
  32. 04-27 20:11:40.890: E/TestinAgent(16432): AppVersion: 1.0
  33. 04-27 20:11:40.890: E/TestinAgent(16432): PackageName: cn.org.octpus.crash
  34. 04-27 20:11:40.890: E/TestinAgent(16432): Activity: MainActivity
  35. 04-27 20:11:40.890: E/TestinAgent(16432): Total Disk Space: 2328 MB ; Free Disk Space: 1688 MB
  36. 04-27 20:11:40.890: E/TestinAgent(16432): Total SD Space: 2308 MB ; Free SD Space: 1668 MB
  37. 04-27 20:11:40.890: E/TestinAgent(16432): CPU Usage: 17.742 %
  38. 04-27 20:11:40.890: E/TestinAgent(16432): Memory Usage: 12 MB
  39. 04-27 20:11:40.890: E/TestinAgent(16432): Userinfo:
  40. 04-27 20:11:40.890: E/TestinAgent(16432): ****************************************


(2) 后台信息


后台崩溃数据

-- 控制台信息 : 进入崩溃大师的控制台, 就会看到刚看到的 CrashInfoDemo 应用, 此时我们估计产生的异常已经打印出来了;


-- 点击进入该应用的详情


-- 详细的崩溃信息查看






文章来源: hanshuliang.blog.csdn.net,作者:韩曙亮,版权归原作者所有,如需转载,请联系作者。

原文链接:hanshuliang.blog.csdn.net/article/details/45306495

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。