首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用处理程序更新UI-thread

使用处理程序更新UI-thread
EN

Stack Overflow用户
提问于 2013-08-01 17:57:23
回答 2查看 693关注 0票数 0

我已经在网络上寻找了明确的例子,但到目前为止还没有找到一个我可以应用到我的项目中的例子。

我正在尝试创建一个每100ms运行一次的工作线程。然后,它应该用结果更新UI。经过一些研究后,我决定我可能应该使用处理程序来管理UI更新。我得到了这样的解决方案:

我的活动处理程序:

代码语言:javascript
复制
private  final Handler handler = new Handler() {

        public void handleMessage(Message msg) {

        String aResponse = msg.getData().getString("message");

        if ((null != aResponse)) {

            // ALERT MESSAGE
            Log.v("udppacket", "UDP message!");
            if (msg.obj != null)
            {
                ManagerUdpPacket p = (ManagerUdpPacket) msg.obj;
                operatorListFragment.updateContent((int) p.getOperationTime());
            }
        }
        else
        {

        }    

    }
};

我的另一个类有worker-thread:

代码语言:javascript
复制
public class ManagerUdpReceiver 
{
    private int minPort = 1234;
    private int maxPort = 1240;
    private ArrayList<PortListener> portList;
    private Handler handler;
    private Thread portThread;
    private int queryInterval = 100;
    private boolean stop = false;


    public ManagerUdpReceiver(int minport, int maxport, Handler handler, int queryInterval)
    {
        minPort = minport;
        maxPort = maxport;
        this.handler = handler;
        this.queryInterval = queryInterval;

        //create port listeners from given range and start their threads


    start();
}

private void start()
{
    stop = false;
    // Create Inner Thread Class
    portThread = new Thread(new Runnable() 
    {
        // After call for background.start this run method call
        public void run() 
        {

            if (portList == null)
            {
                portList = new ArrayList<PortListener>();
                for (int i = minPort; i < maxPort; i++)
                {
                    portList.add(new PortListener(i));
                }
            }

            if (!stop)
            {
                ManagerUdpPacket p = portList.get(0).receive();
                threadMsg("moi", p);
                //mHandler.postDelayed(this, queryInterval);

            }
            else
            {
                //stop execution and close ports
                for (int i = 0; i < portList.size(); i++)
                {
                    portList.get(i).close();
                }
            }


        }

        //send message to the handler
        private void threadMsg(String msg, ManagerUdpPacket p) 
        {
             if (!msg.equals(null) && !msg.equals("")) 
             {
                 Message msgObj = handler.obtainMessage();
                 //msgObj.obj = p;
                 Bundle b = new Bundle();
                 b.putString("message", msg);
                 msgObj.setData(b);
                 handler.sendMessage(msgObj);
             }               
        }
    });

    // Start Thread
    portThread.start();
}



public void close()
    {   
        stop = true;
    }
}

当我运行程序时,我得到异常运行网络代码在UI-thread。现在,工作线程应该接收和处理UDP数据包。但是,它的代码在portThread线程内部!我假设我用来每隔100ms循环线程的handler.postDelayed(this,queryInterval)会导致下一个周期在UI-thread中运行,而不是在我的worker-thread中运行。

所以我的问题是,我在这里做错了什么,以及如何修复它?或者,如何让循环在每100毫秒内正确工作?我也不确定该把Handler放在哪里,因为我已经看到过它在Activity和worker-thread内部的例子。

EN

回答 2

Stack Overflow用户

发布于 2013-08-01 18:32:21

好的,我想我得到了它的工作,尽管我对它不满意,所以不检查它。

基本上,我最终使用TimerTask每隔100ms运行一次代码,并通过处理程序通知UI-thread。我真的不确定这是不是最好的选择(我听说计时器不是那么好),但似乎是有效的:

代码语言:javascript
复制
dataStreamTimer = new Timer();
    dataStreamTask = new TimerTask()
    {
        public void run() 
        {

            if (portList == null)
            {
                portList = new ArrayList<PortListener>();
                for (int i = minPort; i < maxPort; i++)
                {
                    portList.add(new PortListener(i));
                }
            }

            if (!stop)
            {

                ManagerUdpPacket p = portList.get(0).receive();
                threadMsg("moi", p);
                //handler.postDelayed(this, queryInterval);

                //stop thread until next query
                try {
                    synchronized(this){
                        this.wait(queryInterval);
                    }
                } catch (InterruptedException e) {
                    Log.e("ERR", "InterruptedException in TimerTask.run");
                }
            }
            else
            {
                //execution has been stopped, clear data:
                //stop execution and close ports
                for (int i = 0; i < portList.size(); i++)
                {
                    portList.get(i).close();
                }
            }

        }
票数 1
EN

Stack Overflow用户

发布于 2013-08-01 18:33:20

并不真正理解处理程序的目的。为什么不在后台线程上准备数据,然后使用myActivity.runOnUIThread()来运行updateContent()方法呢?也许p.getOperationTime()被认为是网络操作,尝试将这个值保存到后台线程的某个变量中,然后通过UI线程发布它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17990813

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档