在调试app时,经常出现偶现bug,十分难以调试,但bug出现时,我们往往来不及获取log来进行分析。
以下代码的功能就是当这些bug出现时,记录下当时的log。
/**
*
* @param isError 判断条件
* @param activity
* @param logFileName log文件的名字, 该log文件会出现在当前app的files/中,即 /data/data/com.test.demo/files/ 中
* @Function
* @TODO TODO
*/
public static void checkAndSavaLog(boolean isError, final Activity activity,
final String logFileName) {
if (isError) {
saveLogAsFile(activity, logFileName);
}
}
private static void saveLogAsFile(final Activity activity, final String logFileName) {
Runnable networkTask = new Runnable() {
@Override
public void run() {
// TODO
try {
ArrayList<String> cmdLine = new ArrayList<String>();
cmdLine.add("logcat");
cmdLine.add("-d");
ArrayList<String> clearLog = new ArrayList<String>();
clearLog.add("logcat");
clearLog.add("-c");
Process process = Runtime.getRuntime()
.exec(cmdLine.toArray(new String[cmdLine.size()]));
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
StringBuffer sb = new StringBuffer();
String str = null;
while ((str = bufferedReader.readLine()) != null) {
sb.append(str);
sb.append(System.getProperty("line.separator"));
}
Runtime.getRuntime().exec(clearLog.toArray(new String[clearLog.size()]));
if (sb.toString().isEmpty()) {
Log.e(TAG, "Why? do not get the log!");
}
writeFileData(activity.getApplication(), logFileName, sb.toString());
}
catch (Exception e) {
e.printStackTrace();
}
}
};
new Thread(networkTask).start();
}
以上代码中用到了一些读写文件的方法,代码如下:
private static void initContext(Application application) {
Context context = application;
try {
mContext = context.createPackageContext(context.getPackageName(), Context.CONTEXT_INCLUDE_CODE);
} catch (NameNotFoundException e) {
throw new RuntimeException(e);
}
}
/**
*
* @param application
* @param fileName
* @param message
* @Function write message as a file to the path of The App. eg. /data/data/com.test.demo/files/
* @TODO TODO
*/
public static void writeFileData(Application application, String fileName, String message) {
initContext(application);
try {
FileOutputStream fout = mContext.openFileOutput(fileName, Context.MODE_PRIVATE);
byte[] bytes = message.getBytes();
fout.write(bytes);
fout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
使用方法,例如我们发现,同一个客户端传到服务器的userid会莫名其妙的变成另外一个userid,那么就可以在发送userid的地方写下
checkAndSavaLog(userid.equals(userid_before), this, "error.log");
这样当userid发送的跟之前的不一样的时候,就会记录下log信息供以分析。
本功能只是供开发者在调试的时候用,如果想要在发布包中也使用这个功能,就需要加上上传log文件的功能了。
关于上传log文件:
- 如果只是针对一些特定的bug,想要调试,log文件不是很多的情况下,那么就可以借用第三方cdn之类的服务,把log文件上传到cdn,然后开发者去分析
- 如果希望获取一些游戏数据,供以统计分析运营,那么最好还是自己写服务端。而且如果不是有特殊需要,比如数据极为私密重要等等,其他情况下,完全可以使用第三方的数据统计工具,比如talkingdata,activation等等