Only the original thread that created a view hierarchy can touch its views и неудачное создание Websockets соединения

Пытаюсь писать свою программу для андроида. Недавно появилась ошибка при создании соединения "Only the original thread that created a view hierarchy can touch its views". Если сделать реконнект, то соединение создается. Но проблема с выводом информации на дисплей. При подключении должно выводится сообщение, что соединение установлено. Но на экран выводится не все. После такой ошибки выводится только слово "Websocket", а другая информация вообще не выводится (Должно быть: Websocket connected to: 192.168.0.104:81). А еще эта ошибка с темы! Прочитал что "это значит, что с UI можно работать только в UI потоке".Код кривой... Но хочу разобраться с проблемой и сделать лучше.

Код:

package com.example.rili;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;

public class MainActivity extends AppCompatActivity {
    private TextView  text;
    private TextView  switch_status;
    private EditText ip_text;
    private Switch switch1;
    private ImageButton button_switch;

    OkHttpClient okHttpClient;
    Request request;
    EchoWebSocketListener listener;
    WebSocket webSocket;

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

        switch1 = findViewById(R.id.switch1);
        button_switch = findViewById(R.id.btn_switch);
        text = findViewById(R.id.ws_status);
        switch_status = findViewById(R.id.switch_status);
        ip_text = findViewById(R.id.ip_address);

        switch1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(switch1.isChecked()){
                    create_cnnection();
                }
                else {
                    destroy_cnnection();
                }
            }
        });
        button_switch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                button_switch.setImageResource(R.drawable.btn_pressed);
                change_switch();
            }
        });
    }

    // WebSocket
    private final class EchoWebSocketListener extends WebSocketListener {
        @Override
        public void onOpen(WebSocket webSocket, Response response) {
            // open
            output("Ha!");
            output("Websocket connected to: " + ip_text.getText() + ":81");
            System.out.println("!!!STATE!!! : CONNECTED");
        }

        @Override
        public void onMessage(WebSocket webSocket, String text) {
            switch (text){
                case "0":
                    button_switch.setImageResource(R.drawable.btn_on);
                    switch_state(0);
                    System.out.println("!!!STATE!!! : RESEIVED 0");
                    break;
                case "1":
                    button_switch.setImageResource(R.drawable.btn_off);
                    switch_state(1);
                    System.out.println("!!!STATE!!! : RESEIVED 1");
                    break;
            }
        }

        @Override
        public void onClosing(WebSocket webSocket, int code, String reason) {
            // close
            output("Websocket closed: " + code + " / " + reason);
            System.out.println("!!!STATE!!! : CLOSED");
        }

        @Override
        public void onFailure(WebSocket webSocket, Throwable t, Response response) {
            // fail
            output("Websocket error: " + t.getMessage());
            System.out.println("!!!STATE!!! : ERROR" + t.getMessage());
        }
    }

    private void create_cnnection() {
        okHttpClient = new OkHttpClient();
        request = new Request.Builder().url("ws://"+ ip_text.getText() + ":81").build();
        listener = new EchoWebSocketListener();
        webSocket = okHttpClient.newWebSocket(request, listener);
        button_switch.setEnabled(true);
    }

    private void destroy_cnnection() {
        // destroy
        webSocket.close(1000, "bye");
    }

    private void change_switch() {
        // send
        webSocket.send("t");
    }

    private void output(final String txt) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                text.setText(txt);
            }
        });
    }
    private void switch_state(final int txt) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                switch_status.setText("Switch Status: " + txt);
            }
        });
    }
}

Что пишет консоль:

I/System.out: !!!STATE!!! : CONNECTED
I/System.out: !!!STATE!!! : ERROROnly the original thread that created a view hierarchy can touch its views.
I/om.example.ril: ProcessProfilingInfo new_methods=1721 is saved saved_to_disk=1 resolve_classes_delay=8000        
I/System.out: !!!STATE!!! : CONNECTED
I/System.out: !!!STATE!!! : RESEIVED 0

Вот что я вижу на экране: введите сюда описание изображения


Ответы (0 шт):