安卓任务调度

625 阅读2分钟
  1. 任务调度管理任务的执行,因为特殊性,有些任务需要先进先出,排队进行,同时任务只能一个个执行
  2. 据我所知,了解三种方案:

- Handler,HandlerThread

- ExecutorService

- Action

  1. Handler,HandlerThread 任务需要在工作线程中HandlerThread中执行,通过Handler的发送消息和处理消息,保证顺序长时间执行,保证线程不会阻塞。
       private Handler eventHandler = null;

       HandlerThread handlerThread = new HandlerThread("WebSocketThread");
       handlerThread.start();
       eventHandler = new Handler(handlerThread.getLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                internalHandler.handleEvent(msg);
                if (!externalHandlers.isEmpty()) {
                    for (IEventHandler handler : externalHandlers) {
                        handler.handleEvent(msg);
                    }
                }
            }
        };

  1. ExecutorService

    通过封装ExecutorService 来实现单线程一个个顺序执行,它也可以实现并行执行,可以参看 Executors相关的工厂方法来确定.

public enum SingleExecutor {
    INSTANCE;
    ExecutorService executorService = Executors.newSingleThreadExecutor();

    public ExecutorService getExecutorService() {
        return executorService;
    }
}

通过ExecutorService来submit执行Runnable,实现任务的执行,多个任务执行内部线程插入进行任务调度。

  1. 自定任务机制,比较麻烦,不建议使用。需要自己维护事件和线程,容易出错。
public class Executor implements LifecycleObserver,
        Action.OnFinishedListener,
        Action.OnReadyListener {
    private static Executor sInstance = null;
    private final IWSServer wsServer;
    private final LinkedList<Action<?>> ongoingActions = new LinkedList<>();
    private final List<Action<?>> pendingActions = new ArrayList<>();
    private WorkThread curThread = null;

    private Executor(IWSServer server) {
        wsServer = server;
    }

    public static Executor getInstance(IWSServer server) {
        if (sInstance == null) {
            synchronized (Executor.class) {
                if (sInstance == null) {
                    sInstance = new Executor(server);
                }
            }
        }

        return sInstance;
    }

    public void add(Action<?> action) {
        if (action == null) {
            return;
        }

        if (!action.isReady()) {
            addPendingAction(action);
        } else {
            addOngoingAction(action);
        }
    }

    /**
     * 反馈
     *
     * @param response
     */
    @Override
    public void onFinished(String response) {
        if (TextUtils.isEmpty(response)) {
            return;
        }
        wsServer.sendMessage(response);
    }

    @Override
    public void onReady(Action<?> action) {
        if (!pendingActions.contains(action)) {
            LogUtil.e("Invalid action in onReady");
            return;
        }

        action.setOnReadyListener(null);
        pendingActions.remove(action);
        addOngoingAction(action);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    private void onDestroy() {
        cancelThread();
    }

    /**
     * 加入队列
     *
     * @param action
     */
    private void addPendingAction(Action<?> action) {
        pendingActions.add(action);
        action.setOnReadyListener(this);
        action.prepare(wsServer);
    }

    /**
     * 正在进行
     *
     * @param action
     */
    private void addOngoingAction(Action<?> action) {
        synchronized (ongoingActions) {
            ongoingActions.add(action);
        }

        if (!ongoingActions.isEmpty() && curThread == null) {
            curThread = new WorkThread();
            curThread.start();
        }
    }

    private void cancelThread() {
        if (curThread != null) {
            curThread.cancel();
            curThread = null;
        }
    }

    private Action<?> popAction() {
        synchronized (ongoingActions) {
            return ongoingActions.isEmpty() ? null : ongoingActions.pop();
        }
    }

    private void process(Action<?> action) {
        action.execute();
    }

    private class WorkThread extends Thread {
        private boolean isCancelled = false;

        @Override
        public void run() {
            LogUtil.e("run work thread to process actions");
            if (isCancelled) {
                return;
            }

            Action<?> current;
            while (!isCancelled && ((current = popAction()) != null)) {
                current.setOnFinishedListener(Executor.this);
                process(current);
            }

            LogUtil.e("finish work thread");
            onFinish();
        }

        public void cancel() {
            isCancelled = true;
        }

        public void onFinish() {
            curThread = null;
        }
    }
}

Action类

public abstract class Action<T extends WSMessage<?>> {
    protected T request;
    protected OnFinishedListener onFinishedListener;
    protected OnReadyListener onReadyListener;

    public Action(T wsMessage) {
        request = wsMessage;
    }

    public abstract void execute();

    public abstract boolean isReady();

    public void setOnFinishedListener(OnFinishedListener listener) {
        onFinishedListener = listener;
    }

    public void setOnReadyListener(OnReadyListener listener) {
        onReadyListener = listener;
    }

    protected void notifyFinish(String response) {
        if (onFinishedListener != null) {
            onFinishedListener.onFinished(response);
        }
    }

    protected void prepare(IWSServer server) {
    }

    public interface OnReadyListener {
        void onReady(Action<?> action);
    }

    public interface OnFinishedListener {
        void onFinished(String response);
    }
}