Reputation: 13
I am writing a simple app used for communicating between a server and an app on a local network. Writing and receiving messages works without problems. But I can't display the messages I received in a Textview.
For receiving incoming messages, I make use of a (worker)thread. When I receive something, I send the message to a handler in the mainthread which should then display the message in a Textview.
But everytime the handler tries to display the message, I get the exception:
"Only the original thread that created a view hierarchy can touch its views."
I've searched many websites, including this one, to find a solution but still couldn't fix the problem. Please help me out.
Code:
public class TCPClientActivity extends Activity {
BufferedWriter output;
Socket s = new Socket();
//my handler
private Handler mHandler;
//where I want to display the message
private TextView lblChat;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tcpclient);
Button btnConnect = (Button)findViewById(R.id.btnConnect);
Button btnSend = (Button) findViewById(R.id.btnSend);
//creating the TextView
lblChat = (TextView) findViewById(R.id.lblChat);
final EditText tbIP = (EditText) findViewById(R.id.tbIP);
final EditText tbInput = (EditText) findViewById(R.id.tbInput);
//creating the handler
mHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
switch(msg.what)
{
case 1:
{
lblChat.append("Received: " + msg.obj + "\r\n" );
}
}
}
};
}
//Thread in which I receive incoming Messages from the server
Thread communication = new Thread()
{
@Override
public void run()
{
String finalText = "";
while(true)
{
try
{
DataInputStream inputStream = new DataInputStream(s.getInputStream());
int bytesRead;
byte[] b = new byte[4096];
bytesRead = inputStream.read(b,0,b.length);
finalText = EncodingUtils.getAsciiString(b);
//sending the message to the handler
Message msg = new Message();
msg.what = 1;
msg.obj = finalText;
mHandler.handleMessage(msg);
}
//android.view.ViewRoot$CalledFromWrongThreadException:
//Only the original thread that created a view hierarchy can touch its views.
//That's the exception I get when running the program
catch (Exception e)
{
e.printStackTrace();
}
}
}
};
//method where I connect to the server
private void connectToServer(String ip)
{
try
{
if(!ip.equals(""))
{
s = new Socket(ip, 3000);
}
else
{
s = new Socket("10.0.0.143", 3000);
}
output = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
output.write("Android Connected");
output.flush();
// new CommuTask().execute();
//starting the thread
communication.start();
// s.close();
}
catch(UnknownHostException e)
{
e.printStackTrace();
try {
s.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
catch(IOException e)
{
e.printStackTrace();
try {
s.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
Upvotes: 1
Views: 975
Reputation: 234867
Instead of this:
mHandler.handleMessage(msg);
Use this:
mHandler.sendMessage(msg);
Upvotes: 0
Reputation: 76574
You are invoking the method on the handler directly (therefore on your worker thread) instead of pushing the message
Instead of:
mHandler.handleMessage(msg);
you will want:
mHandler.sendMessage(msg);
Ref: http://developer.android.com/reference/android/os/Handler.html#sendMessage(android.os.Message)
Upvotes: 1