[app] Improve scope list performance
This commit is contained in:
parent
cb5c9ea4d2
commit
76cf325321
|
|
@ -32,11 +32,13 @@ import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.github.lsposed.manager.ConfigManager;
|
||||||
import io.github.lsposed.manager.R;
|
import io.github.lsposed.manager.R;
|
||||||
|
|
||||||
public class AppHelper {
|
public class AppHelper {
|
||||||
|
|
||||||
public static final String SETTINGS_CATEGORY = "de.robv.android.xposed.category.MODULE_SETTINGS";
|
public static final String SETTINGS_CATEGORY = "de.robv.android.xposed.category.MODULE_SETTINGS";
|
||||||
|
private static List<PackageInfo> appList;
|
||||||
|
|
||||||
public static Intent getSettingsIntent(String packageName, PackageManager packageManager) {
|
public static Intent getSettingsIntent(String packageName, PackageManager packageManager) {
|
||||||
// taken from
|
// taken from
|
||||||
|
|
@ -113,4 +115,11 @@ public class AppHelper {
|
||||||
return (PackageInfo a, PackageInfo b) -> displayNameComparator.compare(a.applicationInfo, b.applicationInfo);
|
return (PackageInfo a, PackageInfo b) -> displayNameComparator.compare(a.applicationInfo, b.applicationInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<PackageInfo> getAppList(boolean force) {
|
||||||
|
if (appList == null || force) {
|
||||||
|
appList = ConfigManager.getInstalledPackagesFromAllUsers(PackageManager.GET_META_DATA, true);
|
||||||
|
}
|
||||||
|
return appList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,30 +90,32 @@ public class ScopeAdapter extends RecyclerView.Adapter<ScopeAdapter.ViewHolder>
|
||||||
private final SharedPreferences preferences;
|
private final SharedPreferences preferences;
|
||||||
private final String modulePackageName;
|
private final String modulePackageName;
|
||||||
private final String moduleName;
|
private final String moduleName;
|
||||||
private final SwitchBar masterSwitch;
|
|
||||||
private final HashSet<ApplicationWithEquals> recommendedList = new HashSet<>();
|
private final HashSet<ApplicationWithEquals> recommendedList = new HashSet<>();
|
||||||
private final HashSet<ApplicationWithEquals> checkedList = new HashSet<>();
|
private final HashSet<ApplicationWithEquals> checkedList = new HashSet<>();
|
||||||
private final List<AppInfo> searchList = new ArrayList<>();
|
private final List<AppInfo> searchList = new ArrayList<>();
|
||||||
private List<AppInfo> showList = new ArrayList<>();
|
private final SwitchBar.OnCheckedChangeListener switchBarOnCheckedChangeListener = new SwitchBar.OnCheckedChangeListener() {
|
||||||
private ApplicationInfo selectedInfo;
|
@Override
|
||||||
private boolean enabled = true;
|
public boolean onCheckedChanged(SwitchBar view, boolean isChecked) {
|
||||||
|
|
||||||
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) -> {
|
|
||||||
if (!ModuleUtil.getInstance().setModuleEnabled(modulePackageName, isChecked)) {
|
if (!ModuleUtil.getInstance().setModuleEnabled(modulePackageName, isChecked)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
enabled = isChecked;
|
enabled = isChecked;
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
return true;
|
return true;
|
||||||
});
|
}
|
||||||
refresh();
|
};
|
||||||
|
private List<AppInfo> 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
|
@NonNull
|
||||||
|
|
@ -123,11 +125,8 @@ public class ScopeAdapter extends RecyclerView.Adapter<ScopeAdapter.ViewHolder>
|
||||||
return new ViewHolder(v);
|
return new ViewHolder(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadApps() {
|
private void loadApps(boolean force) {
|
||||||
enabled = ModuleUtil.getInstance().isModuleEnabled(modulePackageName);
|
List<PackageInfo> appList = AppHelper.getAppList(force);
|
||||||
activity.runOnUiThread(() -> masterSwitch.setChecked(enabled));
|
|
||||||
|
|
||||||
List<PackageInfo> appList = ConfigManager.getInstalledPackagesFromAllUsers(PackageManager.GET_META_DATA, true);
|
|
||||||
checkedList.clear();
|
checkedList.clear();
|
||||||
recommendedList.clear();
|
recommendedList.clear();
|
||||||
searchList.clear();
|
searchList.clear();
|
||||||
|
|
@ -171,6 +170,9 @@ public class ScopeAdapter extends RecyclerView.Adapter<ScopeAdapter.ViewHolder>
|
||||||
ConfigManager.setModuleScope(modulePackageName, checkedList);
|
ConfigManager.setModuleScope(modulePackageName, checkedList);
|
||||||
}
|
}
|
||||||
showList = sortApps(searchList);
|
showList = sortApps(searchList);
|
||||||
|
synchronized (this) {
|
||||||
|
refreshing = false;
|
||||||
|
}
|
||||||
activity.onDataReady();
|
activity.onDataReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -267,6 +269,9 @@ public class ScopeAdapter extends RecyclerView.Adapter<ScopeAdapter.ViewHolder>
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
} else if (itemId == R.id.menu_refresh) {
|
||||||
|
refresh(true);
|
||||||
|
return true;
|
||||||
} else if (itemId == R.id.item_show_system) {
|
} else if (itemId == R.id.item_show_system) {
|
||||||
item.setChecked(!item.isChecked());
|
item.setChecked(!item.isChecked());
|
||||||
preferences.edit().putBoolean("show_system_apps", item.isChecked()).apply();
|
preferences.edit().putBoolean("show_system_apps", item.isChecked()).apply();
|
||||||
|
|
@ -299,7 +304,7 @@ public class ScopeAdapter extends RecyclerView.Adapter<ScopeAdapter.ViewHolder>
|
||||||
} else if (!AppHelper.onOptionsItemSelected(item, preferences)) {
|
} else if (!AppHelper.onOptionsItemSelected(item, preferences)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
refresh();
|
refresh(false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -481,8 +486,18 @@ public class ScopeAdapter extends RecyclerView.Adapter<ScopeAdapter.ViewHolder>
|
||||||
return showList.size();
|
return showList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refresh() {
|
public void refresh(boolean force) {
|
||||||
AsyncTask.THREAD_POOL_EXECUTOR.execute(this::loadApps);
|
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) {
|
protected void onCheckedChange(CompoundButton buttonView, boolean isChecked, AppInfo appInfo) {
|
||||||
|
|
@ -556,7 +571,7 @@ public class ScopeAdapter extends RecyclerView.Adapter<ScopeAdapter.ViewHolder>
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onBackPressed() {
|
public boolean onBackPressed() {
|
||||||
if (masterSwitch.isChecked() && checkedList.isEmpty()) {
|
if (activity.binding.masterSwitch.isChecked() && checkedList.isEmpty()) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||||
builder.setTitle(R.string.use_recommended);
|
builder.setTitle(R.string.use_recommended);
|
||||||
builder.setMessage(!recommendedList.isEmpty() ? R.string.no_scope_selected_has_recommended : R.string.no_scope_selected);
|
builder.setMessage(!recommendedList.isEmpty() ? R.string.no_scope_selected_has_recommended : R.string.no_scope_selected);
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,6 @@ package io.github.lsposed.manager.ui.activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
|
@ -54,7 +52,6 @@ public class AppListActivity extends BaseActivity {
|
||||||
|
|
||||||
private SearchView.OnQueryTextListener searchListener;
|
private SearchView.OnQueryTextListener searchListener;
|
||||||
public ActivityAppListBinding binding;
|
public ActivityAppListBinding binding;
|
||||||
private final Handler handler = new Handler(Looper.getMainLooper());
|
|
||||||
public ActivityResultLauncher<String> backupLauncher;
|
public ActivityResultLauncher<String> backupLauncher;
|
||||||
public ActivityResultLauncher<String[]> restoreLauncher;
|
public ActivityResultLauncher<String[]> restoreLauncher;
|
||||||
|
|
||||||
|
|
@ -73,7 +70,7 @@ public class AppListActivity extends BaseActivity {
|
||||||
bar.setDisplayHomeAsUpEnabled(true);
|
bar.setDisplayHomeAsUpEnabled(true);
|
||||||
bar.setTitle(moduleName);
|
bar.setTitle(moduleName);
|
||||||
bar.setSubtitle(modulePackageName);
|
bar.setSubtitle(modulePackageName);
|
||||||
scopeAdapter = new ScopeAdapter(this, moduleName, modulePackageName, binding.masterSwitch);
|
scopeAdapter = new ScopeAdapter(this, moduleName, modulePackageName);
|
||||||
scopeAdapter.setHasStableIds(true);
|
scopeAdapter.setHasStableIds(true);
|
||||||
binding.recyclerView.setAdapter(scopeAdapter);
|
binding.recyclerView.setAdapter(scopeAdapter);
|
||||||
binding.recyclerView.setHasFixedSize(true);
|
binding.recyclerView.setHasFixedSize(true);
|
||||||
|
|
@ -140,7 +137,7 @@ public class AppListActivity extends BaseActivity {
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
alertDialog.dismiss();
|
alertDialog.dismiss();
|
||||||
makeSnackBar(success ? R.string.settings_restore_success : R.string.settings_restore_failed, Snackbar.LENGTH_SHORT);
|
makeSnackBar(success ? R.string.settings_restore_success : R.string.settings_restore_failed, Snackbar.LENGTH_SHORT);
|
||||||
scopeAdapter.refresh();
|
scopeAdapter.refresh(false);
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
@ -167,9 +164,11 @@ public class AppListActivity extends BaseActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDataReady() {
|
public void onDataReady() {
|
||||||
handler.post(() -> binding.progress.setIndeterminate(false));
|
runOnUiThread(() -> {
|
||||||
String queryStr = searchView != null ? searchView.getQuery().toString() : "";
|
binding.progress.setIndeterminate(false);
|
||||||
runOnUiThread(() -> scopeAdapter.getFilter().filter(queryStr));
|
String queryStr = searchView != null ? searchView.getQuery().toString() : "";
|
||||||
|
scopeAdapter.getFilter().filter(queryStr);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ public class ModulesActivity extends ListActivity implements ModuleUtil.ModuleLi
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
adapter.refresh();
|
adapter.refresh(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -105,6 +105,15 @@ public class ModulesActivity extends ListActivity implements ModuleUtil.ModuleLi
|
||||||
adapter.refresh();
|
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
|
@Override
|
||||||
public boolean onContextItemSelected(@NonNull MenuItem item) {
|
public boolean onContextItemSelected(@NonNull MenuItem item) {
|
||||||
ModuleUtil.InstalledModule module = ModuleUtil.getInstance().getModule(selectedPackageName);
|
ModuleUtil.InstalledModule module = ModuleUtil.getInstance().getModule(selectedPackageName);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ package io.github.lsposed.manager.ui.activity;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
@ -228,7 +227,7 @@ public class SettingsActivity extends BaseActivity {
|
||||||
new AlertDialog.Builder(requireActivity())
|
new AlertDialog.Builder(requireActivity())
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.setMessage(R.string.settings_sandhook_deprecated_warning)
|
.setMessage(R.string.settings_sandhook_deprecated_warning)
|
||||||
.setPositiveButton(android.R.string.ok, (di, i) -> {})
|
.setPositiveButton(android.R.string.ok, null)
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
return ConfigManager.setVariant(Integer.parseInt((String) newValue));
|
return ConfigManager.setVariant(Integer.parseInt((String) newValue));
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,12 @@
|
||||||
android:icon="@drawable/ic_settings"
|
android:icon="@drawable/ic_settings"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_refresh"
|
||||||
|
android:title="@string/refresh"
|
||||||
|
android:icon="@drawable/ic_refresh"
|
||||||
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/use_recommended"
|
android:id="@+id/use_recommended"
|
||||||
android:title="@string/use_recommended" />
|
android:title="@string/use_recommended" />
|
||||||
|
|
|
||||||
|
|
@ -26,4 +26,11 @@
|
||||||
android:id="@+id/menu_search"
|
android:id="@+id/menu_search"
|
||||||
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_refresh"
|
||||||
|
android:title="@string/refresh"
|
||||||
|
android:icon="@drawable/ic_refresh"
|
||||||
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
Loading…
Reference in New Issue