版权声明:本文为HaiyuKing原创文章,转载请注明出处!

前言

简单记录下LogcatHelper的使用,并对原有代码进行了修改【因为保存到应用内的目录中不需要申请权限,所以去掉保存到SD的功能--个人觉得这个类主要用于开发者自己调试用】:

  1. /**初始化目录 "包名+logcat"
  2. * */
  3. public void init(Context context) {
  4. // if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {// 优先保存到SD卡中
  5. // PATH_LOGCAT = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + context.getPackageName() + File.separator + "logcat";
  6. // } else {
  7. //如果SD卡不存在,就保存到本应用的目录下【why 直接保存到本应用的目录下】
  8. PATH_LOGCAT = context.getFilesDir().getAbsolutePath() + File.separator + "logcat";
  9. // }
  10. File file = new File(PATH_LOGCAT);
  11. if (!file.exists()) {
  12. file.mkdirs();
  13. }
  14. }

效果图

存储在应用内的目录:

logcat-2018-08-14.log 

  1. 2018-08-14 10:18:06 I/art (24242): Late-enabling -Xcheck:jni
  2. 2018-08-14 10:18:06 W/art (24242): Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
  3. 2018-08-14 10:18:06 E/Process (24242): android_os_Process_getProcessNameByPid pid is 24242
  4. 2018-08-14 10:18:06 E/Process (24242): android_os_Process_getProcessNameByPid value is ogcathelperdemo
  5. 2018-08-14 10:18:06 V/MainActivity(24242): 这是V日志
  6. 2018-08-14 10:18:06 D/MainActivity(24242): 这是D日志
  7. 2018-08-14 10:18:06 I/MainActivity(24242): 这是I日志
  8. 2018-08-14 10:18:06 W/MainActivity(24242): 这是W日志
  9. 2018-08-14 10:18:06 E/MainActivity(24242): 这是E日志
  10. 2018-08-14 10:18:06 V/PhoneWindow(24242): DecorView setVisiblity: visibility = 4 ,Parent =null, this =com.android.internal.policy.impl.PhoneWindow$DecorView{34498aa9 I.E..... R.....ID 0,0-0,0}
  11. 2018-08-14 10:18:06 D/OpenGLRenderer(24242): Dumper init 4 threads <0x7f84d321c0>
  12. 2018-08-14 10:18:06 D/OpenGLRenderer(24242): <com.why.project.logcathelperdemo> is running.
  13. 2018-08-14 10:18:06 D/OpenGLRenderer(24242): <com.why.project.logcathelperdemo> setHwuiLog: debug.egl.trace=false
  14. 2018-08-14 10:18:06 D/OpenGLRenderer(24242): initialize DisplayEventReceiver 0x7f8ac1a400
  15. 2018-08-14 10:18:06 D/OpenGLRenderer(24242): Use EGL_SWAP_BEHAVIOR_PRESERVED: true
  16. 2018-08-14 10:18:06 D/Atlas (24242): Validating map...
  17. 2018-08-14 10:18:06 D/ViewRootImpl(24242): hardware acceleration is enabled, this = ViewRoot{296d9189 com.why.project.logcathelperdemo/com.why.project.logcathelperdemo.MainActivity,ident = 0}
  18. 2018-08-14 10:18:06 V/PhoneWindow(24242): DecorView setVisiblity: visibility = 0 ,Parent =ViewRoot{296d9189 com.why.project.logcathelperdemo/com.why.project.logcathelperdemo.MainActivity,ident = 0}, this =com.android.internal.policy.impl.PhoneWindow$DecorView{34498aa9 V.E..... R.....ID 0,0-0,0}
  19. 2018-08-14 10:18:06 D/OpenGLRenderer(24242): CanvasContext() 0x7f8ac1db40 initialize 0x7f91e3c610
  20. 2018-08-14 10:18:06 D/MALI (24242): eglInitialize:1479: [+]
  21. 2018-08-14 10:18:06 E/GED (24242): Failed to get GED Log Buf, err(0)
  22. 2018-08-14 10:18:06 D/MALI (24242): eglInitialize:1850: [-]
  23. 2018-08-14 10:18:06 I/ (24242): elapse(include ctx switch):3533 (ms), eglInitialize
  24. 2018-08-14 10:18:06 I/OpenGLRenderer(24242): Initialized EGL, version 1.4
  25. 2018-08-14 10:18:06 D/MALI (24242): eglCreateContext:206: [MALI] eglCreateContext display 0x7f91c5fd00, share context 0x0 here.
  26. 2018-08-14 10:18:06 D/MALI (24242): gles_context_new:248: Create GLES ctx 0x7f8ae8a008 successfully
  27. 2018-08-14 10:18:06 D/MALI (24242): eglCreateContext:543: [MALI] eglCreateContext end. Created context 0x7f8ae7ad80 here.
  28. 2018-08-14 10:18:06 D/OpenGLRenderer(24242): Created EGL context (0x7f8ae37040)
  29. 2018-08-14 10:18:06 I/OpenGLRenderer(24242): Get enable program binary service property (1)
  30. 2018-08-14 10:18:06 I/OpenGLRenderer(24242): Initializing program atlas...
  31. 2018-08-14 10:18:06 D/ProgramBinary/Service(24242): BpProgramBinaryService.getFileDescriptor
  32. 2018-08-14 10:18:06 D/ProgramBinary/Service(24242): BpProgramBinaryService.getProgramMapLen
  33. 2018-08-14 10:18:06 D/ProgramBinary/Service(24242): BpProgramBinaryService.getProgramMapArray
  34. 2018-08-14 10:18:06 D/ProgramBinary/Service(24242): BpProgramBinaryService.getProgramBinaryLen
  35. 2018-08-14 10:18:06 I/OpenGLRenderer(24242): Program binary detail: Binary length is 169984, program map length is 152.
  36. 2018-08-14 10:18:06 I/OpenGLRenderer(24242): Succeeded to mmap program binaries. File descriptor is 46, and path is /dev/ashmem{.
  37. 2018-08-14 10:18:06 I/OpenGLRenderer(24242): No need to use file discriptor anymore, close fd(46).
  38. 2018-08-14 10:18:06 D/OpenGLRenderer(24242): TaskManager() 0x7f8acff1f0, cpu = 8, thread = 4
  39. 2018-08-14 10:18:06 D/OpenGLRenderer(24242): Initializing program cache from 0x0, size = -1
  40. 2018-08-14 10:18:06 D/OpenGLRenderer(24242): Enabling debug mode 0
  41. 2018-08-14 10:18:06 D/Surface (24242): Surface::connect(this=0x7f91e3c600,api=1)
  42. 2018-08-14 10:18:06 D/mali_winsys(24242): new_window_surface returns 0x3000
  43. 2018-08-14 10:18:06 D/Surface (24242): Surface::allocateBuffers(this=0x7f91e3c600)
  44. 2018-08-14 10:18:06 D/OpenGLRenderer(24242): [TaskMgr] Running thread hwuiTask1 (24290)
  45. 2018-08-14 10:18:06 W/MALI (24242): glDrawArrays:714: [MALI] glDrawArrays takes more than 5ms here. Total elapse time(us): 6667
  46. 2018-08-14 10:18:06 D/OpenGLRenderer(24242): ProgramCache save to disk, size = 3
  47. 2018-08-14 10:18:06 V/InputMethodManager(24242): onWindowFocus: null softInputMode=288 first=true flags=#81810100
  48. 2018-08-14 10:18:06 V/InputMethodManager(24242): START INPUT: com.android.internal.policy.impl.PhoneWindow$DecorView{34498aa9 V.E..... R....... 0,0-1080,1920} ic=null tba=android.view.inputmethod.EditorInfo@2ce154f2 controlFlags=#104
  49. 2018-08-14 10:18:06 D/InputMethodManager(24242): receive service's setActive call, active:true
  50. 2018-08-14 10:18:06 I/InputMethodManager(24242): handleMessage: MSG_SET_ACTIVE true, was false

使用步骤

一、项目组织结构图

注意事项:

1、  导入类文件后需要change包名以及重新import R文件路径

2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

二、导入步骤

(1)将logcathelper包复制到项目中

  1. package com.why.project.logcathelperdemo.logcathelper;
  2.  
  3. import android.content.Context;
  4.  
  5. import java.io.BufferedReader;
  6. import java.io.File;
  7. import java.io.FileNotFoundException;
  8. import java.io.FileOutputStream;
  9. import java.io.IOException;
  10. import java.io.InputStreamReader;
  11.  
  12. /**
  13. * Created by HaiyuKing
  14. * Used log日志统计保存到本地文件
  15. * 参考资料 Android将应用log信息保存文件:http://www.cnblogs.com/weixing/p/3414164.html
  16. */
  17. public class LogcatHelper {
  18. private static LogcatHelper INSTANCE = null;
  19. /**日志文件保存路径*/
  20. private static String PATH_LOGCAT;
  21. private LogDumper mLogDumper = null;
  22. /**应用进程ID*/
  23. private int mPId;
  24.  
  25. /**初始化目录 "包名+logcat"
  26. * */
  27. public void init(Context context) {
  28. // if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {// 优先保存到SD卡中
  29. // PATH_LOGCAT = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + context.getPackageName() + File.separator + "logcat";
  30. // } else {
  31. //如果SD卡不存在,就保存到本应用的目录下【why 直接保存到本应用的目录下】
  32. PATH_LOGCAT = context.getFilesDir().getAbsolutePath() + File.separator + "logcat";
  33. // }
  34. File file = new File(PATH_LOGCAT);
  35. if (!file.exists()) {
  36. file.mkdirs();
  37. }
  38. }
  39. /**单例模式
  40. * */
  41. public static LogcatHelper getInstance(Context context) {
  42. if (INSTANCE == null) {
  43. INSTANCE = new LogcatHelper(context);
  44. }
  45. return INSTANCE;
  46. }
  47.  
  48. private LogcatHelper(Context context) {
  49. init(context);
  50. mPId = android.os.Process.myPid();
  51. }
  52.  
  53. public void start() {
  54. if (mLogDumper == null)
  55. mLogDumper = new LogDumper(String.valueOf(mPId), PATH_LOGCAT);
  56. mLogDumper.start();
  57. }
  58.  
  59. public void stop() {
  60. if (mLogDumper != null) {
  61. mLogDumper.stopLogs();
  62. mLogDumper = null;
  63. }
  64. }
  65.  
  66. private class LogDumper extends Thread {
  67.  
  68. private Process logcatProc;
  69. private BufferedReader mReader = null;
  70. private boolean mRunning = true;
  71. String cmds = null;
  72. private String mPID;
  73. private FileOutputStream out = null;
  74.  
  75. public LogDumper(String pid, String dir) {
  76. mPID = pid;
  77. try {
  78. out = new FileOutputStream(new File(dir, "logcat-" + MyDate.getFileName() + ".log"));
  79. } catch (FileNotFoundException e) {
  80. // TODO Auto-generated catch block
  81. e.printStackTrace();
  82. }
  83.  
  84. /**
  85. *
  86. * 日志等级:*:v , *:d , *:w , *:e , *:f , *:s
  87. *
  88. * 显示当前mPID程序的 E和W等级的日志.
  89. *
  90. * */
  91.  
  92. // cmds = "logcat *:e *:w | grep \"(" + mPID + ")\"";
  93. cmds = "logcat | grep \"(" + mPID + ")\"";//打印所有日志信息
  94. // cmds = "logcat -s way";//打印标签过滤信息
  95. //cmds = "logcat *:e *:i | grep \"(" + mPID + ")\"";
  96.  
  97. }
  98.  
  99. public void stopLogs() {
  100. mRunning = false;
  101. }
  102.  
  103. @Override
  104. public void run() {
  105. try {
  106. logcatProc = Runtime.getRuntime().exec(cmds);
  107. mReader = new BufferedReader(new InputStreamReader(logcatProc.getInputStream()), 1024);
  108. String line = null;
  109. while (mRunning && (line = mReader.readLine()) != null) {
  110. if (!mRunning) {
  111. break;
  112. }
  113. if (line.length() == 0) {
  114. continue;
  115. }
  116. if (out != null && line.contains(mPID)) {
  117. out.write((MyDate.getDateEN() + " " + line + "\n")
  118. .getBytes());
  119. }
  120. }
  121.  
  122. } catch (IOException e) {
  123. e.printStackTrace();
  124. } finally {
  125. if (logcatProc != null) {
  126. logcatProc.destroy();
  127. logcatProc = null;
  128. }
  129. if (mReader != null) {
  130. try {
  131. mReader.close();
  132. mReader = null;
  133. } catch (IOException e) {
  134. e.printStackTrace();
  135. }
  136. }
  137. if (out != null) {
  138. try {
  139. out.close();
  140. } catch (IOException e) {
  141. e.printStackTrace();
  142. }
  143. out = null;
  144. }
  145. }
  146. }
  147. }
  148. }

LogcatHelper.java

  1. package com.why.project.logcathelperdemo.logcathelper;
  2.  
  3. import java.text.SimpleDateFormat;
  4. import java.util.Date;
  5. import java.util.Locale;
  6.  
  7. /**
  8. * Created by HaiyuKing
  9. * Used
  10. */
  11. public class MyDate {
  12. public static String getFileName() {
  13. SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd",Locale.CHINA);
  14. String date = format.format(new Date(System.currentTimeMillis()));
  15. return date;// 2012-10-03
  16. }
  17.  
  18. public static String getDateEN() {
  19. SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.CHINA);
  20. String date1 = format1.format(new Date(System.currentTimeMillis()));
  21. return date1;// 2012-10-03 23:41:31
  22. }
  23. }

