为什么 activity 在 Android 重新启动其生命周期后,Timber 日志会生成两次日志消息?
Why Timber log produces the log messages twice once the activity restart its lifecycle in Android?
在我的 Android 项目开发过程中,我遇到了鼓励使用 Timber 日志库的情况;但是当我切换到使用它时,我发现一旦我放置 Timber.plant(new Timber.DebugTree());
的 activity 重新启动它的生命周期(第二次调用 onCreate(savedInstanceState)
),Timber 生成的所有日志都会生成在 LogCat 面板中两次。
这个简单的代码说明了问题:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "StateChange";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Timber.plant(new Timber.DebugTree()); // plant a debug tree
setContentView(ActivityMainBinding.inflate(getLayoutInflater()).getRoot());
Timber.tag(TAG).i("onCreate"); // using timber log
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy"); // using android log
}
}
现在当我运行应用程序旋转屏幕时(这会导致activity销毁并重新创建),LogCat的内容如下:
... I/StateChange: onCreate <-- everything is normal in the first creation
... I/StateChange: onDestroy
... I/StateChange: onCreate <-- when lifecycle restarts (rotate screen)
... I/StateChange: onCreate <-- those use Timber will get logged twice
... I/StateChange: onDestroy <-- but those use standard log remain normal
... I/StateChange: onCreate <-- rotate again
... I/StateChange: onCreate <-- same problem, but only twice
所以无论如何这仍然是我第一次使用 Timber,我不知道我们是否应该在任何地方放置任何代码来处理这种情况。虽然这看起来无伤大雅,但我现在做的项目涉及到很多LogCat面板的调试,查看两倍的信息来调试应用程序真的很麻烦。
您应该在应用程序 onCreate()
方法中种植木材,而不是 Activity onCreate()
方法。
否则,您可以将 Timber.plant()
方法包装成这样的条件:
if (Timber.treeCount() == 0) {
Timber.plant(new Timber.DebugTree()); // plant a debug tree
}
这是预期的行为。毕竟,每次创建 activity 时,您都会种植一棵新的“调试树”。
您应该有一个自定义 Application
class 并覆盖 onCreate
函数,而不是这样做。在里面,只需种植“调试树”即可。
例如:
public class MyCustomApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Timber.plant(new Timber.DebugTree());
...
}
这样,Timber 调试树只会在应用程序初始化时被“种植”。
在我的 Android 项目开发过程中,我遇到了鼓励使用 Timber 日志库的情况;但是当我切换到使用它时,我发现一旦我放置 Timber.plant(new Timber.DebugTree());
的 activity 重新启动它的生命周期(第二次调用 onCreate(savedInstanceState)
),Timber 生成的所有日志都会生成在 LogCat 面板中两次。
这个简单的代码说明了问题:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "StateChange";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Timber.plant(new Timber.DebugTree()); // plant a debug tree
setContentView(ActivityMainBinding.inflate(getLayoutInflater()).getRoot());
Timber.tag(TAG).i("onCreate"); // using timber log
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy"); // using android log
}
}
现在当我运行应用程序旋转屏幕时(这会导致activity销毁并重新创建),LogCat的内容如下:
... I/StateChange: onCreate <-- everything is normal in the first creation
... I/StateChange: onDestroy
... I/StateChange: onCreate <-- when lifecycle restarts (rotate screen)
... I/StateChange: onCreate <-- those use Timber will get logged twice
... I/StateChange: onDestroy <-- but those use standard log remain normal
... I/StateChange: onCreate <-- rotate again
... I/StateChange: onCreate <-- same problem, but only twice
所以无论如何这仍然是我第一次使用 Timber,我不知道我们是否应该在任何地方放置任何代码来处理这种情况。虽然这看起来无伤大雅,但我现在做的项目涉及到很多LogCat面板的调试,查看两倍的信息来调试应用程序真的很麻烦。
您应该在应用程序 onCreate()
方法中种植木材,而不是 Activity onCreate()
方法。
否则,您可以将 Timber.plant()
方法包装成这样的条件:
if (Timber.treeCount() == 0) {
Timber.plant(new Timber.DebugTree()); // plant a debug tree
}
这是预期的行为。毕竟,每次创建 activity 时,您都会种植一棵新的“调试树”。
您应该有一个自定义 Application
class 并覆盖 onCreate
函数,而不是这样做。在里面,只需种植“调试树”即可。
例如:
public class MyCustomApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Timber.plant(new Timber.DebugTree());
...
}
这样,Timber 调试树只会在应用程序初始化时被“种植”。