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

前言

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

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

效果图

存储在应用内的目录:

logcat-2018-08-14.log 

2018-08-14 10:18:06  I/art     (24242): Late-enabling -Xcheck:jni
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
2018-08-14 10:18:06 E/Process (24242): android_os_Process_getProcessNameByPid pid is 24242
2018-08-14 10:18:06 E/Process (24242): android_os_Process_getProcessNameByPid value is ogcathelperdemo
2018-08-14 10:18:06 V/MainActivity(24242): 这是V日志
2018-08-14 10:18:06 D/MainActivity(24242): 这是D日志
2018-08-14 10:18:06 I/MainActivity(24242): 这是I日志
2018-08-14 10:18:06 W/MainActivity(24242): 这是W日志
2018-08-14 10:18:06 E/MainActivity(24242): 这是E日志
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}
2018-08-14 10:18:06 D/OpenGLRenderer(24242): Dumper init 4 threads <0x7f84d321c0>
2018-08-14 10:18:06 D/OpenGLRenderer(24242): <com.why.project.logcathelperdemo> is running.
2018-08-14 10:18:06 D/OpenGLRenderer(24242): <com.why.project.logcathelperdemo> setHwuiLog: debug.egl.trace=false
2018-08-14 10:18:06 D/OpenGLRenderer(24242): initialize DisplayEventReceiver 0x7f8ac1a400
2018-08-14 10:18:06 D/OpenGLRenderer(24242): Use EGL_SWAP_BEHAVIOR_PRESERVED: true
2018-08-14 10:18:06 D/Atlas (24242): Validating map...
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}
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}
2018-08-14 10:18:06 D/OpenGLRenderer(24242): CanvasContext() 0x7f8ac1db40 initialize 0x7f91e3c610
2018-08-14 10:18:06 D/MALI (24242): eglInitialize:1479: [+]
2018-08-14 10:18:06 E/GED (24242): Failed to get GED Log Buf, err(0)
2018-08-14 10:18:06 D/MALI (24242): eglInitialize:1850: [-]
2018-08-14 10:18:06 I/ (24242): elapse(include ctx switch):3533 (ms), eglInitialize
2018-08-14 10:18:06 I/OpenGLRenderer(24242): Initialized EGL, version 1.4
2018-08-14 10:18:06 D/MALI (24242): eglCreateContext:206: [MALI] eglCreateContext display 0x7f91c5fd00, share context 0x0 here.
2018-08-14 10:18:06 D/MALI (24242): gles_context_new:248: Create GLES ctx 0x7f8ae8a008 successfully
2018-08-14 10:18:06 D/MALI (24242): eglCreateContext:543: [MALI] eglCreateContext end. Created context 0x7f8ae7ad80 here.
2018-08-14 10:18:06 D/OpenGLRenderer(24242): Created EGL context (0x7f8ae37040)
2018-08-14 10:18:06 I/OpenGLRenderer(24242): Get enable program binary service property (1)
2018-08-14 10:18:06 I/OpenGLRenderer(24242): Initializing program atlas...
2018-08-14 10:18:06 D/ProgramBinary/Service(24242): BpProgramBinaryService.getFileDescriptor
2018-08-14 10:18:06 D/ProgramBinary/Service(24242): BpProgramBinaryService.getProgramMapLen
2018-08-14 10:18:06 D/ProgramBinary/Service(24242): BpProgramBinaryService.getProgramMapArray
2018-08-14 10:18:06 D/ProgramBinary/Service(24242): BpProgramBinaryService.getProgramBinaryLen
2018-08-14 10:18:06 I/OpenGLRenderer(24242): Program binary detail: Binary length is 169984, program map length is 152.
2018-08-14 10:18:06 I/OpenGLRenderer(24242): Succeeded to mmap program binaries. File descriptor is 46, and path is /dev/ashmem{.
2018-08-14 10:18:06 I/OpenGLRenderer(24242): No need to use file discriptor anymore, close fd(46).
2018-08-14 10:18:06 D/OpenGLRenderer(24242): TaskManager() 0x7f8acff1f0, cpu = 8, thread = 4
2018-08-14 10:18:06 D/OpenGLRenderer(24242): Initializing program cache from 0x0, size = -1
2018-08-14 10:18:06 D/OpenGLRenderer(24242): Enabling debug mode 0
2018-08-14 10:18:06 D/Surface (24242): Surface::connect(this=0x7f91e3c600,api=1)
2018-08-14 10:18:06 D/mali_winsys(24242): new_window_surface returns 0x3000
2018-08-14 10:18:06 D/Surface (24242): Surface::allocateBuffers(this=0x7f91e3c600)
2018-08-14 10:18:06 D/OpenGLRenderer(24242): [TaskMgr] Running thread hwuiTask1 (24290)
2018-08-14 10:18:06 W/MALI (24242): glDrawArrays:714: [MALI] glDrawArrays takes more than 5ms here. Total elapse time(us): 6667
2018-08-14 10:18:06 D/OpenGLRenderer(24242): ProgramCache save to disk, size = 3
2018-08-14 10:18:06 V/InputMethodManager(24242): onWindowFocus: null softInputMode=288 first=true flags=#81810100
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
2018-08-14 10:18:06 D/InputMethodManager(24242): receive service's setActive call, active:true
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包复制到项目中

package com.why.project.logcathelperdemo.logcathelper;

import android.content.Context;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader; /**
* Created by HaiyuKing
* Used log日志统计保存到本地文件
* 参考资料 Android将应用log信息保存文件:http://www.cnblogs.com/weixing/p/3414164.html
*/
public class LogcatHelper {
private static LogcatHelper INSTANCE = null;
/**日志文件保存路径*/
private static String PATH_LOGCAT;
private LogDumper mLogDumper = null;
/**应用进程ID*/
private int mPId; /**初始化目录 "包名+logcat"
* */
public void init(Context context) {
// if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {// 优先保存到SD卡中
// PATH_LOGCAT = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + context.getPackageName() + File.separator + "logcat";
// } else {
//如果SD卡不存在,就保存到本应用的目录下【why 直接保存到本应用的目录下】
PATH_LOGCAT = context.getFilesDir().getAbsolutePath() + File.separator + "logcat";
// }
File file = new File(PATH_LOGCAT);
if (!file.exists()) {
file.mkdirs();
}
}
/**单例模式
* */
public static LogcatHelper getInstance(Context context) {
if (INSTANCE == null) {
INSTANCE = new LogcatHelper(context);
}
return INSTANCE;
} private LogcatHelper(Context context) {
init(context);
mPId = android.os.Process.myPid();
} public void start() {
if (mLogDumper == null)
mLogDumper = new LogDumper(String.valueOf(mPId), PATH_LOGCAT);
mLogDumper.start();
} public void stop() {
if (mLogDumper != null) {
mLogDumper.stopLogs();
mLogDumper = null;
}
} private class LogDumper extends Thread { private Process logcatProc;
private BufferedReader mReader = null;
private boolean mRunning = true;
String cmds = null;
private String mPID;
private FileOutputStream out = null; public LogDumper(String pid, String dir) {
mPID = pid;
try {
out = new FileOutputStream(new File(dir, "logcat-" + MyDate.getFileName() + ".log"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} /**
*
* 日志等级:*:v , *:d , *:w , *:e , *:f , *:s
*
* 显示当前mPID程序的 E和W等级的日志.
*
* */ // cmds = "logcat *:e *:w | grep \"(" + mPID + ")\"";
cmds = "logcat | grep \"(" + mPID + ")\"";//打印所有日志信息
// cmds = "logcat -s way";//打印标签过滤信息
//cmds = "logcat *:e *:i | grep \"(" + mPID + ")\""; } public void stopLogs() {
mRunning = false;
} @Override
public void run() {
try {
logcatProc = Runtime.getRuntime().exec(cmds);
mReader = new BufferedReader(new InputStreamReader(logcatProc.getInputStream()), 1024);
String line = null;
while (mRunning && (line = mReader.readLine()) != null) {
if (!mRunning) {
break;
}
if (line.length() == 0) {
continue;
}
if (out != null && line.contains(mPID)) {
out.write((MyDate.getDateEN() + " " + line + "\n")
.getBytes());
}
} } catch (IOException e) {
e.printStackTrace();
} finally {
if (logcatProc != null) {
logcatProc.destroy();
logcatProc = null;
}
if (mReader != null) {
try {
mReader.close();
mReader = null;
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
out = null;
}
}
}
}
}

LogcatHelper.java

package com.why.project.logcathelperdemo.logcathelper;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale; /**
* Created by HaiyuKing
* Used
*/
public class MyDate {
public static String getFileName() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd",Locale.CHINA);
String date = format.format(new Date(System.currentTimeMillis()));
return date;// 2012-10-03
} public static String getDateEN() {
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.CHINA);
String date1 = format1.format(new Date(System.currentTimeMillis()));
return date1;// 2012-10-03 23:41:31
}
}

MyDate.java

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

package com.why.project.logcathelperdemo;

import android.app.Application;

import com.why.project.logcathelperdemo.logcathelper.LogcatHelper;

/**
* Created by HaiyuKing
* Used 自定义application
*/ public class MyApplication extends Application{
@Override
public void onCreate() {
super.onCreate();
//在应用中start LogcatHelper
LogcatHelper.getInstance(this).start();
} @Override
public void onTerminate() {
super.onTerminate();
//在应用中stop LogcatHelper
LogcatHelper.getInstance(this).stop();
} @Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
} }

(3)在AndroidManifest.xml中申请MyApplication

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.why.project.logcathelperdemo"> <application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application> </manifest>

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

三、使用方法

正常执行Log方法即可。

package com.why.project.logcathelperdemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log; import com.why.project.logcathelperdemo.logcathelper.LogcatHelper; public class MainActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); Log.v("MainActivity", "这是V日志");
Log.d("MainActivity", "这是D日志");
Log.i("MainActivity", "这是I日志");
Log.w("MainActivity", "这是W日志");
Log.e("MainActivity", "这是E日志");
} @Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy(); //使用完后,调用stop
LogcatHelper.getInstance(getApplicationContext()).stop();
}
}

