error: Sólo el subproceso original que creó una jerarquía de vista puede tocar sus vistas

Hola y gracias por mirar mi pregunta. Soy un programador intermedio en C pero un novato de Android. He estado intentando conseguir una programación de la charla que trabaja. Suponiendo que todo lo demás en el código a continuación funciona perfectamente. La única pregunta que me gusta preguntar es cuando intento setText () de un hilo en ejecución, obtengo una excepción anterior. Miré muchos sitios web y aquí también. Encontré muchas cosas, pero realmente no entiendo. Por favor, explíqueme de la manera más sencilla o me ofrecen algunos arreglos simples si es posible.

¡¡Muchas gracias!!

public class chatter extends Activity { private String name = "Unknown User"; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final EditText msgToServer = (EditText) findViewById(R.id.msgBox); final EditText chatFromServer = (EditText) findViewById(R.id.chatBox); final Button MsgToServer = (Button) findViewById(R.id.sendButton); Socket socket = null; String ipAddress = "192.168.1.103"; try { InetAddress serverAddr = InetAddress.getByName(ipAddress); Socket socketMain = new Socket(serverAddr, 4444); socket = socketMain; } catch (IOException e) { // TODO Auto-generated catch block Log.e("TCP", "error", e); } final OutMsg outMsg = new OutMsg(socket); Thread msgSenderThread = new Thread(outMsg); msgSenderThread.start(); //chatFromServer.post(new InMsg(socket, chatFromServer)); Thread msgReceiverThread = new Thread(new InMsg(socket, chatFromServer)); msgReceiverThread.start(); MsgToServer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String msgToServerString; msgToServerString = msgToServer.getText().toString(); outMsg.message = name + ": " + msgToServerString; outMsg.readyToSend = true; msgToServer.setText(""); } }); } public void updateResultsInUi (String msg) { final EditText chatFromServer = (EditText) findViewById(R.id.chatBox); chatFromServer.setText(msg); } public class InMsg implements Runnable { Socket socket; EditText chatFromServer; public InMsg(Socket socket, EditText chatFromServer) { this.socket = socket; this.chatFromServer = chatFromServer; } public void run(){ try { BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); String str = "FIRSTMESSAGEFROMSERVER"; while (true) { if (str.equals("FIRSTMESSAGEFROMSERVER")) str = in.readLine(); else str = str + "\n" + in.readLine(); Log.e("TCP", "got the message: " + str); //Here is where went wrong****************** chatFromServer.setText(str); //****************************************** } } catch (IOException e) { // TODO Auto-generated catch block Log.e("TCP", "error in receiving", e); } } } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle item selection switch (item.getItemId()) { case R.id.setNameMenu: setname(); return true; default: return super.onOptionsItemSelected(item); } } public void populateChatBox (String msgFromS) { Log.e("TCP", "going in to popC"); final EditText textNameInput = (EditText) findViewById(R.id.nameBox); Log.e("TCP", " popC"); textNameInput.setText(msgFromS); Log.e("TCP", "going out from popC"); } public void setname() { setContentView(R.layout.custom_dialog); final EditText textNameInput = (EditText) findViewById(R.id.nameBox); Button submitNameButton = (Button) findViewById(R.id.submitNameButton); submitNameButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String nameinput = textNameInput.getText().toString(); if (!name.equals("")) name = nameinput; setContentView(R.layout.main); } }); } } 

En el método run ():

 Message msg = new Message(); String textTochange = "text"; msg.obj = textTochange; mHandler.sendMessage(msg); 

Cree el mHandler en su hilo de interfaz de usuario;

 Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { String text = (String)msg.obj; //call setText here } }; 

No está en el subproceso de la interfaz de usuario al configurar el texto. Usted necesita estar en la interfaz de usuario si desea trabajar en los elementos de la interfaz de usuario. Cree un manejador de mensajes en el subproceso de interfaz de usuario, envíe sus mensajes a él y llame a setText desde el controlador del subproceso de interfaz de usuario.

puedes hacerlo siempre que estés en un hilo:

 msgToServer.post(new Runnable() { public void run() { msgToServer.setText("your text here"); } } 

Su problema es que hay ciertas interacciones que sólo puede hacer en el hilo de la interfaz de usuario. Este es uno de ellos.

Parece que quizás quieras usar AsyncTask

http://developer.android.com/reference/android/os/AsyncTask.html

Básicamente usted podría hacer su Runnable un AsyncTask en su lugar y hacer el setText en onProgressUpdate, que se ejecuta en el UIThread.

Si desea utilizar un AsyncTask para ejecutar en segundo plano esto es cómo lo haría:

 public class UpdateTextProgress_Task extends AsyncTask<Void,String,Void> { Socket socket; EditText chatFromServer; UpdateTextProgress_Task(EditText chatFromServer, Socket socket){ this.socket = socket; this.chatFromServer = chatFromServer; } @Override protected Void doInBackground(Void... params) { try { BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); String str = "FIRSTMESSAGEFROMSERVER"; while(true){ if (str.equals("FIRSTMESSAGEFROMSERVER")){ str = in.readLine(); } else{ str = str + "\n" + in.readLine(); } Log.e("TCP", "got the message: " + str); publishProgress(str); // calls the onProgressUpdate method }catch (IOException e) { Log.e("UpdateTextProgress", e.getMessage()); } return null; } @Override protected void onProgressUpdate(String... progress) { chatFromServer.setText(progress[0]); //now we are on the UI thread so we can update our EditText } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); Log.e("UpdateTextProgress", "Finished"); } 

}

Para ejecutar el código:

 UpdateTextProgress_Task task = new UpdateTextProgress_Task(chatFromServer,socket); task.execute(); 
  • ¿Cómo puedo pasar variables extra durante una búsqueda invocada por un SearchView / Widget?
  • Cómo ocultar el teclado de Android en la vista de búsqueda
  • La vista personalizada de Android no se vuelve a pintar, aunque onDraw se está llamando
  • SearchView es nulo Android
  • ¿Qué es exactamente un widget?
  • GetMeasuredWidth devuelve un valor totalmente erróneo
  • ¿Cómo utilizar mi SurfaceView con main.xml en Android?
  • El tamaño de texto de Android en la lona difiere del tamaño de texto en TextView
  • SearchView y teclado
  • Tratamiento de mapas de bits grandes (mosaico de un pequeño mapa de bits para crear papel tapiz)
  • Android SurfaceView no muestra onDraw
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.