在做一个socket聊天室的程序,在编译时出现
07-04 08:02:21.491: ERROR/AndroidRuntime(259): FATAL EXCEPTION: Thread-8
07-04 08:02:21.491: ERROR/AndroidRuntime(259): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.view.ViewRoot.invalidateChild(ViewRoot.java:607)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:633)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2505)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.view.View.invalidate(View.java:5115)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.widget.TextView.invalidateCursor(TextView.java:3625)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.widget.TextView.spanChange(TextView.java:6221)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.widget.TextView$ChangeWatcher.onSpanAdded(TextView.java:6346)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.text.SpannableStringBuilder.sendSpanAdded(SpannableStringBuilder.java:906)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:611)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:514)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.text.Selection.setSelection(Selection.java:74)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.text.Selection.setSelection(Selection.java:85)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.text.method.ArrowKeyMovementMethod.initialize(ArrowKeyMovementMethod.java:497)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.widget.TextView.setText(TextView.java:2676)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.widget.TextView.setText(TextView.java:2556)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.widget.EditText.setText(EditText.java:75)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.widget.TextView.setText(TextView.java:2531)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at com.wang.chat.ClientThread.run(ClientChat.java:104)
邱解释,一楼附上源码,如果还不够,继续加!
07-04 08:02:21.491: ERROR/AndroidRuntime(259): FATAL EXCEPTION: Thread-8
07-04 08:02:21.491: ERROR/AndroidRuntime(259): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.view.ViewRoot.invalidateChild(ViewRoot.java:607)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:633)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2505)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.view.View.invalidate(View.java:5115)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.widget.TextView.invalidateCursor(TextView.java:3625)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.widget.TextView.spanChange(TextView.java:6221)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.widget.TextView$ChangeWatcher.onSpanAdded(TextView.java:6346)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.text.SpannableStringBuilder.sendSpanAdded(SpannableStringBuilder.java:906)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:611)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:514)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.text.Selection.setSelection(Selection.java:74)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.text.Selection.setSelection(Selection.java:85)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.text.method.ArrowKeyMovementMethod.initialize(ArrowKeyMovementMethod.java:497)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.widget.TextView.setText(TextView.java:2676)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.widget.TextView.setText(TextView.java:2556)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.widget.EditText.setText(EditText.java:75)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at android.widget.TextView.setText(TextView.java:2531)
07-04 08:02:21.491: ERROR/AndroidRuntime(259): at com.wang.chat.ClientThread.run(ClientChat.java:104)
邱解释,一楼附上源码,如果还不够,继续加!
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;public class ClientChat extends Activity{
TextView msg1 = null;
EditText msg = null;
Button send = null;
Socket socket = null;
String name;
/* public ClientChat(Socket socket, String name) {
this.socket = socket;
this.name = name;
ClientThread thread = new ClientThread(socket, msg1);
thread.start();
}*/
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.client);
setTitle("我的聊天室");
msg1 = (TextView)findViewById(R.id.msg1);
msg = (EditText)findViewById(R.id.msg);
send = (Button)findViewById(R.id.send);
msg1.setBackgroundColor(Color.WHITE);
try {
socket = new Socket();
System.out.println(InetAddress.getLocalHost());
socket.connect(new InetSocketAddress( "10.0.2.2", 8899));
System.out.println(socket.isConnected()+"success");
//setTitle(InetAddress.getLocalHost().toString());
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println(e.getMessage());
e.printStackTrace();
}
System.out.println(socket.getPort()+"success");
ClientThread thread = new ClientThread(socket, msg1);
thread.start();
//if(msg1!=null)
//message.append(msg1.getText().toString());
send.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String str = msg.getText().toString();
SimpleDateFormat formater = new SimpleDateFormat("HH:mm:ss");
String time = formater.format(new Date());
String sendStr = "name" + " " + time + "说: " + str; //接受login出来的值--用户名
System.out.println(str);
//往服务器发
PrintWriter out = null;
try {
out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
out.println(sendStr);
out.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
msg.setText("");
}
});
}}
class ClientThread extends Thread{
private Socket socket;
private TextView area; public ClientThread(Socket socket, TextView area){
this.socket = socket;
this.area = area;
}
public void run(){
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str = null;
area.setText("");
while((str = br.readLine()) != null){
System.out.println(str);
area.setText(area.getText().toString()+str+"\n");
//area.append(str);
//area.append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
又是这个问题
不能在 ClientThread 这个线程显示文字area.setText(area.getText().toString()+str+"\n");用handler发个消息,然后在handlerMessage中显示TextView的文字即:
area.setText(area.getText().toString()+str+"\n");
TextView msg1 = null;
EditText msg = null;
Button send = null;
Socket socket = null;
String name;
Handler hMsg=new Handler(){ @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
if(msg.what==1)
{
msg1.setText(msg1.getText().toString()+msg.obj.toString()+"\n");
}
else
super.handleMessage(msg);
}
};
/* public ClientChat(Socket socket, String name) {
this.socket = socket;
this.name = name;
ClientThread thread = new ClientThread(socket, msg1);
thread.start();
}*/
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setTitle("我的聊天室");
msg1 = (TextView)findViewById(R.id.msg1);
msg = (EditText)findViewById(R.id.msg);
send = (Button)findViewById(R.id.send);
msg1.setBackgroundColor(Color.WHITE);
try {
socket = new Socket();
System.out.println(InetAddress.getLocalHost());
socket.connect(new InetSocketAddress( "10.0.2.2", 8899));
System.out.println(socket.isConnected()+"success");
//setTitle(InetAddress.getLocalHost().toString());
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println(e.getMessage());
e.printStackTrace();
}
System.out.println(socket.getPort()+"success");
ClientThread thread = new ClientThread(socket, hMsg);
thread.start();
//if(msg1!=null)
//message.append(msg1.getText().toString());
send.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String str = msg.getText().toString();
SimpleDateFormat formater = new SimpleDateFormat("HH:mm:ss");
String time = formater.format(new Date());
String sendStr = "name" + " " + time + "说: " + str; //接受login出来的值--用户名
System.out.println(str);
//往服务器发
PrintWriter out = null;
try {
out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
out.println(sendStr);
out.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
msg.setText("");
}
});
}}
class ClientThread extends Thread{
private Socket socket;
private Handler hmsg;
public ClientThread(Socket socket,Handler hmsg){
this.socket = socket;
this.hmsg = hmsg;
}
public void run(){
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str = null;
while((str = br.readLine()) != null){
System.out.println(str);
hmsg.sendMessage(hmsg.obtainMessage(1, new String(str)));
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
不要放在线程里执行 可以使用handler发送个消息执行
while((str = br.readLine()) != null){
System.out.println(str);
handler.sendEmptyMessage(1);
//area.append(str);
//area.append("\n");
}private Handler handler = new Handler()
{ @Override
public void handleMessage(Message msg)
{
area.setText(area.getText().toString()+str+"\n");
}
};
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;public class ServerChat { private List<Socket> sockets = new ArrayList<Socket>(); public ServerChat() throws IOException {
this.init();
} // 启动监听
public void init() throws IOException {
ServerSocket ss = new ServerSocket(8899); System.out.println("服务器已经监听在8899端口了....");
// 监听并接收客户端
while (true) {
Socket socket = ss.accept();
sockets.add(socket);
String ip = socket.getInetAddress().getHostAddress(); System.out.println("有一个客户端来了..它的IP是:" + ip); // 针对每个客户端都启动一个线程单独跟它通信
Thread thread = new Thread(new ServerRunner(sockets, socket));
thread.start(); }
} /**
* @param args
*/
public static void main(String[] args) {
try {
new ServerChat();
} catch (IOException e) {
e.printStackTrace();
}
}}
class ServerRunner implements Runnable {
private List<Socket> sockets;
private Socket currentSocket; public ServerRunner(List<Socket> sockets, Socket currentSocket) {
this.sockets = sockets;
this.currentSocket = currentSocket;
} public void run() {
//
String ip = currentSocket.getInetAddress().getHostAddress();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(
currentSocket.getInputStream())); String str = null;
while ((str = br.readLine()) != null) {
System.out.println(ip + "说:" + str);
// 往所有的客户端Socket写信息
for (Socket temp : sockets) {
PrintWriter pw = new PrintWriter(new OutputStreamWriter(
temp.getOutputStream()));
pw.println(str);
pw.flush();
} }
} catch (IOException e) {
e.printStackTrace();
}
}
}