Dav*_*vid 109 android logcat android-logcat
我想阅读并回应我的应用程序中的logcat日志.
我找到了以下代码:
try {
Process process = Runtime.getRuntime().exec("logcat -d");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
StringBuilder log=new StringBuilder();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
}
TextView tv = (TextView)findViewById(R.id.textView1);
tv.setText(log.toString());
}
catch (IOException e) {}
Run Code Online (Sandbox Code Playgroud)
此代码确实返回在应用程序启动之前所做的logcat日志 -
但是有可能连续监听甚至新的logcat日志吗?
Lui*_*uis 55
只需删除上面代码中的"-d"标志,即可继续阅读日志.
"-d"标志指示logcat显示日志内容并退出.如果删除该标志,logcat将不会终止并继续发送添加到其中的任何新行.
请记住,如果设计不正确,可能会阻止您的应用程序.
祝好运.
use*_*087 22
随着协同程序和官方的生命周期livedata-KTX和生命周期-视图模型- KTX库,它的简单这样的:
class LogCatViewModel : ViewModel() {
fun logCatOutput() = liveData(viewModelScope.coroutineContext + Dispatchers.IO) {
Runtime.getRuntime().exec("logcat -c")
Runtime.getRuntime().exec("logcat")
.inputStream
.bufferedReader()
.useLines { lines -> lines.forEach { line -> emit(line) }
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法
val logCatViewModel by viewModels<LogCatViewModel>()
logCatViewModel.logCatOutput().observe(this, Observer{ logMessage ->
logMessageTextView.append("$logMessage\n")
})
Run Code Online (Sandbox Code Playgroud)
您可以使用此方法清除您的logcat,我将其用于在将logcat写入文件后清除,以避免重复的行:
public void clearLog(){
try {
Process process = new ProcessBuilder()
.command("logcat", "-c")
.redirectErrorStream(true)
.start();
} catch (IOException e) {
}
}
Run Code Online (Sandbox Code Playgroud)
小智 8
根据 @user1185087 的回答,没有 ViewModel 的简单解决方案可能是:
在 IO 线程上启动作业:
// Custom scope for collecting logs on IO threads.
val scope = CoroutineScope(Job() + Dispatchers.IO)
val job = scope.launch {
Runtime.getRuntime().exec("logcat -c") // Clear logs
Runtime.getRuntime().exec("logcat") // Start to capture new logs
.inputStream
.bufferedReader()
.useLines { lines ->
// Note that this forEach loop is an infinite loop until this job is cancelled.
lines.forEach { newLine ->
// Check whether this job is cancelled, since a coroutine must
// cooperate to be cancellable.
ensureActive()
// TODO: Write newLine into a file or buffer or anywhere appropriate
}
}
}
Run Code Online (Sandbox Code Playgroud)
从主线程取消作业:
MainScope().launch {
// Cancel the job and wait for its completion on main thread.
job.cancelAndJoin()
job = null // May be necessary
// TODO: Anything else you may want to clean up
}
Run Code Online (Sandbox Code Playgroud)
如果您想在后台线程上连续收集应用程序的新日志,此解决方案应该足够了。
这是一个快速组合/插入,可用于捕获所有当前或所有新的(自上次请求以来)日志项。
您应该修改/扩展它,因为您可能想要返回连续流而不是 LogCapture。
Android LogCat“手册”:https://developer.android.com/studio/command-line/logcat.html
import android.util.Log;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Stack;
/**
* Created by triston on 6/30/17.
*/
public class Logger {
// http://www.java2s.com/Tutorial/Java/0040__Data-Type/SimpleDateFormat.htm
private static final String ANDROID_LOG_TIME_FORMAT = "MM-dd kk:mm:ss.SSS";
private static SimpleDateFormat logCatDate = new SimpleDateFormat(ANDROID_LOG_TIME_FORMAT);
public static String lineEnding = "\n";
private final String logKey;
private static List<String> logKeys = new ArrayList<String>();
Logger(String tag) {
logKey = tag;
if (! logKeys.contains(tag)) logKeys.add(logKey);
}
public static class LogCapture {
private String lastLogTime = null;
public final String buffer;
public final List<String> log, keys;
LogCapture(String oLogBuffer, List<String>oLogKeys) {
this.buffer = oLogBuffer;
this.keys = oLogKeys;
this.log = new ArrayList<>();
}
private void close() {
if (isEmpty()) return;
String[] out = log.get(log.size() - 1).split(" ");
lastLogTime = (out[0]+" "+out[1]);
}
private boolean isEmpty() {
return log.size() == 0;
}
public LogCapture getNextCapture() {
LogCapture capture = getLogCat(buffer, lastLogTime, keys);
if (capture == null || capture.isEmpty()) return null;
return capture;
}
public String toString() {
StringBuilder output = new StringBuilder();
for (String data : log) {
output.append(data+lineEnding);
}
return output.toString();
}
}
/**
* Get a list of the known log keys
* @return copy only
*/
public static List<String> getLogKeys() {
return logKeys.subList(0, logKeys.size() - 1);
}
/**
* Platform: Android
* Get the logcat output in time format from a buffer for this set of static logKeys.
* @param oLogBuffer logcat buffer ring
* @return A log capture which can be used to make further captures.
*/
public static LogCapture getLogCat(String oLogBuffer) { return getLogCat(oLogBuffer, null, getLogKeys()); }
/**
* Platform: Android
* Get the logcat output in time format from a buffer for a set of log-keys; since a specified time.
* @param oLogBuffer logcat buffer ring
* @param oLogTime time at which to start capturing log data, or null for all data
* @param oLogKeys logcat tags to capture
* @return A log capture; which can be used to make further captures.
*/
public static LogCapture getLogCat(String oLogBuffer, String oLogTime, List<String> oLogKeys) {
try {
List<String>sCommand = new ArrayList<String>();
sCommand.add("logcat");
sCommand.add("-bmain");
sCommand.add("-vtime");
sCommand.add("-s");
sCommand.add("-d");
sCommand.add("-T"+oLogTime);
for (String item : oLogKeys) sCommand.add(item+":V"); // log level: ALL
sCommand.add("*:S"); // ignore logs which are not selected
Process process = new ProcessBuilder().command(sCommand).start();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
LogCapture mLogCapture = new LogCapture(oLogBuffer, oLogKeys);
String line = "";
long lLogTime = logCatDate.parse(oLogTime).getTime();
if (lLogTime > 0) {
// Synchronize with "NO YEAR CLOCK" @ unix epoch-year: 1970
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date(oLogTime));
calendar.set(Calendar.YEAR, 1970);
Date calDate = calendar.getTime();
lLogTime = calDate.getTime();
}
while ((line = bufferedReader.readLine()) != null) {
long when = logCatDate.parse(line).getTime();
if (when > lLogTime) {
mLogCapture.log.add(line);
break; // stop checking for date matching
}
}
// continue collecting
while ((line = bufferedReader.readLine()) != null) mLogCapture.log.add(line);
mLogCapture.close();
return mLogCapture;
} catch (Exception e) {
// since this is a log reader, there is nowhere to go and nothing useful to do
return null;
}
}
/**
* "Error"
* @param e
*/
public void failure(Exception e) {
Log.e(logKey, Log.getStackTraceString(e));
}
/**
* "Error"
* @param message
* @param e
*/
public void failure(String message, Exception e) {
Log.e(logKey, message, e);
}
public void warning(String message) {
Log.w(logKey, message);
}
public void warning(String message, Exception e) {
Log.w(logKey, message, e);
}
/**
* "Information"
* @param message
*/
public void message(String message) {
Log.i(logKey, message);
}
/**
* "Debug"
* @param message a Message
*/
public void examination(String message) {
Log.d(logKey, message);
}
/**
* "Debug"
* @param message a Message
* @param e An failure
*/
public void examination(String message, Exception e) {
Log.d(logKey, message, e);
}
}
Run Code Online (Sandbox Code Playgroud)
在执行活动日志记录的项目中:
Logger log = new Logger("SuperLog");
// perform logging methods
Run Code Online (Sandbox Code Playgroud)
当您想捕获通过“Logger”记录的所有内容时
LogCapture capture = Logger.getLogCat("main");
Run Code Online (Sandbox Code Playgroud)
当您饿了并且想吃更多原木时
LogCapture nextCapture = capture.getNextCapture();
Run Code Online (Sandbox Code Playgroud)
您可以将捕获作为字符串获取
String captureString = capture.toString();
Run Code Online (Sandbox Code Playgroud)
或者您可以使用以下命令获取捕获的日志项
String logItem = capture.log.get(itemNumber);
Run Code Online (Sandbox Code Playgroud)
没有确切的静态方法来捕获外部日志键,但仍然有一种方法
LogCapture foreignCapture = Logger.getLogCat("main", null, foreignCaptureKeyList);
Run Code Online (Sandbox Code Playgroud)
使用上述方法还可以让您调用Logger.this.nextCapture外国捕获。
| 归档时间: |
|
| 查看次数: |
63262 次 |
| 最近记录: |