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
