在应用程序关闭时刷新 RxJava 缓冲区

Flushing RxJava buffer on application close

我使用 Timber 编写了一个 FileTree 记录器,它将 Android 日志写入磁盘上的文件。我缓冲日志,每 2 分钟或 100 条日志消息刷新到磁盘,以先到者为准。缓冲区防止每条日志消息触发 IO 写入,以免因立即写入每条日志消息而使 IO 资源过载。

我正在使用 RxJava 来处理这个任务。一小段(摘自 here):

logBuffer.observeOn(Schedulers.computation())
    .doOnEach((log) -> {
        processed++;

        if(processed % 100 == 0) {
            flush();
        }
    })
    .buffer(flush.mergeWith(Observable.interval(2, TimeUnit.MINUTES)))
    .subscribeOn(Schedulers.io())
    .subscribe((logs) -> {
        // Flush the logs to the file
        try {
            File logFile = new File(logDir, "app.log");

            FileWriter fw = new FileWriter(logFile, true);

            for(LogMessage msg : logs) {
                fw.append(msg.toString());
            }

            fw.flush();

            flushCompleted.onNext(logFile.length());
        } catch(Exception e) {
            Timber.e(e, "Failed to flush logs");
        }
    });        

如果我需要手动触发同花顺,我会使用“同花顺”主题。 我在 ApplicationonCreate():

中种植 FileTree in Timber
public class App extends Application {

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

        Timber.plant(new Timber.DebugTree(), new FileTree(getApplicationContext()));
    }
}

这也是设置 RxJava 订阅的地方。我有两个问题:

  1. 无需在每个 activity 完成时复制该代码,您可以使用 BaseActivity,或使用 Application's activity 状态回调 API ( https://developer.android.com/reference/android/app/Application#registerActivityLifecycleCallbacks(android.app.Application.ActivityLifecycleCallbacks) ).

我应该注意,为了选择要刷新的生命周期方法,onPause() 之后的任何方法都不能保证被 OS 调用。如果操作系统需要为低内存终止您的应用程序,则不能保证 onDestroy() 会被调用(而是它只会终止您的进程)。

引用https://developer.android.com/reference/android/app/Activity :

Note the "Killable" column in the above table -- for those methods that are marked as being killable, after that method returns the process hosting the activity may be killed by the system at any time without another line of its code being executed. Because of this, you should use the onPause() method to write any persistent data (such as user edits) to storage



  1. 如果您的代码 'lifecycle' 与应用程序的代码相同,则完全可以忽略订阅结果(因为您永远不会处理订阅)。只要确保你没有在那个范围内捕获需要更短生命周期的部分(例如,不要在那里保留对 activity 上下文的引用,否则你会泄漏它)