Не удается получить доступ к представлениям из другого потока, даже при использовании обработчика

1

Я пишу простое приложение, используемое для связи между сервером и приложением в локальной сети. Написание и получение сообщений работает без проблем. Но я не могу отображать сообщения, полученные в 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 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();
            }
        }

    }
}
  • 0
    Добро пожаловать в stackoverflow, не забывайте привыкать отмечать ваши вопросы как ответы, когда вы нашли решение i.stack.imgur.com/uqJeW.png
Теги:
multithreading
handler
view

2 ответа

0
Лучший ответ

Вы вызываете метод непосредственно на обработчике (поэтому на рабочем рабочем потоке) вместо нажатия сообщения

Вместо:

 mHandler.handleMessage(msg);

ты захочешь:

 mHandler.sendMessage(msg);

Ссылка: http://developer.android.com/reference/android/os/Handler.html#sendMessage(android.os.Message)

  • 0
    Dang! Побей меня на 10 секунд!
  • 0
    @TedHopp ;-) Я дам вам его за 10 тысяч репутации
Показать ещё 1 комментарий
0

Вместо этого:

mHandler.handleMessage(msg);

Использовать это:

mHandler.sendMessage(msg);
  • 0
    Спасибо! это сработало :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню