美文网首页
Android 如何实现RxJava中throttleFirst

Android 如何实现RxJava中throttleFirst

作者: 有没有口罩给我一个 | 来源:发表于2017-12-26 00:12 被阅读0次

    概述

    在指定时间内只执行一次,类似RxJava中的throttleFirst方法,最近在做Android网络监控,发现断网和连上网时,会有回调多次,这样就会导致我们的逻辑被调用多次,不合符需求,本来打算用RxJava中throttleFirst方法做,后来想想还是自己实现,毕竟也不难;

    具体实现:

    package com.manbot.rebot.utils;
    import android.os.Handler;
    import android.os.HandlerThread;
    import android.os.Looper;
    import android.os.Message;
    import android.support.annotation.WorkerThread;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    public class BotSingleCallUtil {
    private static boolean isTimeIn;//是否还在指定时间内
    private static long mTime;//指定的时间,默认2秒
    private static Lock mLock = new ReentrantLock();
    private static BotSingleCallUtil mThrottleFirst;
    private static HandlerThread handlerThread;
    private static Handler handler;
    
    private static BotSingleCallUtil initSingleCall() {
        if (null == mThrottleFirst) {
            try {
                mLock.lock();
                if (null == mThrottleFirst) {
                    mThrottleFirst = new BotSingleCallUtil();
                    isTimeIn = true;
                    mTime = 2000;
                    handlerThread = new HandlerThread("Manbot WorkThread");
                    handlerThread.start();//必须得启动线程,要抛NullException
                    handler = new MyHandler(handlerThread.getLooper());
                }
            } finally {
                mLock.unlock();
            }
        }
        return mThrottleFirst;
    }
    
    static class MyHandler extends Handler {
        public MyHandler(Looper looper) {
            super(looper);
        }
    
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 0) {
                isTimeIn = true;
            } else if (msg.what == 1) {
                Observer observer = (Observer) msg.obj;
                observer.callback();
            }
        }
    }
    
    private BotSingleCallUtil setTimeIn(long time) {
        this.mTime = time;
        return this;
    }
    
    /**
     * 子线程中调用
     *
     * @param observer
     */
    @WorkerThread
    public void subcribe(Observer observer) {
        try {
            mLock.lock();
            if (isTimeIn) {
                isTimeIn = false;
                Message message = handler.obtainMessage();
                message.obj = observer;
                message.what = 1;
                handler.sendMessage(message);
                handler.sendEmptyMessageDelayed(0, mTime);
            }
        } finally {
            mLock.unlock();
        }
    
    }
    //构建者
    public static class Builder {
        public Builder() {
            initSingleCall();
        }
    
        public Builder setTimeIn(long time) {
            if (isTimeIn && mThrottleFirst != null) {
                mThrottleFirst.setTimeIn(time);
            }
            return this;
        }
    
        public BotSingleCallUtil build() {
            return mThrottleFirst;
        }
    }
    
    public interface Observer {
        void callback();
    }
    
    public void release() {
        if (handler != null) {
            handler.removeCallbacksAndMessages(null);
        }
        mThrottleFirst = null;
    }
    }
    

    说明:这里我假装用了构建者模式和单例模式,不是很清楚构建者模式的实现,见笑了各位;

    • 构建者模式:
      构建者模式就是构建复杂对象,并不让使用者知道对象内部如何实现,对外隐藏了具体的实现,例如:Retrofit;
    • 单例模式:
      全局至存在一个对象;

    相关文章

      网友评论

          本文标题:Android 如何实现RxJava中throttleFirst

          本文链接:https://www.haomeiwen.com/subject/tzorgxtx.html