Search code examples
loggingandroid-jetpack-composetimber

Why is Timber accumulating log statements


I ran into a problem with Timber when used with Jetpack compose. I was trying to log statements in response to device rotation. Using Timber, each rotation generated one more log statement then the previous one. So, first rotation generated one log statement, the second rotation produced two log statements and so on. This gave the impression that either the OS was notifying me multiple times or Jetpack compose was doing its magic. After chasing my tail for a full day, I finally replaced Timber, with Log. The result is no more duplicate log statements. Is this a known problem, or am I doing something wrong? This is the code that reacted to rotation: If you replace Log with Timber, ########## ORIENTATION previousOrientation is printed multiple times.

    @Composable
fun OrientationListener(onPortrait: () -> Unit, onLandscape: () -> Unit) {
    var previousOrientation by rememberSaveable { mutableIntStateOf(Configuration.ORIENTATION_UNDEFINED) }
    val configuration = LocalConfiguration.current

    // Use LaunchedEffect to detect orientation changes and call the appropriate callback
    LaunchedEffect(configuration.orientation) {
        if (previousOrientation != configuration.orientation) {
            Log.d(TAG,"########## ORIENTATION previousOrientation: $previousOrientation  current configuration: ${configuration.orientation}###############")
            previousOrientation = configuration.orientation
            val isPortrait = configuration.orientation == Configuration.ORIENTATION_PORTRAIT
            if (isPortrait) {
                onPortrait()
            } else {
                onLandscape()
            }
        }
    }
}

Replacing Log with TImber causes multiple log statements to be printed to the console. Timber was initialized in MainActivity like so:

if (BuildConfig.DEBUG)
    Timber.plant(Timber.DebugTree())

Solution

  • Please initialize Timber in the Application class instead of in the Activity.

    First, create a class MyApplication.kt and add the following code there:

    class MyApplication: Application() {
    
        override fun onCreate() {
            super.onCreate()
    
            // setup Timber
            Timber.plant(Timber.DebugTree())
        }
    }
    

    Then, register your custom Application class in your manifest.xml like this:

    <application
        android:name=".MyApplication"
        ...>
    </application>