gpt4 book ai didi

android - 定期 LogCat 轮询更新并保存到 SD 卡

转载 作者:行者123 更新时间:2023-11-29 02:03:01 26 4
gpt4 key购买 nike

目标

收集 LogCat 的定期更新并将这些文本 block 保存(附加)到 SD 卡上的文件中

问题

Log 类不提供自特定时间戳以来的更新

可能的解决方案

我的计划是定期运行类似于以下代码:http://www.helloandroid.com/tutorials/reading-logs-programaticallyhttps://stackoverflow.com/a/9039352/550471

但是,有一个显着的区别:使用 -v time 参数来确保每一行都带有时间戳。

每次收集 LogCat 数据后,应用程序将存储最后一个 Log 条目的时间戳。下次收集 LogCat 数据时,应用程序将搜索文本以查找时间戳,然后将数据 block 保存到自指定时间戳以来添加到日志中的 sdcard。

可能的问题

如果 LogCat 数据的收集周期太短,则 CPU 会忙于处理大量“旧”数据。如果 Logcat 数据的收集时间过长,则可能会遗漏一些数据。

有没有更好的办法?

最佳答案

这就是我想出的 - 它在不卡住时效果很好。

您可能知道,Runtime.getRuntime().exec("") 很可能比 Jelly Bean 更早地在 Android 中引起 ANR。如果有人有克服 ANR 的解决方案,请分享。

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;

import android.os.Environment;
import android.util.Log;

/*
* For (compressed) buffer sizes, see: http://elinux.org/Android_Logging_System
* buffer:main = 64KB
* buffer:radio = 64KB
* buffer:system = 64KB
* buffer:event = 256KB
*
* NOTE: the 'command' must include "-d -v time" !!
* to switch buffers, use "-b <buffer>"
*/
public class LogCatReader {
// constants
private static final String CR = "\r\n";
private static final String END_OF_DATE_TIME = "): ";
private static final int DEFAULT_SEARCH_START_INDEX = 0;

// member variables
private StringBuilder mLog;
private LogThread mLogThread = null;
private String mLastLogReadToken = "";
private String mLogCommand = "";
private int mStringCapacity;
private File mFileTarget = null;

// constructor
public LogCatReader(String command, int capacity) {
mLogCommand = command;
mStringCapacity = capacity;
}

// returns complete logcat buffer
// note: takes about 1.5sec to finish
synchronized public StringBuilder getLogComplete() {
try {
// capacity should be about 25% bigger than buffer size since the
// buffer is compressed
mLog = new StringBuilder(mStringCapacity);

// command to capture log
Process process = Runtime.getRuntime().exec(mLogCommand);
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));

String line;
while ((line = bufferedReader.readLine()) != null) {
// append() is costly if capacity needs to be increased, be sure
// to reserve enough in the first place
mLog.append(line + CR);
}
} catch (IOException e) {
}

return mLog;
}

public String getLogUpdatesOnly() {
String strReturn = "";

StringBuilder sbLog = getLogComplete();

try {
int iStartindex = DEFAULT_SEARCH_START_INDEX;

// if there exists a token from a previous search then use that
if (mLastLogReadToken.length() > 0) {
iStartindex = sbLog.indexOf(mLastLogReadToken);

// if string not found then start at beginning
if (iStartindex == -1) {
// start search at beginning of log
iStartindex = DEFAULT_SEARCH_START_INDEX;
}
}

int iEndindex = sbLog.length();

// if token is found then move index to the next line
if (iStartindex > DEFAULT_SEARCH_START_INDEX) {
iStartindex = sbLog.indexOf(CR, iStartindex);

if (iStartindex != -1) {
iStartindex += CR.length();
} else {
// return an empty string
iStartindex = iEndindex;
}
}

// grab the data between the start and end indices
strReturn = sbLog.substring(iStartindex, iEndindex);

// grab date/time token for next search
iStartindex = sbLog.lastIndexOf(END_OF_DATE_TIME);

if (iStartindex != -1) {
iEndindex = iStartindex;
iStartindex = sbLog.lastIndexOf(CR, iEndindex);
iStartindex += CR.length();

if (iStartindex == -1) {
// read from beginning
iStartindex = 0;
}

mLastLogReadToken = sbLog.substring(iStartindex, iEndindex);
}
} catch (Exception e) {
strReturn = "";
}

return strReturn;
}

public void startPeriodicLogCatReader(int timePeriod, String logfilename) {
if (mLogThread == null) {
mLogThread = new LogThread(timePeriod, logfilename);
mLogThread.start();
}
}

public void stopPeriodicLogCatReader() {
if (mLogThread != null) {
mLogThread.interrupt();
mLogThread = null;
}
}

private class LogThread extends Thread {
private boolean mInterrupted;
private int mTimePeriod;// in seconds
private String mLogref;
private BufferedWriter mBuffWriter = null;
public boolean mPauseLogCollection = false;

// constructor: logfilename is optional - pass null to not use
public LogThread(int timePeriod, String logfilename) {
mTimePeriod = timePeriod;

if (logfilename != null) {
File fLogFolder = new File(
Environment.getExternalStorageDirectory() + "/logfiles");
if (fLogFolder.exists() == false) {
if (fLogFolder.mkdirs() == false) {
Log.e("LogCatReader",
"Could not create "
+ fLogFolder.getAbsolutePath());
}
}

mFileTarget = new File(
Environment.getExternalStorageDirectory() + "/logfiles",
logfilename);

if (mFileTarget.exists() == false) {
try {
// file doesn't yet exist - create a fresh one !
mFileTarget.createNewFile();
} catch (IOException e) {
e.printStackTrace();
mFileTarget = null;
}
}
}
}

@Override
public void interrupt() {
mInterrupted = true;
super.interrupt();
}

@Override
public void run() {
super.run();

// initialization
mInterrupted = false;

// set up storage
if (mFileTarget != null) {
try {
mBuffWriter = new BufferedWriter(new FileWriter(
mFileTarget, true), 10240);
} catch (IOException e) {
e.printStackTrace();
}
}

while ((mInterrupted == false) && (mBuffWriter != null)) {
if (mPauseLogCollection == false) {
// read log updates
mLogref = getLogUpdatesOnly();

// save log updates to file
try {
mBuffWriter.append(mLogref);
mBuffWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}

if (!mInterrupted) {
try {
sleep(mTimePeriod * 1000);
} catch (InterruptedException e) {
}
}
}

if (mBuffWriter != null) {
try {
mBuffWriter.close();
mBuffWriter = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}// end of inner class
}// end of outer class

我用来仅查找更新的过程是捕获 logcat 最后一行的日期和时间,并在下次使用它作为搜索标记。

要使用这个类,下面是一个例子:

        LogCatReader logcatPeriodicReader = new LogCatReader("logcat -b main -d -v time", 80 * 1024);//collect "main" buffer, exit after reading logcat
logcatPeriodicReader.startPeriodicLogReader(90, "log.txt");//read logcat every 90 secs

关于android - 定期 LogCat 轮询更新并保存到 SD 卡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11570458/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com