How to forward Log to textView in non-UI threads for Android?

1

I want my app to print the log in a TextView. I have created a class called Log that mimics Utils.Log, but the problem occurs when calling from a thread other than UI.

This is what the class looks like:

public class Log {

    private static Logger logger = new DefaultLogger();

    public static void l(String tag, String content) {
        logger.l(tag, content);
    }

    public static void e(String tag, String content) {
        logger.e(tag, content);
    }

    public static void setLogger(Logger l) {
        if (l != null)
            logger = l;
    }

    public interface Logger {
        void l(String tag, String content);

        void e(String tag, String content);
    }

    private static class DefaultLogger implements Logger {

        @Override
        public void l(String tag, String content) {
            android.util.Log.d(tag, content);
        }

        @Override
        public void e(String tag, String content) {
            android.util.Log.e(tag, content);
        }
    }
}

Then I can send any Log to a text view in the following way:

public class MyActivity extends Activity implements Log.Logger {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.setLogger(this);
        Log.l("Default", "El log funciona!!");
    }

    @Override
    public void l(String tag, String content) {
        // escribir log en textview aqui
        textview.append("\n" + content);
    }

    @Override
    public void e(String tag, String content) {
        // escribir log en textview aqui
    }
}

The problem is that when I call Log from a thread other than Ui (such as the networking thread), it throws me the exception:

  

FATAL EXCEPTION: NsdManager
  Process: com.example.app, PID: 21189
android.view.ViewRootImpl $ CalledFromWrongThreadException:   Only the original thread that created a view of the hierarchy can touch its views.

To Fix this I have done:

@Override
public void l(final String tag, final String content) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            addChatLine(tag + " * " + content);
        }
    });
}

@Override
public void e(final String tag, final String content) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            addChatLine(tag + " * " + content);
        }
    });
}

But I can not think of any cleaner solution. I was wondering, is there a more "clean" solution to do what I want?

    
asked by UselesssCat 29.03.2017 в 20:30
source

1 answer

0

The option in this case is to use runOnUiThread () to be able to make the modification of the properties of the view in the Thread main.

  runOnUiThread(new Runnable() {
        @Override
        public void run() {
                 // escribir log en textview aqui
                textview.append("\n" + content);
        }
    });
    
answered by 30.03.2017 в 00:44