diff --git a/app/src/main/java/com/fongmi/android/tv/model/LiveViewModel.java b/app/src/main/java/com/fongmi/android/tv/model/LiveViewModel.java index 2d7c6e69e..731c2f65a 100644 --- a/app/src/main/java/com/fongmi/android/tv/model/LiveViewModel.java +++ b/app/src/main/java/com/fongmi/android/tv/model/LiveViewModel.java @@ -33,6 +33,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; public class LiveViewModel extends ViewModel { @@ -50,10 +51,12 @@ public class LiveViewModel extends ViewModel { } } + private final Map taskIds; private final List formatTime; private final Map> futures; private final SimpleDateFormat formatDate; private final ExecutorService executor; + public final MutableLiveData xml; public final MutableLiveData url; public final MutableLiveData live; @@ -66,10 +69,12 @@ public class LiveViewModel extends ViewModel { this.url = new MutableLiveData<>(); this.formatTime = new ArrayList<>(); this.futures = new EnumMap<>(TaskType.class); + this.taskIds = new EnumMap<>(TaskType.class); this.executor = Executors.newFixedThreadPool(2); this.formatDate = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()); this.formatTime.add(new SimpleDateFormat("yyyy-MM-ddHH:mm", Locale.getDefault())); this.formatTime.add(new SimpleDateFormat("yyyy-MM-ddHH:mm:ss", Locale.getDefault())); + for (TaskType type : TaskType.values()) taskIds.put(type, new AtomicInteger(0)); } public void getLive(Live item) { @@ -138,6 +143,8 @@ public class LiveViewModel extends ViewModel { private void execute(TaskType type, Callable callable) { Future oldFuture = futures.get(type); + AtomicInteger taskId = taskIds.get(type); + int currentId = taskId.incrementAndGet(); if (oldFuture != null && !oldFuture.isDone()) oldFuture.cancel(true); Future newFuture = App.submit(callable); if (executor.isShutdown()) return; @@ -145,12 +152,14 @@ public class LiveViewModel extends ViewModel { executor.execute(() -> { try { T result = newFuture.get(type.timeout, TimeUnit.MILLISECONDS); + if (taskId.get() != currentId) return; if (type == TaskType.EPG) epg.postValue((Epg) result); else if (type == TaskType.LIVE) live.postValue((Live) result); else if (type == TaskType.URL) url.postValue((Result) result); else if (type == TaskType.XML) xml.postValue((Boolean) result); + } catch (CancellationException ignored) { } catch (Throwable e) { - if (e instanceof CancellationException) return; + if (taskId.get() != currentId) return; if (e.getCause() instanceof ExtractException) url.postValue(Result.error(e.getCause().getMessage())); else if (type == TaskType.LIVE) live.postValue(new Live()); else if (type == TaskType.URL) url.postValue(new Result()); diff --git a/app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java b/app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java index 866051e7b..d2cc1f940 100644 --- a/app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java +++ b/app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java @@ -36,6 +36,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import okhttp3.Call; import okhttp3.Response; @@ -44,6 +45,7 @@ public class SiteViewModel extends ViewModel { private final List> searchFuture; private final ExecutorService executor; + private final AtomicInteger taskId; private Future future; public final MutableLiveData episode; @@ -53,6 +55,7 @@ public class SiteViewModel extends ViewModel { public final MutableLiveData action; public SiteViewModel() { + taskId = new AtomicInteger(0); episode = new MutableLiveData<>(); result = new MutableLiveData<>(); player = new MutableLiveData<>(); @@ -254,15 +257,18 @@ public class SiteViewModel extends ViewModel { } private void execute(MutableLiveData result, Callable callable) { + int currentId = taskId.incrementAndGet(); if (future != null && !future.isDone()) future.cancel(true); if (executor.isShutdown()) return; future = App.submit(callable); executor.execute(() -> { try { Result taskResult = future.get(Constant.TIMEOUT_VOD, TimeUnit.MILLISECONDS); + if (taskId.get() != currentId) return; result.postValue(taskResult); + } catch (CancellationException ignored) { } catch (Throwable e) { - if (e instanceof CancellationException) return; + if (taskId.get() != currentId) return; if (e.getCause() instanceof ExtractException) result.postValue(Result.error(e.getCause().getMessage())); else result.postValue(Result.empty()); e.printStackTrace();