MyDate.java

(2)新建MyApplication.java并添加以下代码

  1. package com.why.project.logcathelperdemo;
  2.  
  3. import android.app.Application;
  4.  
  5. import com.why.project.logcathelperdemo.logcathelper.LogcatHelper;
  6.  
  7. /**
  8. * Created by HaiyuKing
  9. * Used 自定义application
  10. */
  11.  
  12. public class MyApplication extends Application{
  13. @Override
  14. public void onCreate() {
  15. super.onCreate();
  16. //在应用中start LogcatHelper
  17. LogcatHelper.getInstance(this).start();
  18. }
  19.  
  20. @Override
  21. public void onTerminate() {
  22. super.onTerminate();
  23. //在应用中stop LogcatHelper
  24. LogcatHelper.getInstance(this).stop();
  25. }
  26.  
  27. @Override
  28. public void onTrimMemory(int level) {
  29. super.onTrimMemory(level);
  30. }
  31.  
  32. }

(3)在AndroidManifest.xml中申请MyApplication

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.why.project.logcathelperdemo">
  4.  
  5. <application
  6. android:name=".MyApplication"
  7. android:allowBackup="true"
  8. android:icon="@mipmap/ic_launcher"
  9. android:label="@string/app_name"
  10. android:roundIcon="@mipmap/ic_launcher_round"
  11. android:supportsRtl="true"
  12. android:theme="@style/AppTheme">
  13. <activity android:name=".MainActivity">
  14. <intent-filter>
  15. <action android:name="android.intent.action.MAIN"/>
  16.  
  17. <category android:name="android.intent.category.LAUNCHER"/>
  18. </intent-filter>
  19. </activity>
  20. </application>
  21.  
  22. </manifest>

