在辅助线程的主线程上使用/ Argument调用方法

时间:2014-03-02 20:13:07

标签: java android multithreading

像标题一样,我有一个带有MainActivity类的android项目,该类有一个TextView,我想在收到消息后设置文本。我还有一个类在一个单独的线程上运行ServerSocket,该线程接收我想要显示的字符串消息。

我的MainActivity的一部分看起来像这样,

private Handler UIHandler = new Handler();
private RemoteControlServer remoteConnection;
public static final int controlPort = 9090;
public class MainActivity extends Activity implements SensorEventListener
{
    ...

    remoteConnection = new RemoteControlServer(controlPort, UIHandler);

    ...

    private class RemoteControlServer extends RemoteControl
    {
        RemoteControlServer(int port, Handler ui)
        {
            super(port, ui);
        }

        @Override
        public void onReceive(String[] msg)
        {
            //updates messages textview
        }

        @Override
        public void onNotify(String[] msg)
        {
            //updates notification textview
        }
    }
}

调用onReceive(String [] msg)并且还处理在不同线程上接收消息的代码的RemoteControlServer实现看起来像这样,

...

public abstract void onReceive(String[] msg);
public abstract void onNotify(String[] msg);

...

controlListener = new Thread(new Runnable()
{
    boolean running = true;
    public void run()
    {
        String line = null;
        while(running)
        {
            try
            {
                //Handle incoming messages

                ...

                onReceive(messages);    
            }
            catch (final Exception e)
            {
                UIHandler.post(new Runnable()
                {
                    public void run()
                    {
                        onNotify("Wifi Receive Failed " + e.toString() + "\n");
                    }
                });
            }
        }
    }
});

...

我收到错误“只有创建视图层次结构的原始线程才能触及其视图。”当调用onReceive()并抛出异常并使用异常描述调用onNotify()时。为什么onNotify()有效但另一个没有?如何正确调用TextView的监听器并更新其文本?感谢

1 个答案:

答案 0 :(得分:1)

private class RemoteControlServer extends RemoteControl
{

    ...

    public class BridgeThread implements Runnable
    {
        String[] msgArray = null;
        public BridgeThread(String[] msg)
        {
            msgArray = msg;
        }

        public void run()
        {
            runOnUiThread(new Runnable()
            {   
                @Override
                public void run()
                {
                    TextView zValue = (TextView) findViewById(R.id.connectionStatus);
                    zValue.setText(msgArray[0]);
                }
            });
        }
    }

    @Override
    public void onReceive(String[] msg)
    {
        BridgeThread bridgeTest = new BridgeThread(msg);
        bridgeTest.run();
    }

    ...
}