【问题标题】:Creating log files on external storage in Android. Is there a correct way to do that?在 Android 的外部存储上创建日志文件。有正确的方法吗?
【发布时间】:2015-09-28 21:14:01
【问题描述】:

现在我正在创建一个在发布版本中测试并添加了 proguard 的应用程序。 正如您可能想象的那样,我编写和测试的东西与人们使用的东西之间存在一些差异。有时我会收到一个错误报告,说某些东西不起作用。嗯...它对我有用,对吧?

所以,我的想法是编写某种 LogManager,将新行写入设备上的文本文件。这是我的实现,基本上是有效的:

@Application
public class LogManager {

private static final String TAG = LogManager.class.getSimpleName();
private static final String FOLDER_NAME = "/logs/";
private static final String FILE_NAME = "app_logs.txt";

DateTime dateTime;
DateTimeFormatter parser;
String date;
FileOutputStream fileOutputStream;
File logFile;
Gson gson;

@Inject
public LogManager(Gson gson) {
    parser = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS");
    this.gson = gson;
    createFile();
}

private void createFile(){
    if(isExternalStorageReadable() && isExternalStorageWritable()){
        try {
            File path = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+FOLDER_NAME);
            path.mkdirs();
            logFile = new File(path, FILE_NAME);
            logFile.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

public void log(Object o){
    log(gson.toJson(o));
}

public void log(String text){
    dateTime = new DateTime();
    date = parser.print(dateTime);

    String log = date + "    " + text;
    try{
        fileOutputStream = new FileOutputStream(logFile, true);
        fileOutputStream.write(System.getProperty("line.separator").getBytes());
        fileOutputStream.write(log.getBytes());
        fileOutputStream.close();

    }catch (Exception e) {
        e.printStackTrace();
    }
}

public void printLogs(){
    StringBuilder text = new StringBuilder();

    try {
        BufferedReader br = new BufferedReader(new FileReader(logFile));
        String line;

        while ((line = br.readLine()) != null) {
            text.append(line);
            text.append('\n');
        }
        br.close();
    }
    catch (IOException e) {
        e.printStackTrace();
    }

    L.d(TAG, text.toString());
}

public void deleteLog(){
    L.d(TAG, "Log File deleted: "+logFile.delete());
}

private boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    return Environment.MEDIA_MOUNTED.equals(state);
}

private boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    return Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
}

是的。但是,我不确定它在……将来的使用中会如何表现。例如,当我尝试在不同的踏板上使用它时会发生什么?我知道我会的,因为我正在异步下载很多东西。

所以,我的问题是......有一些“官方”的方式来处理这个问题吗?也许某种日志库? 或者也许我的代码没问题,只需要一些调整?

编辑: 示例用法。

...

@Inject
LogManager logManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_userconfig);
    App.getInstance().appComponent.inject(this);

    logStuff();
}

private void logStuff(){
    logManager.log("abc");
    logManager.log("def");

    logManager.printLogs();
}

因为我使用的是 Dagger2 库,所以所有类中注入的 LogManager 应该是同一个实例。

【问题讨论】:

    标签: android logging error-logging


    【解决方案1】:

    没有官方的方法可以做到这一点。

    看看这 2 个库:HugoTimber

    您的代码存在几个问题:

    • 登录到 Logcat 时,您还应该登录到文件,但在您的代码中 你没有登录到 logcat,没有正确包装它。所以在每一点 你想记录到文件你需要两行。浪费时间 和代码。
    • 您没有添加使用示例,因此我真的不知道有多重要 LogManager 的对象你有,你不应该有多个 处理日志。
    • 没有批量写入文件。不要写入文件 每次您需要记录但批处理。它。
    • 当然在批处理的时候同步会更容易 完成。
    • 在此实现中,当从您正在写入的 UI 线程进行日志记录时 文件,这是不好的做法。不要在 UI 线程上执行任何读/写操作。

    结论—— 你有很多工作要做。这些提示将帮助您创建正确的记录器。

    【讨论】:

    • 感谢您的评论。我编辑了我的帖子,向您展示我的示例用法。我会考虑你的提示:)
    猜你喜欢
    • 1970-01-01
    • 2014-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-21
    • 2020-11-17
    • 1970-01-01
    • 2012-01-13
    相关资源
    最近更新 更多