During the development of my Android project, I encountered the encouraged use of the Timber log library; but when I switched to using it, I found that once the activity in which I place Timber.plant(new Timber.DebugTree());
restarts its lifecycle (calling onCreate(savedInstanceState)
a second time), all the log generated by Timber get produced twice in the LogCat panel.
This simple code illustrates the problem:
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
}
}
Now when I run the app and rotate the screen (which will cause the activity to destroy and recreate again), the content of the LogCat is as follow:
... 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
So anyway this is still my first use of Timber, I don't know if we should put any code anywhere to handle the situation. Although this seems harmless enough, the project I am currently doing involves a lot of debugging from the LogCat panel, and looking at twice as much information to debug the app is really cumbersome.
This is the expected behaviour. After all, you are planting a new "Debug tree" every time the activity gets created.
Instead of doing it this way, you should have a Custom Application
class and override the onCreate
function. Inside, just plant the "Debug tree".
E.g.:
public class MyCustomApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Timber.plant(new Timber.DebugTree());
...
}
This way, the Timber debug tree will only be "planted" on app initialisation.