在做一个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)

邱解释,一楼附上源码,如果还不够,继续加!

解决方案 »

  1.   

    package com.wang.chat;import java.io.BufferedReader;
    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();
    }
    }
    }
    }
    }
      

  2.   

    Only the original thread that created a view hierarchy can touch its views.
    又是这个问题
    不能在 ClientThread 这个线程显示文字area.setText(area.getText().toString()+str+"\n");用handler发个消息,然后在handlerMessage中显示TextView的文字即:
    area.setText(area.getText().toString()+str+"\n");
      

  3.   

    能帮忙纠正下代码啊,因为有段时间没碰android了,最近做课程设计,想起用他练练手,因为时间很紧,请帮纠正下!
      

  4.   

    同1楼public class ClientChat extends Activity{
        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();
                    }
                }
            }
        }       
    }
      

  5.   

    使用非UI线程不能直接操作ui,可以使用handler发送消息给UI线程更新UI
      

  6.   

    area.setText(area.getText().toString()+str+"\n");
    不要放在线程里执行 可以使用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");
    }
    };
      

  7.   

     setContentView(R.layout.main); 这句忘了告诉你了 换成client 还有,就是没法获得服务器发来的消息
      

  8.   

    import java.io.BufferedReader;
    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();
    }
    }
    }