(4)使用完之后,记得调用一下LogcatHelper.getInstance(this).stop();,MyApplication中执行的LogcatHelper.getInstance(this).stop();,可能有时候执行不到,保险起见,可以在第一个activity的onDestroy中执行LogcatHelper.getInstance(this).stop();

三、使用方法

正常执行Log方法即可。

  1. package com.why.project.logcathelperdemo;
  2.  
  3. import android.os.Bundle;
  4. import android.support.v7.app.AppCompatActivity;
  5. import android.util.Log;
  6.  
  7. import com.why.project.logcathelperdemo.logcathelper.LogcatHelper;
  8.  
  9. public class MainActivity extends AppCompatActivity {
  10.  
  11. @Override
  12. protected void onCreate(Bundle savedInstanceState) {
  13. super.onCreate(savedInstanceState);
  14. setContentView(R.layout.activity_main);
  15.  
  16. Log.v("MainActivity", "这是V日志");
  17. Log.d("MainActivity", "这是D日志");
  18. Log.i("MainActivity", "这是I日志");
  19. Log.w("MainActivity", "这是W日志");
  20. Log.e("MainActivity", "这是E日志");
  21. }
  22.  
  23. @Override
  24. protected void onDestroy() {
  25. // TODO Auto-generated method stub
  26. super.onDestroy();
  27.  
  28. //使用完后,调用stop
  29. LogcatHelper.getInstance(getApplicationContext()).stop();
  30. }
  31. }

