简体   繁体   中英

Looping PC to Android Socket communication?

To start off, i am a complete newbie to Android, and Java... I am working on a robot and need to send it wireless commands. After trying several methods to do this and getting lots of errors and time debugging (not understanding half of what was going on in the example code...) I have found that the simplest way to communicate would be with Sockets. I followed the tutorial at http://android-er.blogspot.com/2011/01/simple-communication-using.html , and it works great! It does exactly what it is supposed to with no errors, a welcome relief, but not what i want. It starts with Android, sends message to PC, then waits for response from PC, then ends until the button is clicked again. I want it to go in the opposite direction. I tried just switching the code, but kept getting force close. I finally got it so after you send a message from the android, the PC responds, then the android automatically sends another message so it is always waiting for PC. It doesn't work very well, and sometimes crashes because of the button. Also it doesn't display the message from the PC anymore! I am trying to put the important part of the code into a thread so the android never needs to be touched and it keeps looping... I have no idea why this is not working, i am getting the following error:

    11-24 13:21:11.492: E/AndroidRuntime(2656): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

My entire program is one class:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

EditText textOut;
TextView textIn;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

//textOut = (EditText)findViewById(R.id.textout);
//Button buttonSend = (Button)findViewById(R.id.send);
textIn = (TextView)findViewById(R.id.textin);
//buttonSend.setOnClickListener(buttonSendOnClickListener);

 // start a loop
new Thread(new Runnable()
{
  public void run()
  {
    while (true)
    {
     Socket socket = null;
     DataOutputStream dataOutputStream = null;
     DataInputStream dataInputStream = null;

     try {
      socket = new Socket("192.168.0.9", 8888);
      dataOutputStream = new DataOutputStream(socket.getOutputStream());
      dataOutputStream.writeUTF("Received!");
      dataInputStream = new DataInputStream(socket.getInputStream());
      textIn.setText(dataInputStream.readUTF());

     } catch (UnknownHostException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     }
     finally{
      if (socket != null){
       try {
        socket.close();
       } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
       }
      }

      if (dataOutputStream != null){
       try {
        dataOutputStream.close();
       } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
       }
      }

      if (dataInputStream != null){
       try {
        dataInputStream.close();
       } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
       }
      }
     }
    }
  }
}).start();
}}

Any help or suggestions of better ways to do this would be GREAT! Thank you!

It is not working because you are trying to update the user interface from a background thread, which is not possible.

textIn.setText(dataInputStream.readUTF());

A possible solution is to use an AsyncTask where you easily can update the UI after the message exchange.

EDIT: Found this answer which is really good

尝试将新线程更改为

 runOnUiThread(new Runnable() {

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM