diff --git a/app/src/main/java/io/github/muntashirakon/AppManager/main/MainViewModel.java b/app/src/main/java/io/github/muntashirakon/AppManager/main/MainViewModel.java
index 849d76ed560f3eb701063b379fe3926012549bf8..5e3ca1ca22cd0682fb7fdb7c7c848c3ccd3a21ae 100644
--- a/app/src/main/java/io/github/muntashirakon/AppManager/main/MainViewModel.java
+++ b/app/src/main/java/io/github/muntashirakon/AppManager/main/MainViewModel.java
@@ -44,6 +44,7 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.Future;
 
 import io.github.muntashirakon.AppManager.apk.list.ListExporter;
 import io.github.muntashirakon.AppManager.backup.BackupUtils;
@@ -63,13 +64,13 @@ import io.github.muntashirakon.AppManager.users.Users;
 import io.github.muntashirakon.AppManager.utils.ArrayUtils;
 import io.github.muntashirakon.AppManager.utils.MultithreadedExecutor;
 import io.github.muntashirakon.AppManager.utils.PackageUtils;
+import io.github.muntashirakon.AppManager.utils.ThreadUtils;
 import io.github.muntashirakon.AppManager.utils.Utils;
 import io.github.muntashirakon.io.Path;
 
 public class MainViewModel extends AndroidViewModel implements ListOptions.ListOptionActions {
     private final PackageManager mPackageManager;
     private final PackageIntentReceiver mPackageObserver;
-    private final Handler mHandler;
     @MainListOptions.SortOrder
     private int mSortBy;
     private boolean mReverseSort;
@@ -82,6 +83,7 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
     private String mSearchQuery;
     @AdvancedSearchView.SearchType
     private int mSearchType;
+    private Future<?> mFilterResult;
     private final Map<String, ApplicationItem> mSelectedPackageApplicationItemMap = Collections.synchronizedMap(new LinkedHashMap<>());
     final MultithreadedExecutor executor = MultithreadedExecutor.getNewInstance();
 
@@ -89,7 +91,6 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
         super(application);
         Log.d("MVM", "New instance created");
         mPackageManager = application.getPackageManager();
-        mHandler = new Handler(application.getMainLooper());
         mPackageObserver = new PackageIntentReceiver(this);
         mSortBy = Prefs.MainPage.getSortOrder();
         mReverseSort = Prefs.MainPage.isReverseSort();
@@ -207,7 +208,8 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
     public void setSearchQuery(String searchQuery, @AdvancedSearchView.SearchType int searchType) {
         this.mSearchQuery = searchType != AdvancedSearchView.SEARCH_TYPE_REGEX ? searchQuery.toLowerCase(Locale.ROOT) : searchQuery;
         this.mSearchType = searchType;
-        executor.submit(this::filterItemsByFlags);
+        cancelIfRunning();
+        mFilterResult = executor.submit(this::filterItemsByFlags);
     }
 
     @Override
@@ -217,7 +219,8 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
 
     @Override
     public void setReverseSort(boolean reverseSort) {
-        executor.submit(() -> {
+        cancelIfRunning();
+        mFilterResult = executor.submit(() -> {
             sortApplicationList(mSortBy, mReverseSort);
             filterItemsByFlags();
         });
@@ -233,7 +236,8 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
     @Override
     public void setSortBy(int sortBy) {
         if (mSortBy != sortBy) {
-            executor.submit(() -> {
+            cancelIfRunning();
+            mFilterResult = executor.submit(() -> {
                 sortApplicationList(sortBy, mReverseSort);
                 filterItemsByFlags();
             });
@@ -251,14 +255,16 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
     public void addFilterFlag(@MainListOptions.Filter int filterFlag) {
         mFilterFlags |= filterFlag;
         Prefs.MainPage.setFilters(mFilterFlags);
-        executor.submit(this::filterItemsByFlags);
+        cancelIfRunning();
+        mFilterResult = executor.submit(this::filterItemsByFlags);
     }
 
     @Override
     public void removeFilterFlag(@MainListOptions.Filter int filterFlag) {
         mFilterFlags &= ~filterFlag;
         Prefs.MainPage.setFilters(mFilterFlags);
-        executor.submit(this::filterItemsByFlags);
+        cancelIfRunning();
+        mFilterResult = executor.submit(this::filterItemsByFlags);
     }
 
     public void setFilterProfileName(@Nullable String filterProfileName) {
@@ -267,7 +273,8 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
         } else if (mFilterProfileName.equals(filterProfileName)) return;
         mFilterProfileName = filterProfileName;
         Prefs.MainPage.setFilteredProfileName(filterProfileName);
-        executor.submit(this::filterItemsByFlags);
+        cancelIfRunning();
+        mFilterResult = executor.submit(this::filterItemsByFlags);
     }
 
     @Nullable
@@ -298,7 +305,8 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
         }
         mSelectedUsers = selectedUsers;
         // TODO: 5/6/23 Store value to prefs
-        executor.submit(this::filterItemsByFlags);
+        cancelIfRunning();
+        mFilterResult = executor.submit(this::filterItemsByFlags);
     }
 
     @Nullable
@@ -310,7 +318,8 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
     public void onResume() {
         if ((mFilterFlags & MainListOptions.FILTER_RUNNING_APPS) != 0) {
             // Reload filters to get running apps again
-            executor.submit(this::filterItemsByFlags);
+            cancelIfRunning();
+            mFilterResult = executor.submit(this::filterItemsByFlags);
         }
     }
 
@@ -337,7 +346,8 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
 
     @GuardedBy("applicationItems")
     public void loadApplicationItems() {
-        executor.submit(() -> {
+        cancelIfRunning();
+        mFilterResult = executor.submit(() -> {
             List<ApplicationItem> updatedApplicationItems = PackageUtils
                     .getInstalledOrBackedUpApplicationsFromDb(getApplication(), true, true);
             synchronized (mApplicationItems) {
@@ -353,6 +363,13 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
         });
     }
 
+    private void cancelIfRunning() {
+        if (mFilterResult != null) {
+            mFilterResult.cancel(true);
+        }
+    }
+
+    @WorkerThread
     private void filterItemsByQuery(@NonNull List<ApplicationItem> applicationItems) {
         List<ApplicationItem> filteredApplicationItems;
         if (mSearchType == AdvancedSearchView.SEARCH_TYPE_REGEX) {
@@ -361,12 +378,15 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
                         add(item.packageName);
                         add(item.label);
                     }}, AdvancedSearchView.SEARCH_TYPE_REGEX);
-            mHandler.post(() -> mApplicationItemsLiveData.postValue(filteredApplicationItems));
+            mApplicationItemsLiveData.postValue(filteredApplicationItems);
             return;
         }
         // Others
         filteredApplicationItems = new ArrayList<>();
         for (ApplicationItem item : applicationItems) {
+            if (ThreadUtils.isInterrupted()) {
+                return;
+            }
             if (AdvancedSearchView.matches(mSearchQuery, item.packageName.toLowerCase(Locale.ROOT), mSearchType)) {
                 filteredApplicationItems.add(item);
             } else if (mSearchType == AdvancedSearchView.SEARCH_TYPE_CONTAINS) {
@@ -377,7 +397,7 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
                 filteredApplicationItems.add(item);
             }
         }
-        mHandler.post(() -> mApplicationItemsLiveData.postValue(filteredApplicationItems));
+        mApplicationItemsLiveData.postValue(filteredApplicationItems);
     }
 
     @WorkerThread
@@ -392,6 +412,9 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
                     AppsProfile profile = AppsProfile.fromPath(profilePath);
                     List<Integer> indexes = new ArrayList<>();
                     for (String packageName : profile.packages) {
+                        if (ThreadUtils.isInterrupted()) {
+                            return;
+                        }
                         ApplicationItem item = new ApplicationItem();
                         item.packageName = packageName;
                         int index = mApplicationItems.indexOf(item);
@@ -401,6 +424,9 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
                     }
                     Collections.sort(indexes);
                     for (int index : indexes) {
+                        if (ThreadUtils.isInterrupted()) {
+                            return;
+                        }
                         ApplicationItem item = mApplicationItems.get(index);
                         if (isAmongSelectedUsers(item)) {
                             candidateApplicationItems.add(item);
@@ -411,6 +437,9 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
                 }
             } else {
                 for (ApplicationItem item : mApplicationItems) {
+                    if (ThreadUtils.isInterrupted()) {
+                        return;
+                    }
                     if (isAmongSelectedUsers(item)) {
                         candidateApplicationItems.add(item);
                     }
@@ -421,7 +450,7 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
                 if (!TextUtils.isEmpty(mSearchQuery)) {
                     filterItemsByQuery(candidateApplicationItems);
                 } else {
-                    mHandler.post(() -> mApplicationItemsLiveData.postValue(candidateApplicationItems));
+                    mApplicationItemsLiveData.postValue(candidateApplicationItems);
                 }
             } else {
                 List<ApplicationItem> filteredApplicationItems = new ArrayList<>();
@@ -429,6 +458,9 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
                     loadRunningApps();
                 }
                 for (ApplicationItem item : candidateApplicationItems) {
+                    if (ThreadUtils.isInterrupted()) {
+                        return;
+                    }
                     // Filter user and system apps first (if requested)
                     if ((mFilterFlags & MainListOptions.FILTER_USER_APPS) != 0 && !item.isUser) {
                         continue;
@@ -472,7 +504,7 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
                 if (!TextUtils.isEmpty(mSearchQuery)) {
                     filterItemsByQuery(filteredApplicationItems);
                 } else {
-                    mHandler.post(() -> mApplicationItemsLiveData.postValue(filteredApplicationItems));
+                    mApplicationItemsLiveData.postValue(filteredApplicationItems);
                 }
             }
         }
@@ -499,9 +531,15 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
                 runningAppProcessInfoList = ActivityManagerCompat.getRunningAppProcesses();
                 Set<String> runningPackages = new HashSet<>();
                 for (ActivityManager.RunningAppProcessInfo runningAppProcessInfo : runningAppProcessInfoList) {
+                    if (ThreadUtils.isInterrupted()) {
+                        return;
+                    }
                     Collections.addAll(runningPackages, runningAppProcessInfo.pkgList);
                 }
                 for (int i = 0; i < mApplicationItems.size(); ++i) {
+                    if (ThreadUtils.isInterrupted()) {
+                        return;
+                    }
                     ApplicationItem applicationItem = mApplicationItems.get(i);
                     applicationItem.isRunning = applicationItem.isInstalled
                             && runningPackages.contains(applicationItem.packageName);
@@ -787,6 +825,7 @@ public class MainViewModel extends AndroidViewModel implements ListOptions.ListO
         @Override
         @WorkerThread
         protected void onPackageChanged(Intent intent, @Nullable Integer uid, @Nullable String[] packages) {
+            mModel.cancelIfRunning();
             if (uid != null) {
                 mModel.updateInfoForUid(uid, intent.getAction());
             } else if (packages != null) {
diff --git a/app/src/main/java/io/github/muntashirakon/AppManager/misc/AdvancedSearchView.java b/app/src/main/java/io/github/muntashirakon/AppManager/misc/AdvancedSearchView.java
index af0f5a87572d4dd5ca68fba41cd033a7d16e38c3..01fc3396e0559f939a9b0ed7d6737652e64c297c 100644
--- a/app/src/main/java/io/github/muntashirakon/AppManager/misc/AdvancedSearchView.java
+++ b/app/src/main/java/io/github/muntashirakon/AppManager/misc/AdvancedSearchView.java
@@ -38,6 +38,7 @@ import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 
 import io.github.muntashirakon.AppManager.R;
+import io.github.muntashirakon.AppManager.utils.ThreadUtils;
 import io.github.muntashirakon.util.UiUtils;
 import io.github.muntashirakon.widget.SearchView;
 
@@ -387,13 +388,16 @@ public class AdvancedSearchView extends SearchView {
     public static <T> List<T> matches(@NonNull String query, @Nullable Collection<T> choices,
                                       @NonNull ChoicesGenerator<T> generator, @SearchType int type) {
         if (choices == null) return null;
-        if (choices.size() == 0) return Collections.emptyList();
+        if (choices.isEmpty()) return Collections.emptyList();
         List<T> results = new ArrayList<>(choices.size());
         if (type == SEARCH_TYPE_REGEX) {
             Pattern p;
             try {
                 p = Pattern.compile(query);
                 for (T choice : choices) {
+                    if (ThreadUtils.isInterrupted()) {
+                        return Collections.emptyList();
+                    }
                     List<String> texts = generator.getChoices(choice);
                     for (String text : texts) {
                         if (text == null) continue;
@@ -409,6 +413,9 @@ public class AdvancedSearchView extends SearchView {
         }
         // Rests are typical
         for (T choice : choices) {
+            if (ThreadUtils.isInterrupted()) {
+                return Collections.emptyList();
+            }
             List<String> texts = generator.getChoices(choice);
             for (String text : texts) {
                 if (text == null) continue;