Improve app list loading

This commit is contained in:
tehcneko 2021-01-29 12:11:20 +08:00
parent 84ad87abf0
commit 1899c82eab
3 changed files with 42 additions and 82 deletions

View File

@ -5,7 +5,6 @@ import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.text.TextUtils; import android.text.TextUtils;
@ -29,11 +28,6 @@ import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition; import com.bumptech.glide.request.transition.Transition;
import io.github.lsposed.manager.App;
import io.github.lsposed.manager.R;
import io.github.lsposed.manager.ui.activity.AppListActivity;
import io.github.lsposed.manager.util.GlideApp;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
@ -43,16 +37,21 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import io.github.lsposed.manager.App;
import io.github.lsposed.manager.R;
import io.github.lsposed.manager.ui.activity.AppListActivity;
import io.github.lsposed.manager.util.GlideApp;
public class AppAdapter extends RecyclerView.Adapter<AppAdapter.ViewHolder> implements Filterable { public class AppAdapter extends RecyclerView.Adapter<AppAdapter.ViewHolder> implements Filterable {
protected AppListActivity activity; protected AppListActivity activity;
private final ApplicationInfo.DisplayNameComparator displayNameComparator; private final ApplicationInfo.DisplayNameComparator displayNameComparator;
protected List<ApplicationInfo> fullList, showList; protected List<PackageInfo> fullList, showList;
private final DateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()); private final DateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
private List<String> checkedList; private List<String> checkedList;
private final PackageManager pm; private final PackageManager pm;
private final ApplicationFilter filter; private final ApplicationFilter filter;
private Comparator<ApplicationInfo> cmp; private Comparator<PackageInfo> cmp;
private final SharedPreferences preferences; private final SharedPreferences preferences;
AppAdapter(AppListActivity activity) { AppAdapter(AppListActivity activity) {
@ -63,7 +62,6 @@ public class AppAdapter extends RecyclerView.Adapter<AppAdapter.ViewHolder> impl
filter = new ApplicationFilter(); filter = new ApplicationFilter();
pm = activity.getPackageManager(); pm = activity.getPackageManager();
displayNameComparator = new ApplicationInfo.DisplayNameComparator(pm); displayNameComparator = new ApplicationInfo.DisplayNameComparator(pm);
cmp = displayNameComparator;
refresh(); refresh();
} }
@ -75,9 +73,9 @@ public class AppAdapter extends RecyclerView.Adapter<AppAdapter.ViewHolder> impl
} }
private void loadApps() { private void loadApps() {
fullList = pm.getInstalledApplications(PackageManager.GET_META_DATA); fullList = pm.getInstalledPackages(PackageManager.GET_META_DATA);
List<ApplicationInfo> rmList = new ArrayList<>(); List<PackageInfo> rmList = new ArrayList<>();
for (ApplicationInfo info : fullList) { for (PackageInfo info : fullList) {
if (this instanceof ScopeAdapter) { if (this instanceof ScopeAdapter) {
boolean white = AppHelper.isWhiteListMode(); boolean white = AppHelper.isWhiteListMode();
List<String> list = AppHelper.getAppList(white); List<String> list = AppHelper.getAppList(white);
@ -97,11 +95,11 @@ public class AppAdapter extends RecyclerView.Adapter<AppAdapter.ViewHolder> impl
} }
} }
if (!preferences.getBoolean("show_modules", true)) { if (!preferences.getBoolean("show_modules", true)) {
if (info.metaData != null && info.metaData.containsKey("xposedmodule") || AppHelper.forceWhiteList.contains(info.packageName)) { if (info.applicationInfo.metaData != null && info.applicationInfo.metaData.containsKey("xposedmodule") || AppHelper.forceWhiteList.contains(info.packageName)) {
rmList.add(info); rmList.add(info);
} }
} }
if (!preferences.getBoolean("show_system_apps", true) && (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { if (!preferences.getBoolean("show_system_apps", true) && (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
rmList.add(info); rmList.add(info);
} }
} }
@ -129,44 +127,16 @@ public class AppAdapter extends RecyclerView.Adapter<AppAdapter.ViewHolder> impl
private void sortApps() { private void sortApps() {
switch (preferences.getInt("list_sort", 0)) { switch (preferences.getInt("list_sort", 0)) {
case 7: case 7:
cmp = Collections.reverseOrder((ApplicationInfo a, ApplicationInfo b) -> { cmp = Collections.reverseOrder((PackageInfo a, PackageInfo b) -> Long.compare(a.lastUpdateTime, b.lastUpdateTime));
try {
return Long.compare(pm.getPackageInfo(a.packageName, 0).lastUpdateTime, pm.getPackageInfo(b.packageName, 0).lastUpdateTime);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return displayNameComparator.compare(a, b);
}
});
break; break;
case 6: case 6:
cmp = (ApplicationInfo a, ApplicationInfo b) -> { cmp = (PackageInfo a, PackageInfo b) -> Long.compare(a.lastUpdateTime, b.lastUpdateTime);
try {
return Long.compare(pm.getPackageInfo(a.packageName, 0).lastUpdateTime, pm.getPackageInfo(b.packageName, 0).lastUpdateTime);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return displayNameComparator.compare(a, b);
}
};
break; break;
case 5: case 5:
cmp = Collections.reverseOrder((ApplicationInfo a, ApplicationInfo b) -> { cmp = Collections.reverseOrder((PackageInfo a, PackageInfo b) -> Long.compare(a.firstInstallTime, b.firstInstallTime));
try {
return Long.compare(pm.getPackageInfo(a.packageName, 0).firstInstallTime, pm.getPackageInfo(b.packageName, 0).firstInstallTime);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return displayNameComparator.compare(a, b);
}
});
break; break;
case 4: case 4:
cmp = (ApplicationInfo a, ApplicationInfo b) -> { cmp = (PackageInfo a, PackageInfo b) -> Long.compare(a.firstInstallTime, b.firstInstallTime);
try {
return Long.compare(pm.getPackageInfo(a.packageName, 0).firstInstallTime, pm.getPackageInfo(b.packageName, 0).firstInstallTime);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return displayNameComparator.compare(a, b);
}
};
break; break;
case 3: case 3:
cmp = Collections.reverseOrder((a, b) -> a.packageName.compareTo(b.packageName)); cmp = Collections.reverseOrder((a, b) -> a.packageName.compareTo(b.packageName));
@ -175,11 +145,11 @@ public class AppAdapter extends RecyclerView.Adapter<AppAdapter.ViewHolder> impl
cmp = (a, b) -> a.packageName.compareTo(b.packageName); cmp = (a, b) -> a.packageName.compareTo(b.packageName);
break; break;
case 1: case 1:
cmp = Collections.reverseOrder(displayNameComparator); cmp = Collections.reverseOrder((PackageInfo a, PackageInfo b) -> displayNameComparator.compare(a.applicationInfo, b.applicationInfo));
break; break;
case 0: case 0:
default: default:
cmp = displayNameComparator; cmp = (PackageInfo a, PackageInfo b) -> displayNameComparator.compare(a.applicationInfo, b.applicationInfo);
break; break;
} }
fullList.sort((a, b) -> { fullList.sort((a, b) -> {
@ -270,8 +240,8 @@ public class AppAdapter extends RecyclerView.Adapter<AppAdapter.ViewHolder> impl
@Override @Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) { public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
ApplicationInfo info = showList.get(position); PackageInfo info = showList.get(position);
holder.appName.setText(getAppLabel(info, pm)); holder.appName.setText(getAppLabel(info.applicationInfo, pm));
try { try {
PackageInfo packageInfo = pm.getPackageInfo(info.packageName, 0); PackageInfo packageInfo = pm.getPackageInfo(info.packageName, 0);
GlideApp.with(holder.appIcon) GlideApp.with(holder.appIcon)
@ -305,10 +275,8 @@ public class AppAdapter extends RecyclerView.Adapter<AppAdapter.ViewHolder> impl
holder.mSwitch.setEnabled(true); holder.mSwitch.setEnabled(true);
} }
holder.mSwitch.setOnCheckedChangeListener((v, isChecked) -> holder.mSwitch.setOnCheckedChangeListener((v, isChecked) ->
onCheckedChange(v, isChecked, info)); onCheckedChange(v, isChecked, info.packageName));
holder.itemView.setOnClickListener(v -> { holder.itemView.setOnClickListener(v -> AppHelper.showMenu(activity, activity.getSupportFragmentManager(), v, info.applicationInfo));
AppHelper.showMenu(activity, activity.getSupportFragmentManager(), v, info);
});
} }
@Override @Override
@ -335,7 +303,7 @@ public class AppAdapter extends RecyclerView.Adapter<AppAdapter.ViewHolder> impl
AsyncTask.THREAD_POOL_EXECUTOR.execute(this::loadApps); AsyncTask.THREAD_POOL_EXECUTOR.execute(this::loadApps);
} }
protected void onCheckedChange(CompoundButton buttonView, boolean isChecked, ApplicationInfo info) { protected void onCheckedChange(CompoundButton buttonView, boolean isChecked, String packageName) {
// override this to implements your functions // override this to implements your functions
} }
@ -370,10 +338,10 @@ public class AppAdapter extends RecyclerView.Adapter<AppAdapter.ViewHolder> impl
if (constraint.toString().isEmpty()) { if (constraint.toString().isEmpty()) {
showList = fullList; showList = fullList;
} else { } else {
ArrayList<ApplicationInfo> filtered = new ArrayList<>(); ArrayList<PackageInfo> filtered = new ArrayList<>();
String filter = constraint.toString().toLowerCase(); String filter = constraint.toString().toLowerCase();
for (ApplicationInfo info : fullList) { for (PackageInfo info : fullList) {
if (lowercaseContains(getAppLabel(info, pm), filter) if (lowercaseContains(getAppLabel(info.applicationInfo, pm), filter)
|| lowercaseContains(info.packageName, filter)) { || lowercaseContains(info.packageName, filter)) {
filtered.add(info); filtered.add(info);
} }
@ -390,13 +358,6 @@ public class AppAdapter extends RecyclerView.Adapter<AppAdapter.ViewHolder> impl
} }
public static String getAppLabel(ApplicationInfo info, PackageManager pm) { public static String getAppLabel(ApplicationInfo info, PackageManager pm) {
try {
if (info.labelRes > 0) {
Resources res = pm.getResourcesForApplication(info);
return res.getString(info.labelRes);
}
} catch (Exception ignored) {
}
return info.loadLabel(pm).toString(); return info.loadLabel(pm).toString();
} }
} }

View File

@ -1,15 +1,14 @@
package io.github.lsposed.manager.adapters; package io.github.lsposed.manager.adapters;
import android.content.pm.ApplicationInfo;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import java.util.List;
import io.github.lsposed.manager.R; import io.github.lsposed.manager.R;
import io.github.lsposed.manager.ui.activity.AppListActivity; import io.github.lsposed.manager.ui.activity.AppListActivity;
import java.util.List;
public class BlackListAdapter extends AppAdapter { public class BlackListAdapter extends AppAdapter {
@ -26,13 +25,13 @@ public class BlackListAdapter extends AppAdapter {
} }
@Override @Override
protected void onCheckedChange(CompoundButton view, boolean isChecked, ApplicationInfo info) { protected void onCheckedChange(CompoundButton view, boolean isChecked, String packageName) {
boolean success = AppHelper.setPackageAppList(info.packageName, isChecked); boolean success = AppHelper.setPackageAppList(packageName, isChecked);
if (success) { if (success) {
if (isChecked) { if (isChecked) {
checkedList.add(info.packageName); checkedList.add(packageName);
} else { } else {
checkedList.remove(info.packageName); checkedList.remove(packageName);
} }
} else { } else {
activity.makeSnackBar(R.string.add_package_failed, Snackbar.LENGTH_SHORT); activity.makeSnackBar(R.string.add_package_failed, Snackbar.LENGTH_SHORT);

View File

@ -1,17 +1,17 @@
package io.github.lsposed.manager.adapters; package io.github.lsposed.manager.adapters;
import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import java.util.ArrayList;
import java.util.List;
import io.github.lsposed.manager.R; import io.github.lsposed.manager.R;
import io.github.lsposed.manager.ui.activity.AppListActivity; import io.github.lsposed.manager.ui.activity.AppListActivity;
import io.github.lsposed.manager.ui.widget.MasterSwitch; import io.github.lsposed.manager.ui.widget.MasterSwitch;
import java.util.ArrayList;
import java.util.List;
public class ScopeAdapter extends AppAdapter { public class ScopeAdapter extends AppAdapter {
protected final String modulePackageName; protected final String modulePackageName;
@ -38,7 +38,7 @@ public class ScopeAdapter extends AppAdapter {
AppHelper.makeSurePath(); AppHelper.makeSurePath();
List<String> scopeList = AppHelper.getScopeList(modulePackageName); List<String> scopeList = AppHelper.getScopeList(modulePackageName);
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
for (ApplicationInfo info : fullList) { for (PackageInfo info : fullList) {
list.add(info.packageName); list.add(info.packageName);
} }
scopeList.retainAll(list); scopeList.retainAll(list);
@ -49,18 +49,18 @@ public class ScopeAdapter extends AppAdapter {
} }
@Override @Override
protected void onCheckedChange(CompoundButton view, boolean isChecked, ApplicationInfo info) { protected void onCheckedChange(CompoundButton view, boolean isChecked, String packageName) {
if (isChecked) { if (isChecked) {
checkedList.add(info.packageName); checkedList.add(packageName);
} else { } else {
checkedList.remove(info.packageName); checkedList.remove(packageName);
} }
if (!AppHelper.saveScopeList(modulePackageName, checkedList)) { if (!AppHelper.saveScopeList(modulePackageName, checkedList)) {
activity.makeSnackBar(R.string.add_package_failed, Snackbar.LENGTH_SHORT); activity.makeSnackBar(R.string.add_package_failed, Snackbar.LENGTH_SHORT);
if (!isChecked) { if (!isChecked) {
checkedList.add(info.packageName); checkedList.add(packageName);
} else { } else {
checkedList.remove(info.packageName); checkedList.remove(packageName);
} }
view.setChecked(!isChecked); view.setChecked(!isChecked);
} }