工作线程(耗时操作)与UI线程实现异步更新

本文介绍了一种通过创建基础流程类实现工作线程与UI线程交互的方法,确保耗时操作不在UI线程中执行,同时实现了消息的有序处理和UI的逐步更新。
  1. 概述:工作线程A(多任务)执行期间,把单一任务的结果返回到UI线程更新。
  2. 实现: 创建基础流程类(两个handler)
public abstract class BaseQueueThread
{
    /**
     * 设置处理线程、ui处理流程,由子类实现
     */
    protected abstract Object doInWork(int integer);//耗时操作

    protected abstract void doInUi(Object obj);//更新ui

    private Handler mWorkHandler,mUiHandler;

    private boolean isDestroy;

    private PriorityQueue<Message> mQueue;//优先队列

    public BaseQueueThread()
    {
        initProcess();
    }


    //暴露数据访问接口
    public void sendMessage(int priority,Integer obj)
    {
        Message msg = Message.obtain();
        msg.what = priority;
        msg.obj = obj;
        mWorkHandler.sendMessage(msg);//从工作线程开始
    }

    private void initProcess()
    {
        mUiHandler = new Handler(Looper.getMainLooper());
        HandlerThread handlerThread = new HandlerThread(getClass().getName());
        handlerThread.start();
        mWorkHandler = new Handler(handlerThread.getLooper())
        {
            private boolean isWait;//是否在等待ui更新
            @Override
            public void handleMessage(Message msg)
            {
                if(isDestroy)
                {
                    return;
                }
                try
                {
                    if(msg.what == -1)
                    {
                        if (mQueue == null)
                        {
                            isWait = false;
                            return;
                        }
                        msg = mQueue.poll();
                        if (msg == null)
                        {
                            isWait = false;
                            return;
                        }

                    }else if(isWait)
                    {
                        if (mQueue == null)
                        {
                            mQueue = new PriorityQueue<Message>(11, new Comparator<Message>()
                            {
                                @Override
                                public int compare(Message lhs, Message rhs)
                                {
                                    return rhs.what - lhs.what;
                                }
                            });
                        }
                        Message message = Message.obtain();
                        message.copyFrom(msg);
                        mQueue.add(message);
                        return;
                    }else
                    {
                        isWait = true;
                    }

                    final Object result = doInWork((Integer) msg.obj);

                    mUiHandler.post(new Runnable()
                    {
                        @Override
                        public void run()
                        {
                            doInUi(result);
                            Message msg1 = Message.obtain();
                            msg1.what = -1;//通知ui更新成功
                            mWorkHandler.sendMessageAtFrontOfQueue(msg1);
                        }
                    });
                } catch (Exception e)
                {
                    isWait = false;
                    e.printStackTrace();
                }
            }
        };


    }

    public void onDestroy()
    {
        isDestroy = true;
        if(mWorkHandler!=null)
        {
            mWorkHandler.removeCallbacksAndMessages(null);
        }

        if (mUiHandler!=null)
        {
            mUiHandler.removeCallbacksAndMessages(null);
        }
    }


}

具体实现类:

public class EasyQueueThread extends BaseQueueThread
{
    private TextView mTextView;
    public EasyQueueThread(TextView textView)
    {
        super();
        mTextView = textView;
    }

    @Override
    protected Object doInWork(int obj)
    {
        try
        {
            Thread.sleep(1000);
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        return "ok"+obj;
    }

    @Override
    protected void doInUi(Object obj)
    {
        mTextView.setText((String)obj);
    }
}

发送工作线程消息,逐步更新UI:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TextView bt = (TextView) findViewById(R.id.button1);

        EasyQueueThread easyQueueThread = new EasyQueueThread(bt);

        for (int i = 0;i< 10 ;i++)
        {
            easyQueueThread.sendMessage(i,i);
        }

    }
}

3.总结:耗时操作不要放在UI线程,关键点要处理好什么时候执行工作线程,什么时候执行UI线程。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值