jQuery鼠标指针特效

Thead+Handler+Looper应用实例

使用SeekBar(当用户的选择有变化后,会回调onProgressChanged函数)来控制系统的音效,
比如高音的增益,范围-12~+12dp.
要求1:UI界面不能卡顿,响应流畅
要求2:能实时反应出音效的变化,功能不延迟
要求3:系统必须稳定

假设有如下前提:
1.像系统发送音效调整是一个耗时的操作
2.频繁发送调整命令可能导致界面卡死,系统死机
3.用户从操作是不可控的,可能快速,也可能缓慢,不能让用户感受到滞后的感觉

针对要求1,可以将耗时的操作放在一个独立的线程内,这样不会影响主线程刷新UI
而要求2和要求3的表现是有矛盾的,如果需要实时听到音效的变化,意味着SeekBar在变化的时候,
需要不断的发送变化的值给系统,而不是等用户松手是才发送最终值.但是如果用户操作是快速来回拖动,
必然会产生大量的请求命令,这样违背了前提2.举个例子,用户在1s内从-12拉到+12,这可能产生(假设)24个调整值,
(实际可能少一点,seekBar可能不会触发这么多次onProgressChanged),而发送每个调整值则需要500ms,相当于
用户停止操作后,最坏情况要0.5*24-1 = 11s,才能逐步听到音效的变化.

思路:
如果用户1s内产生了24个调整值,这24个调整值自然有产生的先后顺序,可以按照这个先后顺序将它们放入一个队列中,
然后排队进行处理,直到用户操作结束(500ms才处理一个),队列里面的数就不会在增加!对于这个队列里的值,
是存在优先级,明显后进入队列的值,更能接近用户想要的效果.控制队列中的消息数量,比如:
1.当产生一个新的调整值时,先清空消息队列,然后在才把请求入队
2.当产生一个新的调整值时,先判断消息队列中的数量,根据实际情况删除部分消息,然后才把请求入队

总是去处理最后几个进入队列的调整值

BusinessThread.java

import android.os.Handler;
import android.os.Looper;
import android.os.Message;

public class BusinessThread {
    private Thread mBusinessThread = null;
    private boolean mBusinessThreadStarted = false;
    private BusinessThreadHandler mBusinessThreadHandler = null;

    private void startBusinessThread() {
        if (true == mBusinessThreadStarted) {
            return;
        } else {

            mBusinessThreadStarted = true;
            mBusinessThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    Looper.prepare();
                    mBusinessThreadHandler = new BusinessThreadHandler();
                    Looper.loop();
                }
            });

            mBusinessThread.start();
        }
    }

    class BusinessThreadHandler extends Handler {

        public boolean sendMessage(int what, int arg1, int arg2) {//重写sendMessage
            removeMessages(what);//清理消息队列中未处理的消息
            return super.sendMessage(obtainMessage(what, arg1, arg2));//发送消息到队列
        }

        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 0:
                    //耗时操作
                    break;
            }
        }
    }
}

在Android系统中负责调节音量的SystemUI中音量模块,也用到了类似的设计思路

com.android.systemui.volume.VolumeDialogControllerImpl.java

    private final HandlerThread mWorkerThread;
    private final W mWorker;
    
    public VolumeDialogControllerImpl(...){
            ...
        mWorkerThread = new HandlerThread(VolumeDialogControllerImpl.class.getSimpleName());
        mWorkerThread.start();
        mWorker = new W(mWorkerThread.getLooper());
            ...
            
    }
    
    
    private final class W extends Handler {
        private static final int VOLUME_CHANGED = 1;
           ...
           
        W(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case VOLUME_CHANGED: onVolumeChangedW(msg.arg1, msg.arg2); break;
                ...
            }
        }
    }
posted @ 2024-06-28 15:14  僵小七  阅读(2)  评论(0编辑  收藏  举报