即使使用处理程序,也无法访问其他线程的视图

时间:2012-06-21 22:14:24

标签: android multithreading view handler

我正在编写一个简单的应用程序,用于在本地网络上的服务器和应用程序之间进行通信。编写和接收消息没有问题。但我无法在Textview中显示收到的消息。

为了接收传入的消息,我使用了(工作者)线程。当我收到某些内容时,我会将消息发送到mainthread中的处理程序,然后该处理程序应在Textview中显示该消息 但每次处理程序尝试显示消息时,我都会得到异常:
“只有创建视图层次结构的原始线程才能触及其视图。”

我搜索了许多网站,包括这个网站,以找到解决方案,但仍无法解决问题。请帮帮我。

代码:

    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();
            }
        }

    }
}

2 个答案:

答案 0 :(得分:0)

您正在调用处理程序上的方法(因此在您的工作线程上),而不是按下消息

而不是:

 mHandler.handleMessage(msg);

你会想要:

 mHandler.sendMessage(msg);

参考:http://developer.android.com/reference/android/os/Handler.html#sendMessage(android.os.Message)

答案 1 :(得分:0)

而不是:

mHandler.handleMessage(msg);

使用此:

mHandler.sendMessage(msg);