Android 日志写入不成功,充分利用logcat的AndroidRuntime异常和写入文件

本文介绍了如何利用logcat的AndroidRuntime异常信息,并通过自定义的LogCatReader类将错误日志写入Android设备的SD卡上。作者遇到的问题是,adb logcat命令在Windows上有效,但在Android设备上无法正常工作。他们希望只记录导致应用程序执行ANR的AndroidRuntime错误,而不是依赖于Log.d, Log.e等常规日志输出。" 53871830,1354672,分治策略解决POJ 1854问题 - G++实现,"['算法', '分治', '搜索', '编程语言-G++', '竞赛编程']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当我浏览到Android的SDK文件夹下我platform-tools文件夹,我能够执行一些操作,所以我可以从LogCat充分利用logcat的AndroidRuntime异常和写入文件

得到输出,如该命令实例

adb logcat AndroidRuntime:E *:E

这将列出带有标记AndroidRuntime的消息。为了测试这个我在onResume方法去除super.onResume(),输出会是这个样子在我的命令行窗口,在Win7:

f68b2128f9a6383d392239a91114f333.png

到目前为止好,这是我想要的信息的类型登录。我在我的应用程序的方法,看起来像这样:

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 String mProcess = "";

private int mStringCapacity;

private File mFileTarget = null;

// constructor

public LogCatReader(String command, int capacity, String process) {

mLogCommand = command;

mStringCapacity = capacity;

mProcess = process;

}

// 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() + "/SteriaFITMobile/CoreLogging");

if (fLogFolder.exists() == false) {

if (fLogFolder.mkdirs() == false) {

Log.e("LogCatReader",

"Could not create "

+ fLogFolder.getAbsolutePath());

}

}

mFileTarget = new File(

Environment.getExternalStorageDirectory() + "/SteriaFITMobile/CoreLogging",

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 = mProcess + ": " + 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

这个方法有三个参数,命令,能力和processName(ActivityName)。

此方法只是执行command parameter到Runtime.getRuntime().exec方法调用,并将其保存到SD卡上的.txt文件。我的问题是,命令

adb logcat AndroidRuntime:E *:E

工作在Windows中,但不是在Android手机上。

我想实现的是将此类AndroidRuntime错误注销到SD卡上的日志文件。我只对导致我的应用程序执行ANR的AndroidRuntime错误感兴趣。

有些人可能认为我只是创建自己的Log.d, Log.e, Log.v并将它们写入一个文件,但我不希望出现这种情况..

有人可以帮我吗?

+0

那么解释你为什么不直接使用自定义标记输出logcat的错误?似乎不是试图重新创建轮子,而应该使用现有的功能。 –

2013-04-26 13:20:33

+0

在Android手机上,您只需使用'logcat'命令。 –

2013-04-26 13:22:59

+0

@Booger我不确定是否有任何其他方式注销AndroidRuntime异常,而不在'Try/Catch'中执行。在我的例子中,我应该如何记录我忘记'super.onPause'? –

2013-04-26 13:23:57

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值