From 76cf325321e855afd2b3ec24c89db037895f3dc6 Mon Sep 17 00:00:00 2001 From: tehcneko <7764726+tehcneko@users.noreply.github.com> Date: Sat, 27 Feb 2021 15:47:52 +0800 Subject: [PATCH] [app] Improve scope list performance --- .../lsposed/manager/adapters/AppHelper.java | 9 +++ .../manager/adapters/ScopeAdapter.java | 63 ++++++++++++------- .../manager/ui/activity/AppListActivity.java | 15 +++-- .../manager/ui/activity/ModulesActivity.java | 11 +++- .../manager/ui/activity/SettingsActivity.java | 3 +- app/src/main/res/menu/menu_app_list.xml | 6 ++ app/src/main/res/menu/menu_modules.xml | 7 +++ 7 files changed, 79 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/io/github/lsposed/manager/adapters/AppHelper.java b/app/src/main/java/io/github/lsposed/manager/adapters/AppHelper.java index 1412a7f0..552b025c 100644 --- a/app/src/main/java/io/github/lsposed/manager/adapters/AppHelper.java +++ b/app/src/main/java/io/github/lsposed/manager/adapters/AppHelper.java @@ -32,11 +32,13 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; +import io.github.lsposed.manager.ConfigManager; import io.github.lsposed.manager.R; public class AppHelper { public static final String SETTINGS_CATEGORY = "de.robv.android.xposed.category.MODULE_SETTINGS"; + private static List appList; public static Intent getSettingsIntent(String packageName, PackageManager packageManager) { // taken from @@ -113,4 +115,11 @@ public class AppHelper { return (PackageInfo a, PackageInfo b) -> displayNameComparator.compare(a.applicationInfo, b.applicationInfo); } } + + public static List getAppList(boolean force) { + if (appList == null || force) { + appList = ConfigManager.getInstalledPackagesFromAllUsers(PackageManager.GET_META_DATA, true); + } + return appList; + } } diff --git a/app/src/main/java/io/github/lsposed/manager/adapters/ScopeAdapter.java b/app/src/main/java/io/github/lsposed/manager/adapters/ScopeAdapter.java index 2e7e3255..a57b5099 100644 --- a/app/src/main/java/io/github/lsposed/manager/adapters/ScopeAdapter.java +++ b/app/src/main/java/io/github/lsposed/manager/adapters/ScopeAdapter.java @@ -90,30 +90,32 @@ public class ScopeAdapter extends RecyclerView.Adapter private final SharedPreferences preferences; private final String modulePackageName; private final String moduleName; - private final SwitchBar masterSwitch; private final HashSet recommendedList = new HashSet<>(); private final HashSet checkedList = new HashSet<>(); private final List searchList = new ArrayList<>(); - private List showList = new ArrayList<>(); - private ApplicationInfo selectedInfo; - private boolean enabled = true; - - public ScopeAdapter(AppListActivity activity, String moduleName, String modulePackageName, SwitchBar masterSwitch) { - this.activity = activity; - this.moduleName = moduleName; - this.modulePackageName = modulePackageName; - this.masterSwitch = masterSwitch; - preferences = App.getPreferences(); - pm = activity.getPackageManager(); - masterSwitch.setOnCheckedChangeListener((view, isChecked) -> { + private final SwitchBar.OnCheckedChangeListener switchBarOnCheckedChangeListener = new SwitchBar.OnCheckedChangeListener() { + @Override + public boolean onCheckedChanged(SwitchBar view, boolean isChecked) { if (!ModuleUtil.getInstance().setModuleEnabled(modulePackageName, isChecked)) { return false; } enabled = isChecked; notifyDataSetChanged(); return true; - }); - refresh(); + } + }; + private List showList = new ArrayList<>(); + private ApplicationInfo selectedInfo; + private boolean refreshing = false; + private boolean enabled = true; + + public ScopeAdapter(AppListActivity activity, String moduleName, String modulePackageName) { + this.activity = activity; + this.moduleName = moduleName; + this.modulePackageName = modulePackageName; + preferences = App.getPreferences(); + pm = activity.getPackageManager(); + refresh(false); } @NonNull @@ -123,11 +125,8 @@ public class ScopeAdapter extends RecyclerView.Adapter return new ViewHolder(v); } - private void loadApps() { - enabled = ModuleUtil.getInstance().isModuleEnabled(modulePackageName); - activity.runOnUiThread(() -> masterSwitch.setChecked(enabled)); - - List appList = ConfigManager.getInstalledPackagesFromAllUsers(PackageManager.GET_META_DATA, true); + private void loadApps(boolean force) { + List appList = AppHelper.getAppList(force); checkedList.clear(); recommendedList.clear(); searchList.clear(); @@ -171,6 +170,9 @@ public class ScopeAdapter extends RecyclerView.Adapter ConfigManager.setModuleScope(modulePackageName, checkedList); } showList = sortApps(searchList); + synchronized (this) { + refreshing = false; + } activity.onDataReady(); } @@ -267,6 +269,9 @@ public class ScopeAdapter extends RecyclerView.Adapter notifyDataSetChanged(); } return true; + } else if (itemId == R.id.menu_refresh) { + refresh(true); + return true; } else if (itemId == R.id.item_show_system) { item.setChecked(!item.isChecked()); preferences.edit().putBoolean("show_system_apps", item.isChecked()).apply(); @@ -299,7 +304,7 @@ public class ScopeAdapter extends RecyclerView.Adapter } else if (!AppHelper.onOptionsItemSelected(item, preferences)) { return false; } - refresh(); + refresh(false); return true; } @@ -481,8 +486,18 @@ public class ScopeAdapter extends RecyclerView.Adapter return showList.size(); } - public void refresh() { - AsyncTask.THREAD_POOL_EXECUTOR.execute(this::loadApps); + public void refresh(boolean force) { + synchronized (this) { + if (refreshing) { + return; + } + refreshing = true; + } + enabled = ModuleUtil.getInstance().isModuleEnabled(modulePackageName); + activity.binding.masterSwitch.setOnCheckedChangeListener(null); + activity.binding.masterSwitch.setChecked(enabled); + activity.binding.masterSwitch.setOnCheckedChangeListener(switchBarOnCheckedChangeListener); + AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> loadApps(force)); } protected void onCheckedChange(CompoundButton buttonView, boolean isChecked, AppInfo appInfo) { @@ -556,7 +571,7 @@ public class ScopeAdapter extends RecyclerView.Adapter } public boolean onBackPressed() { - if (masterSwitch.isChecked() && checkedList.isEmpty()) { + if (activity.binding.masterSwitch.isChecked() && checkedList.isEmpty()) { AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle(R.string.use_recommended); builder.setMessage(!recommendedList.isEmpty() ? R.string.no_scope_selected_has_recommended : R.string.no_scope_selected); diff --git a/app/src/main/java/io/github/lsposed/manager/ui/activity/AppListActivity.java b/app/src/main/java/io/github/lsposed/manager/ui/activity/AppListActivity.java index 234350b6..6011ad99 100644 --- a/app/src/main/java/io/github/lsposed/manager/ui/activity/AppListActivity.java +++ b/app/src/main/java/io/github/lsposed/manager/ui/activity/AppListActivity.java @@ -23,8 +23,6 @@ package io.github.lsposed.manager.ui.activity; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; import android.view.Menu; import android.view.MenuItem; @@ -54,7 +52,6 @@ public class AppListActivity extends BaseActivity { private SearchView.OnQueryTextListener searchListener; public ActivityAppListBinding binding; - private final Handler handler = new Handler(Looper.getMainLooper()); public ActivityResultLauncher backupLauncher; public ActivityResultLauncher restoreLauncher; @@ -73,7 +70,7 @@ public class AppListActivity extends BaseActivity { bar.setDisplayHomeAsUpEnabled(true); bar.setTitle(moduleName); bar.setSubtitle(modulePackageName); - scopeAdapter = new ScopeAdapter(this, moduleName, modulePackageName, binding.masterSwitch); + scopeAdapter = new ScopeAdapter(this, moduleName, modulePackageName); scopeAdapter.setHasStableIds(true); binding.recyclerView.setAdapter(scopeAdapter); binding.recyclerView.setHasFixedSize(true); @@ -140,7 +137,7 @@ public class AppListActivity extends BaseActivity { runOnUiThread(() -> { alertDialog.dismiss(); makeSnackBar(success ? R.string.settings_restore_success : R.string.settings_restore_failed, Snackbar.LENGTH_SHORT); - scopeAdapter.refresh(); + scopeAdapter.refresh(false); }); } catch (Exception e) { e.printStackTrace(); @@ -167,9 +164,11 @@ public class AppListActivity extends BaseActivity { } public void onDataReady() { - handler.post(() -> binding.progress.setIndeterminate(false)); - String queryStr = searchView != null ? searchView.getQuery().toString() : ""; - runOnUiThread(() -> scopeAdapter.getFilter().filter(queryStr)); + runOnUiThread(() -> { + binding.progress.setIndeterminate(false); + String queryStr = searchView != null ? searchView.getQuery().toString() : ""; + scopeAdapter.getFilter().filter(queryStr); + }); } @Override diff --git a/app/src/main/java/io/github/lsposed/manager/ui/activity/ModulesActivity.java b/app/src/main/java/io/github/lsposed/manager/ui/activity/ModulesActivity.java index 579bf36e..121fdb00 100644 --- a/app/src/main/java/io/github/lsposed/manager/ui/activity/ModulesActivity.java +++ b/app/src/main/java/io/github/lsposed/manager/ui/activity/ModulesActivity.java @@ -85,7 +85,7 @@ public class ModulesActivity extends ListActivity implements ModuleUtil.ModuleLi @Override protected void onResume() { super.onResume(); - adapter.refresh(); + adapter.refresh(true); } @Override @@ -105,6 +105,15 @@ public class ModulesActivity extends ListActivity implements ModuleUtil.ModuleLi adapter.refresh(); } + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + int itemId = item.getItemId(); + if (itemId == R.id.menu_refresh) { + adapter.refresh(true); + } + return super.onOptionsItemSelected(item); + } + @Override public boolean onContextItemSelected(@NonNull MenuItem item) { ModuleUtil.InstalledModule module = ModuleUtil.getInstance().getModule(selectedPackageName); diff --git a/app/src/main/java/io/github/lsposed/manager/ui/activity/SettingsActivity.java b/app/src/main/java/io/github/lsposed/manager/ui/activity/SettingsActivity.java index 37b0eb21..d430c08e 100644 --- a/app/src/main/java/io/github/lsposed/manager/ui/activity/SettingsActivity.java +++ b/app/src/main/java/io/github/lsposed/manager/ui/activity/SettingsActivity.java @@ -22,7 +22,6 @@ package io.github.lsposed.manager.ui.activity; import android.annotation.SuppressLint; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; @@ -228,7 +227,7 @@ public class SettingsActivity extends BaseActivity { new AlertDialog.Builder(requireActivity()) .setCancelable(true) .setMessage(R.string.settings_sandhook_deprecated_warning) - .setPositiveButton(android.R.string.ok, (di, i) -> {}) + .setPositiveButton(android.R.string.ok, null) .show(); } return ConfigManager.setVariant(Integer.parseInt((String) newValue)); diff --git a/app/src/main/res/menu/menu_app_list.xml b/app/src/main/res/menu/menu_app_list.xml index 44e0266a..626b88d4 100644 --- a/app/src/main/res/menu/menu_app_list.xml +++ b/app/src/main/res/menu/menu_app_list.xml @@ -33,6 +33,12 @@ android:icon="@drawable/ic_settings" app:showAsAction="ifRoom" /> + + diff --git a/app/src/main/res/menu/menu_modules.xml b/app/src/main/res/menu/menu_modules.xml index 02c2ca87..9ea41357 100644 --- a/app/src/main/res/menu/menu_modules.xml +++ b/app/src/main/res/menu/menu_modules.xml @@ -26,4 +26,11 @@ android:id="@+id/menu_search" app:actionViewClass="androidx.appcompat.widget.SearchView" app:showAsAction="ifRoom" /> + + + \ No newline at end of file