0

I'd like to use a TextView to log some actions in my app. Is the following method bad practice (are there any drawbacks?)

TextView tv = (TextView)findViewById(R.id.textView);
String s = "";

s = s + "Starting app...\n";
tv.setText(s);

...

s = s + "Doing action #1.\n";
tv.setText(s);

...

s = s + "Doing action #2.\n";
tv.setText(s);

Is there a better way to do it than redo a setText(s) each time, after having appended the new logging information to s ?

Basj
  • 41,386
  • 99
  • 383
  • 673
  • [Like using the Log class](https://developer.android.com/reference/android/util/Log.html)? Or do you want the user to see these logs? If this isn't what you are asking for, then please be more specific with your question. – codeMagic Dec 10 '17 at 20:38
  • It is preferred to use the [`Log`](https://developer.android.com/reference/android/util/Log.html) class to log messages. For instance, you can use `Log.v(TAG, msg)` to log verbosely to the android monitor. – ljeabmreosn Dec 10 '17 at 20:40
  • @codeMagic yes but this wouldn't print it in my TextView, I'd like to do this. – Basj Dec 10 '17 at 20:40
  • @ljeabmreosn Yes but with the Log class, it won't be displayed to the final user, right? I want it to be displayed to the final user, it's useful informations for the user of the app, thus I want to display it in a TextView. – Basj Dec 10 '17 at 20:41
  • Then, from what you've provided, the way you are doing it seems fine. Why do you think otherwise? – codeMagic Dec 10 '17 at 20:42
  • @Basj as codeMagic said, it would better to make your question more specific. – ljeabmreosn Dec 10 '17 at 20:42
  • @codeMagic Don't know, I thought maybe there's a better way :) – Basj Dec 10 '17 at 20:43
  • Nope, unless there's something here you aren't providing (such as the context of how you are doing it) this way seems fine. Whether it is best for the UX or not we don't know without knowing what your app does or how you are doing it. But that would be a question for a different stack site – codeMagic Dec 10 '17 at 20:45

1 Answers1

1

There's a pretty clean approach, which is to use DataBinding in android. I will go through a short example of how your use case might end up looking.

First, to use DataBinding you must enable it from the build.gradle of your app:

android {
    dataBinding {
        enabled = true
    }
}

Second thing would be to create a model that would contain your log message, this is also a clean way to store the message instead of simply appending to a string. In my case, I'll call it Log:

public class Log extends BaseObservable{
    //This will be the message you wanna print
    private String message;

    @Bindable
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
        //This would automatically update any binded views with this model whenever the message changes
        notifyPropertyChanged(BR.message);
    }
}

Third thing would be to update your layout file which contains the TextView you're using. Basically, we'll create a Log variable in the layout, and tell the textView to read the message from it and display it as its text. In my example, activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
    <variable
        name="log"
        type="com.riad.crypto.databinding.Log" />
</data>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/text_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="top"
        android:textSize="18sp"
        android:text="@={log.message}" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/button_view"
        android:gravity="bottom"/>

</LinearLayout>

Now simply, wherever you wanna display the logs, create a Logger object and bind it with the textView. In my example MainActivity:

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


    final Log logger = new Log();
    ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    binding.setLog(logger); //This is where we bind the layout with the object

    Button button = (Button) findViewById(R.id.button_view);

    logger.setMessage("1st log statement"); //You'll notice that the texview displays this message first

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            logger.setMessage("2nd log message"); //After button click, the texview would automatically change text to this. All you did was set the message
        }
    });
}

So now you could change the textView on every button click, but ofcourse you could do it wherever you want. And in case you need the Log object in different classes you could improve this by creating a Singleton or something, but this was just for the demo.

Hope this helps! Goodluck

riadrifai
  • 1,108
  • 2
  • 13
  • 26