混淆配置

参考资料

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. Asp.Net Core NLog 将日志输出到数据库以及添加LayoutRenderer的支持

    在这之前打算用Apache的Log4Net,但是发现其AdoNetAppender方法已经不存在了,无法使用配置文件直接输出到数据库了,因此我便改用了NLog框架. 一.对项目添加NLog 通过Nug ...

  2. 用Java为Hyperledger Fabric(超级账本)开发区块链智能合约链代码之部署与运行示例代码

    部署并运行 Java 链代码示例 您已经定义并启动了本地区块链网络,而且已构建 Java shim 客户端 JAR 并安装到本地 Maven 存储库中,现在已准备好在之前下载的 Hyperledger ...

  3. logrus_hook.go

    package) //表示自身栈中跳过6个,:]     entry.Data["file"] = fileName     entry.Data["func" ...

  4. OpenGL执行渲染图片的主要操作步骤

    一个用来执行图形渲染的OpenGL程序的主要步骤包括: 1.从OpenGL的几何图元中设置数据,用于构建形状: 2.使用不用的着色器(shader)对输入的图元数据进行进行计算,判断它们的位置.颜色以 ...

  5. 【莫比乌斯反演】BZOJ2005 [NOI2010]能量采集

    Description 求sigma gcd(x,y)*2-1,1<=x<=n, 1<=y<=m.n, m<=1e5. Solution f(n)为gcd正好是n的(x, ...

  6. Linux vim常用命令

    什么是 vim? Vim是从 vi 发展出来的一个文本编辑器.代码补完.编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用. 简单的来说, vi 是老式的字处理器,不过功能已经很齐全了,但是 ...

  7. python--装饰器(附偏函数、断言)

    博客地址:http://www.cnblogs.com/yudanqu/ 概念:装饰器是一个闭包,把一个函数当做参数返回一个替代版的函数,本质上就是一个返回函数的函数 装饰器就是在我们需要的一个函数外 ...

  8. 新手篇丨Python任意网段Web端口信息探测工具

    你学习Python的目的是什么?是想写爬虫爬取数据(数据.图片等内容),还是想自写自动化的小工具,又或是作为一个新手小白单纯的欣赏这门语言呢? 今天i春秋分享的是一篇关于多线程工具的文章,工具使用效率 ...

  9. SpringBoot之旅第五篇-数据访问

    一.引言 大部分系统都离不开数据访问,数据库包括SQL和NOSQL,SQL是指关系型数据库,常见的有SQL Server,Oracle,MySQL(开源),NOSQL是泛指非关系型数据库,常见的有Mo ...

  10. 『神坑』DotNetty 内存泄漏 解决办法

    背景 近来在用 DotNetty 实现一个文件上传下载的同步服务. 其中:客户端下载服务端的文件,客户端多次请求,从服务端将文件分片下载下来,追加到本地磁盘. —— 非常简单的代码,都写了几十次了,驾 ...