顺序执行器
import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
public class ContinuousTrigger2 implements LifecycleEventObserver {
private final static HashMap<LifecycleOwner, ContinuousTrigger2> DIALOG_MANAGER = new HashMap<>();
private ConcurrentLinkedQueue<TriggerTask> mConcurrentLinkedQueue;
private TriggerTask mCurrentRunningTrigger = null;
private Disposable mCurrentDisposable = null;
private ConcurrentHashMap<String, TriggerTask> mTaskMap; // 用于快速查找任务
/**
* 任务包装类,包含标识符和实际任务
*/
public static class TriggerTask {
private final String taskId;
private final Observable<String> observable;
public TriggerTask(String taskId, Observable<String> observable) {
this.taskId = taskId;
this.observable = observable;
}
public String getTaskId() { return taskId; }
public Observable<String> getObservable() { return observable; }
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
TriggerTask that = (TriggerTask) obj;
return taskId.equals(that.taskId);
}
@Override
public int hashCode() {
return taskId.hashCode();
}
}
public static ContinuousTrigger2 getInstance(LifecycleOwner lifecycleOwner) {
ContinuousTrigger2 manager = DIALOG_MANAGER.get(lifecycleOwner);
if (manager == null) {
manager = new ContinuousTrigger2(lifecycleOwner);
DIALOG_MANAGER.put(lifecycleOwner, manager);
}
return manager;
}
private ContinuousTrigger2(LifecycleOwner lifecycleOwner) {
lifecycleOwner.getLifecycle().addObserver(this);
mConcurrentLinkedQueue = new ConcurrentLinkedQueue<>();
mTaskMap = new ConcurrentHashMap<>();
}
/**
* 添加需要执行的事件(推荐使用带任务ID的方法)
*/
public synchronized void addTrigger(Observable<String> trigger) {
// 生成默认任务ID
addTrigger("task_" + System.currentTimeMillis() + "_" + trigger.hashCode(), trigger);
}
/**
* 添加需要执行的事件(带任务ID)
*/
public synchronized void addTrigger(String taskId, Observable<String> trigger) {
if (mConcurrentLinkedQueue == null) {
mConcurrentLinkedQueue = new ConcurrentLinkedQueue<>();
mTaskMap = new ConcurrentHashMap<>();
}
TriggerTask triggerTask = new TriggerTask(taskId, trigger);
mConcurrentLinkedQueue.offer(triggerTask);
mTaskMap.put(taskId, triggerTask);
if (mCurrentRunningTrigger == null) {
next();
}
}
/**
* 删除指定的任务(通过任务ID)
*/
public synchronized boolean removeTriggerById(String taskId) {
if (mConcurrentLinkedQueue == null || taskId == null) {
return false;
}
boolean removed = false;
// 从队列中移除
Iterator<TriggerTask> iterator = mConcurrentLinkedQueue.iterator();
while (iterator.hasNext()) {
TriggerTask task = iterator.next();
if (taskId.equals(task.getTaskId())) {
iterator.remove();
removed = true;
break; // 通常ID唯一,找到一个即可
}
}
// 从快速查找Map中移除
if (mTaskMap.remove(taskId) != null) {
removed = true;
}
return removed;
}
/**
* 删除除了指定任务ID之外的所有任务
* @param preservedTaskIds 需要保留的任务ID数组
* @return 是否成功删除了任务
*/
public synchronized boolean removeAllExcept(String[] preservedTaskIds) {
if (mConcurrentLinkedQueue == null || preservedTaskIds == null) {
return false;
}
boolean removed = false;
// 将需要保留的任务ID转换为Set以便快速查找
java.util.HashSet<String> preservedSet = new java.util.HashSet<>();
for (String id : preservedTaskIds) {
preservedSet.add(id);
}
// 从队列中移除不需要保留的任务
Iterator<TriggerTask> iterator = mConcurrentLinkedQueue.iterator();
while (iterator.hasNext()) {
TriggerTask task = iterator.next();
if (!preservedSet.contains(task.getTaskId())) {
iterator.remove();
removed = true;
}
}
// 从快速查找Map中移除不需要保留的任务
Iterator<String> mapIterator = mTaskMap.keySet().iterator();
while (mapIterator.hasNext()) {
String taskId = mapIterator.next();
if (!preservedSet.contains(taskId)) {
mapIterator.remove();
removed = true;
}
}
return removed;
}
/**
* 删除除了指定任务ID之外的所有任务(重载版本,支持单个任务ID)
* @param preservedTaskId 需要保留的任务ID
* @return 是否成功删除了任务
*/
public synchronized boolean removeAllExcept(String preservedTaskId) {
return removeAllExcept(new String[]{preservedTaskId});
}
/**
* 删除所有任务,只保留当前正在执行的任务(如果有)
* @return 是否成功删除了任务
*/
public synchronized boolean removeAllExceptCurrent() {
if (mCurrentRunningTrigger == null) {
return clearAllTrigger();
}
return removeAllExcept(new String[]{mCurrentRunningTrigger.getTaskId()});
}
/**
* 删除指定的任务(通过Observable对象引用)
*/
public synchronized boolean removeTrigger(Observable<String> trigger) {
if (mConcurrentLinkedQueue == null || trigger == null) {
return false;
}
boolean removed = false;
Iterator<TriggerTask> iterator = mConcurrentLinkedQueue.iterator();
while (iterator.hasNext()) {
TriggerTask task = iterator.next();
if (task.getObservable().equals(trigger)) {
iterator.remove();
// 同时从Map中移除
mTaskMap.remove(task.getTaskId());
removed = true;
}
}
return removed;
}
/**
* 删除并取消当前正在执行的任务(如果匹配)
*/
public synchronized boolean removeAndCancelTrigger(String taskId) {
boolean removedFromQueue = removeTriggerById(taskId);
// 如果当前正在执行的任务匹配,则取消它
if (mCurrentRunningTrigger != null &&
taskId.equals(mCurrentRunningTrigger.getTaskId())) {
cancelCurrentTrigger();
return true;
}
return removedFromQueue;
}
/**
* 取消当前正在执行的任务
*/
public synchronized void cancelCurrentTrigger() {
if (mCurrentDisposable != null && !mCurrentDisposable.isDisposed()) {
mCurrentDisposable.dispose();
mCurrentDisposable = null;
mCurrentRunningTrigger = null;
// 立即执行下一个任务
next();
}
}
/**
* 获取当前队列中的任务数量
*/
public synchronized int getPendingTaskCount() {
return mConcurrentLinkedQueue != null ? mConcurrentLinkedQueue.size() : 0;
}
/**
* 判断指定任务是否在队列中
*/
public synchronized boolean containsTask(String taskId) {
return mTaskMap.containsKey(taskId);
}
/**
* 获取所有待执行任务的ID列表
*/
public synchronized java.util.List<String> getAllTaskIds() {
java.util.List<String> taskIds = new java.util.ArrayList<>();
if (mConcurrentLinkedQueue != null) {
for (TriggerTask task : mConcurrentLinkedQueue) {
taskIds.add(task.getTaskId());
}
}
return taskIds;
}
/**
* 清空所有执行的事件
*/
public synchronized boolean clearAllTrigger() {
boolean hadTasks = false;
if (mConcurrentLinkedQueue != null && !mConcurrentLinkedQueue.isEmpty()) {
hadTasks = true;
mConcurrentLinkedQueue.clear();
}
if (mTaskMap != null && !mTaskMap.isEmpty()) {
hadTasks = true;
mTaskMap.clear();
}
// 取消当前执行的任务
cancelCurrentTrigger();
return hadTasks;
}
private void next() {
if (mConcurrentLinkedQueue == null) {
return;
}
mCurrentRunningTrigger = mConcurrentLinkedQueue.poll();
if (mCurrentRunningTrigger == null) {
return;
}
// 从快速查找Map中移除,因为任务即将执行
if (mTaskMap != null) {
mTaskMap.remove(mCurrentRunningTrigger.getTaskId());
}
mCurrentRunningTrigger.getObservable()
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
mCurrentDisposable = d;
}
@Override
public void onNext(String s) {
// 可以在这里处理任务执行中的回调
}
@Override
public void onError(Throwable e) {
mCurrentDisposable = null;
mCurrentRunningTrigger = null;
next();
}
@Override
public void onComplete() {
mCurrentDisposable = null;
mCurrentRunningTrigger = null;
next();
}
});
}
@Override
public void onStateChanged(@NonNull LifecycleOwner lifecycleOwner, @NonNull Lifecycle.Event event) {
if (event != Lifecycle.Event.ON_DESTROY) {
return;
}
DIALOG_MANAGER.remove(lifecycleOwner);
lifecycleOwner.getLifecycle().removeObserver(this);
clearAllTrigger();
}
}
// 获取实例
ContinuousTrigger trigger = ContinuousTrigger.getInstance(lifecycleOwner);
// 添加多个任务
trigger.addTrigger("dialog_guide", Observable.just("Guide dialog"));
trigger.addTrigger("update_prompt", Observable.just("Update prompt"));
trigger.addTrigger("ad_popup", Observable.just("Ad popup"));
trigger.addTrigger("notification", Observable.just("Notification"));
// 只保留"dialog_guide"任务,删除其他所有任务
trigger.removeAllExcept("dialog_guide");
// 或者保留多个任务
trigger.removeAllExcept(new String[]{"dialog_guide", "update_prompt"});
// 只保留当前正在执行的任务
trigger.removeAllExceptCurrent();
// 清除所有任务
trigger.clearAllTrigger()
// 获取所有任务ID查看结果
java.util.List<String> remainingTasks = trigger.getAllTaskIds();