混淆配置

参考资料

Android将应用log信息保存文件

Android将应用log信息保存文件

项目demo下载地址

https://github.com/haiyuKing/LogcatHelperDemo

LogcatHelperDemo【应用log信息保存成本地文件】的更多相关文章

  1. Android将应用log信息保存文件

    相信大家在做应用调试的时候,不可能时时通过USB线连着电脑去查看log信息,所以,将应用的log信息保存到手机本地就很有必要了,有助我们从这些log信息中提取有用的部分,以解决一些bug,下面我把网上 ...

  2. 51ll网产品信息保存为txt文件

    import requests from pyquery import PyQuery as pq url='http://www.51xxx.com/Try/index/p/3' headers={ ...

  3. 保存mysql用户的登录信息到~.my.cnf文件;用于方便登录操作。

    原理说明: 在用户调用mysql 这个客户端程序去登录目标服务器时,mysql客户端程序会从本地读取配置文件信息,它要去读的配置文件包括 /etc/my.cnf /etc/mysql/my.cnf ~ ...

  4. ios 将Log日志重定向输出到文件中保存

    对于真机,日志没法保存,不好分析问题.所以有必要将日志保存到应用的Docunment目录下,并设置成共享文件,这样才能取出分析. 首先是日志输出,分为c的printf和标准的NSLog输出,print ...

  5. linux重定向总结:如何将shell命令的输出信息自动输出到文件中保存

    在做批量实验室,例如跑批量MR的作业,我们会写好shell脚本,然后启动脚本,等所有作业执行完再去看结果,但是这些执行时的信息如何保存下来到文件中呢?下面这个命令可以完成这个任务. sh batchj ...

  6. Android开发过程中在sh,py,mk文件中添加log信息的方法

    Android开发过程中在sh,py,mk文件中添加log信息的方法 在sh文件中: echo "this is a log info" + $info 在py文件中: print ...

  7. Eclipse将控制台输出信息保存为文件

    当你在Eclipse中 running/debugging一个应用程序的时候,有关该应用程序的运行调试信息及日志信息都会输出到控制台(console )显示,但是Eclipse只会显示最后一部分的日志 ...

  8. openwrt 下python程序后台运行,并将打印信息保存文件

    python -u gw20191223.py  > test.log 1 2 & "python" 表示执行python代码 "-u" 表示不启 ...

  9. 解决在web项目使用log4j中无法将log信息写入文件

    这是log4j.properties中关于的配置 log4j.appender.appender2.File=F:/myeclipseworkspace2/SecondBook2/log/second ...

随机推荐

  1. Python爬虫进阶六之多进程的用法

    前言 在上一节中介绍了thread多线程库.python中的多线程其实并不是真正的多线程,并不能做到充分利用多核CPU资源. 如果想要充分利用,在python中大部分情况需要使用多进程,那么这个包就叫 ...

  2. GO语言.树莓派.环境安装和测试

    Go是Google开发的一种静态强类型.编译型.并发型,并具有垃圾回收功能的编程语言.为了方便搜索和识别,有时会将其称为Golang 记录一下如何在树莓派上安装语言环境 第一步: 下载安装包 http ...

  3. 使用jvisualvm

    jvisualvm是java开发,调试,监控,分析内存的一个可视化工具,可以在安装完JDK中找到,一般在bin目录下 之前调试tomca内存分配,现在总结下心得, windows下的tomcat修改c ...

  4. copy.copy()与copy.deepcopy()的详解

    copy.copy() 元组和列表调用这个方法效果也不一样. 元组的效果: a = [1,2,3] b = [4,5,6] c = (a,b) e = copy.copy(c) 可以看到:e和c是指向 ...

  5. JAVA中正则表达式总结

    昨天,我的朋友请教我正则表达式.我也好久没有写过正则表达式了,昨天刚好看了下如鹏网创始人杨中科老师关于正则表达式的讲解.使我加深了正则表达式的印像.现我把他总结下: 许多语言,包括Perl.PHP.P ...

  6. 【毕业】-《伯恩茅斯大学毕业证书》BU一模一样原件

    ☞伯恩茅斯大学毕业证书[微/Q:2544033233◆WeChat:CC6669834]UC毕业证书/联系人Alice[查看点击百度快照查看][留信网学历认证&博士&硕士&海归 ...

  7. 谈谈volatile关键字以及常见的误解

    转载请保留以下声明 作者:赵宗晟 出处:https://www.cnblogs.com/zhao-zongsheng/p/9092520.html 近期看到C++标准中对volatile关键字的定义, ...

  8. Discuz3.4-SSRF-从触发点到构造payload

    目录 SSRF逆向分析 0x00 前言 0x01 收集情报 0x02 尝试逆向找到触发点 0x03 尝试构造payload 0x04 总结 SSRF逆向分析 0x00 前言 之前有复现过一些漏洞,但是 ...

  9. SVM分类器实现实例

    我正在做一个关于SVM的小项目,在我执行验证SVM训练后的模型的时候,得到的report分数总是很高,无论是召回率(查全率).精准度.还是f1-score都很高: 图1 分类器分数report 但是, ...

  10. appium-desktop录制脚本二次开发,生成我司自动化脚本

    目的 通过对appium-desktop脚本录制功能进行二次开发,使录制的java脚本符合我司自动化框架要求. 实现步骤 1.增加元素名称的输入框 由于ATK(我司自动化测试框架)脚本中元素是以“ap ...