Androidアプリで簡易なthrottle処理を実装する……の、続き


前回の投稿ですが、独立したクラスにして、他のActivityからでも参照できるようにしたほうがいいかと思いました。こちらの方がより汎用性・可読性の意味で使いやすいのではないでしょうか。

[MainActivity.java]

    /** throttle処理で間引く間隔 */
    private static final int THROTTLE_INTERVAL = 60 * 1 * 1000;

    /** throttle処理クラス */
    private Throttle throttle;
    ・
    ・
    ・
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        // 初期化
        throttle = new Throttle(THROTTLE_INTERVAL);
    }
    ・
    ・
    ・
    // コード上の任意の場所で
    {
        //throttle処理を入れて間引く
        throttle.setThrottle(new Throttle.ThrottleEventListener() {
            @Override
            public void onActuate(){
                //実行したい処理
                ・
                ・
                ・
            }
        });
    }

[Throttle.java]

/**
 * Javaでthrottle処理を行う
 */
public class Throttle {

    /**
     * throttle処理用のハンドラ
     */
    private Handler throttleHandler;

    /**
     * throttle処理を実行した最後の時間
     */
    private long throttleLastTimeMillis;

    /**
     * 処理を間引く間隔(ミリ秒)
     */
    long throtteleInterval;

    /**
     * リスナ
     */
    private ThrottleEventListener throttleEventListener;

    //--------------------------------------------------------------
    // コンストラクタ
    //--------------------------------------------------------------
    public Throttle(long throtteleInterval) {
        //初期化
        throttleHandler = new Handler();
        throttleLastTimeMillis = 0;

        //間引く間隔を定義する
        this.throtteleInterval = throtteleInterval;
    }

    //--------------------------------------------------------------
    // メソッド
    //--------------------------------------------------------------
    public void setThrottle(ThrottleEventListener throttleEventListener) {
        //イベントを通知するリスナーセット
        this.throttleEventListener = throttleEventListener;

        long currentTimeMillis = System.currentTimeMillis();

        // 最後に実行した時間から間引きたい時間経過していたら実行
        if ((throttleLastTimeMillis + throtteleInterval) <= currentTimeMillis) {
            throttleLastTimeMillis = currentTimeMillis;

            //処理実行
            throttleEventListener.onActuate();
        } else {
            //重複して呼び出さないようにキャンセルするのを忘れずに
            throttleHandler.removeCallbacks(throttleTask);
            //間引いた場合は、間隔明けに実行する
            throttleHandler.postDelayed(throttleTask, (throttleLastTimeMillis + throtteleInterval) - currentTimeMillis);
        }
    }

    //--------------------------------------------------------------
    // タスク
    //--------------------------------------------------------------
    private final Runnable throttleTask = new Runnable() {
        @Override
        public void run() {
        throttleHandler.removeCallbacks(throttleTask);

        throttleLastTimeMillis = System.currentTimeMillis();

        //処理実行
        throttleEventListener.onActuate();
        }
    };

    //--------------------------------------------------------------
    // イベントリスナ
    //--------------------------------------------------------------
    public interface ThrottleEventListener {
        /**
         * 通知
         */
        void onActuate();
    }
}

独立したクラスでほとんどの処理が完結しているので、Activity側では実質、間引き時間だけを管理すれば良いという状態になり非常に楽です。
当たり前ですが、Throttleクラスをnewするのは1回だけ(onCreate内でだけ)にしてくださいね。じゃないと、newした分だけタスクが走ることになり、処理が重複してしまいます。

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください