3

I have an onTouchListener on my TextView. On touch, I log with Timber.i() and then I call finish(). If after finish(), I launch my app again, and click again on the TextView, It will log twice, then 3 times, etc...

(If I replace Timber.i() by the normal Log.i(), there is no problem)

// first time
Clicked

// second time
Clicked
Clicked

// etc...
Clicked
Clicked
Clicked

Timber version :

compile 'com.jakewharton.timber:timber:4.5.1'

Working code :

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Timber.plant(new Timber.DebugTree());

    TextView tv = (TextView) findViewById(R.id.mytextview);
    tv.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Timber.i("Clicked");
            finish();
            return false;
        }
    });
}

Layout :

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.caca.test.MainActivity">

    <TextView
        android:id="@+id/mytextview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</android.support.constraint.ConstraintLayout>
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62

2 Answers2

8

The problem is that you are 'planting' trees in the Activities onCreate method. Instead, use a custom Applications subclass and plant the trees there.


class MyApp : Application() {

    override fun onCreate() {
        super.onCreate()

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

And update your AndroidManifest accordingly:

<application android:name="com.foo.MyApp" android:icon="@mipmap/ic_launcher" android:label="@string/app_name"/>

cwbowron
  • 1,015
  • 6
  • 10
  • I wanted to add this observation. Although you've called finish(), the app is not actually terminated and Timber is still available. As mentioned by @cwbbowron, calling Timber.plant() in your onCreate just adds another logger. You can also confirm this by checking how many loggers are running by using Timber.treeCount() to see how many loggers are running. It's a static method and found it quite handy.. – angryITguy Nov 21 '17 at 22:48
  • I would just add to this answer that you can call `Timber.uprootAll()` in your custom Application before planting Timber trees. This actually solved a problem for me. – Markymark Apr 15 '20 at 01:14
0

I surely am very late but still posting it. @cwbowron has explained it very well.
This trick got it fixed for me:

class TimberLogImplementation {
companion object {
    fun initLogging() {
        if(Timber.treeCount() != 0) return
        if (BuildConfig.DEBUG) Timber.plant(DebugTree())
        else Timber.plant(ReleaseTree())
        }
    }
}
rdias002
  • 214
  • 2
  • 9