优化数据库没有数据时排序
This commit is contained in:
@@ -22,20 +22,23 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
public class AppManager {
|
public class AppManager {
|
||||||
private static final String TAG = "AppManager";
|
private static final String TAG = "AppManager";
|
||||||
|
// 步骤常量定义,便于回调和日志统一管理
|
||||||
|
private static final String STEP_FIRST_INIT = "首次初始化应用数据";
|
||||||
|
private static final String STEP_REMOVE_UNINSTALLED = "移除未安装应用";
|
||||||
|
private static final String STEP_ADD_NEW_APPS = "添加新安装应用";
|
||||||
|
private static final String STEP_UPDATE_POSITION = "更新应用位置";
|
||||||
|
private static final int TOTAL_STEPS_NORMAL = 3; // 正常流程总步骤
|
||||||
|
private static final int TOTAL_STEPS_FIRST = 2; // 首次初始化总步骤
|
||||||
|
|
||||||
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
|
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
|
||||||
|
|
||||||
@@ -57,7 +60,13 @@ public class AppManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addProgressCallback(ProgressCallback progressCallback) {
|
public void addProgressCallback(ProgressCallback progressCallback) {
|
||||||
mProgressCallbacks.add(progressCallback);
|
if (progressCallback != null) {
|
||||||
|
mProgressCallbacks.add(progressCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeProgressCallback(ProgressCallback progressCallback) {
|
||||||
|
mProgressCallbacks.remove(progressCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final List<String> DEFAULT_APP_PACKAGES = new ArrayList<String>() {{
|
public static final List<String> DEFAULT_APP_PACKAGES = new ArrayList<String>() {{
|
||||||
@@ -88,73 +97,124 @@ public class AppManager {
|
|||||||
executeAppListProcessing();
|
executeAppListProcessing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 通知进度回调
|
||||||
|
private void notifyProgress(String step, int current, int total) {
|
||||||
|
mProgressCallbacks.forEach(callback -> callback.onProgress(step, current, total));
|
||||||
|
}
|
||||||
|
|
||||||
// 异步执行方法
|
// 通知完成回调
|
||||||
|
private void notifyCompleted(boolean success, String message) {
|
||||||
|
mProgressCallbacks.forEach(callback -> callback.onCompleted(success, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 异步执行应用列表处理流程
|
||||||
public void executeAppListProcessing() {
|
public void executeAppListProcessing() {
|
||||||
CompletableFuture
|
CompletableFuture
|
||||||
.supplyAsync(this::getAllDesktopSortApps, ASYNC_EXECUTOR)
|
.supplyAsync(this::getAllDesktopSortApps, ASYNC_EXECUTOR)
|
||||||
.thenComposeAsync(desktopSortApps -> {
|
.thenComposeAsync(desktopApps -> {
|
||||||
// 判断获取的应用列表是否为空
|
// 根据应用列表是否为空,选择不同处理流程
|
||||||
if (desktopSortApps == null || desktopSortApps.isEmpty()) {
|
if (desktopApps.isEmpty()) {
|
||||||
Log.i("AppListProcessor", "检测到桌面应用列表为空,直接插入新应用数据");
|
// 首次初始化流程:首次数据加载 -> 更新位置
|
||||||
return processNewApps()
|
return processFirstTimeApps()
|
||||||
.thenComposeAsync(unused -> updatePosition(), ASYNC_EXECUTOR);
|
.thenComposeAsync(unused -> {
|
||||||
|
notifyProgress(STEP_UPDATE_POSITION, 2, TOTAL_STEPS_FIRST);
|
||||||
|
return updatePosition();
|
||||||
|
}, ASYNC_EXECUTOR);
|
||||||
} else {
|
} else {
|
||||||
return processUninstalledApps(desktopSortApps)
|
// 正常流程:移除未安装 -> 添加新应用 -> 更新位置
|
||||||
.thenComposeAsync(unused -> processNewApps(), ASYNC_EXECUTOR)
|
return processUninstalledApps(desktopApps)
|
||||||
.thenComposeAsync(unused -> updatePosition(), ASYNC_EXECUTOR);
|
.thenComposeAsync(unused -> {
|
||||||
|
notifyProgress(STEP_ADD_NEW_APPS, 2, TOTAL_STEPS_NORMAL);
|
||||||
|
return processNewApps();
|
||||||
|
}, ASYNC_EXECUTOR)
|
||||||
|
.thenComposeAsync(unused -> {
|
||||||
|
notifyProgress(STEP_UPDATE_POSITION, 3, TOTAL_STEPS_NORMAL);
|
||||||
|
return updatePosition();
|
||||||
|
}, ASYNC_EXECUTOR);
|
||||||
}
|
}
|
||||||
}, ASYNC_EXECUTOR)
|
}, ASYNC_EXECUTOR)
|
||||||
.thenComposeAsync(unused -> processNewApps(), ASYNC_EXECUTOR)
|
.thenRun(() -> notifyCompleted(true, "应用列表处理完成"))
|
||||||
.exceptionally(throwable -> {
|
.exceptionally(throwable -> {
|
||||||
// 统一异常处理
|
Log.e(TAG, "异步处理失败", throwable);
|
||||||
Log.e("AppListProcessor", "异步处理失败", throwable);
|
notifyCompleted(false, "处理失败: " + throwable.getMessage());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 第一步:获取所有桌面应用(增加空值安全处理)
|
// 第一步:获取所有桌面应用(空值安全处理)
|
||||||
private List<DesktopSortApp> getAllDesktopSortApps() {
|
private List<DesktopSortApp> getAllDesktopSortApps() {
|
||||||
try {
|
try {
|
||||||
List<DesktopSortApp> result = mAppRepository.getAllApp();
|
List<DesktopSortApp> result = mAppRepository.getAllApp();
|
||||||
return result != null ? result : Collections.emptyList();
|
return result != null ? result : Collections.emptyList();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e("AppListProcessor", "获取桌面应用列表失败", e);
|
Log.e(TAG, "获取桌面应用列表失败", e);
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<List<DesktopSortApp>> getAllDesktopSortAppsSafe() {
|
// 首次初始化应用数据(针对首次获取为空的场景)
|
||||||
try {
|
private CompletableFuture<Void> processFirstTimeApps() {
|
||||||
return Optional.ofNullable(mAppRepository.getAllApp())
|
return CompletableFuture.runAsync(() -> {
|
||||||
.filter(list -> !list.isEmpty());
|
notifyProgress(STEP_FIRST_INIT, 1, TOTAL_STEPS_FIRST);
|
||||||
} catch (Exception e) {
|
Log.i(TAG, "进入首次应用数据初始化流程");
|
||||||
Log.e("AppListProcessor", "获取应用列表失败", e);
|
|
||||||
return Optional.empty();
|
try {
|
||||||
}
|
// 获取所有可启动应用
|
||||||
|
List<ResolveInfo> allLauncherApps = ApkUtils.getAllLauncherResolveInfo(mContext);
|
||||||
|
if (allLauncherApps.isEmpty()) {
|
||||||
|
Log.w(TAG, "未获取到任何可启动应用,无法完成首次初始化");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DesktopSortApp> allFirstApps = allLauncherApps.stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.map(this::resolveInfoToDesktopApp)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.sorted((o1, o2) -> Boolean.compare(ApkUtils.isSystemApp(mContext, o1.getPackageName()), ApkUtils.isSystemApp(mContext, o2.getPackageName())))
|
||||||
|
.sorted(getAppComparator())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
IntStream.range(0, allFirstApps.size())
|
||||||
|
.forEach(index -> allFirstApps.get(index).setPosition(index));
|
||||||
|
|
||||||
|
// 批量插入首次数据
|
||||||
|
allFirstApps.forEach(app -> {
|
||||||
|
try {
|
||||||
|
mAppRepository.insert(app);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "首次初始化插入应用失败: " + app.getPackageName(), e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Log.i(TAG, "首次初始化完成,插入默认应用: " + allFirstApps.size() + " 个");
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "首次应用数据初始化失败", e);
|
||||||
|
throw new RuntimeException("首次初始化失败", e); // 抛出异常触发回调
|
||||||
|
}
|
||||||
|
}, ASYNC_EXECUTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 第二步:处理未安装的应用(删除操作) - 增加空值检查
|
// 处理未安装的应用(删除操作)
|
||||||
private CompletableFuture<Void> processUninstalledApps(List<DesktopSortApp> desktopSortApps) {
|
private CompletableFuture<Void> processUninstalledApps(List<DesktopSortApp> desktopSortApps) {
|
||||||
return CompletableFuture.runAsync(() -> {
|
return CompletableFuture.runAsync(() -> {
|
||||||
if (desktopSortApps == null || desktopSortApps.isEmpty()) {
|
notifyProgress(STEP_REMOVE_UNINSTALLED, 1, TOTAL_STEPS_NORMAL);
|
||||||
Log.w("AppListProcessor", "桌面应用列表为空,跳过删除处理");
|
if (desktopSortApps.isEmpty()) {
|
||||||
|
Log.w(TAG, "桌面应用列表为空,跳过删除处理");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Integer> ids = desktopSortApps.stream()
|
List<Integer> ids = desktopSortApps.stream()
|
||||||
.filter(desktopSortApp -> desktopSortApp != null &&
|
.filter(Objects::nonNull)
|
||||||
!ApkUtils.isInstalled(mContext, desktopSortApp.getPackageName()))
|
.filter(app -> !ApkUtils.isInstalled(mContext, app.getPackageName()))
|
||||||
.map(desktopSortApp -> {
|
.map(app -> {
|
||||||
try {
|
try {
|
||||||
return mAppRepository.getIdByPackageAndClass(
|
return mAppRepository.getIdByPackageAndClass(app.getPackageName(), app.getClassName());
|
||||||
desktopSortApp.getPackageName(), desktopSortApp.getClassName());
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e("AppListProcessor", "获取应用ID失败: " + desktopSortApp.getPackageName(), e);
|
Log.e(TAG, "获取应用ID失败: " + app.getPackageName(), e);
|
||||||
return -1; // 返回无效ID,后续过滤掉
|
return -1;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(id -> id > 0) // 过滤掉无效ID
|
.filter(id -> id > 0)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
if (!ids.isEmpty()) {
|
if (!ids.isEmpty()) {
|
||||||
@@ -162,232 +222,160 @@ public class AppManager {
|
|||||||
try {
|
try {
|
||||||
mAppRepository.deleteById(id);
|
mAppRepository.deleteById(id);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e("AppListProcessor", "删除应用失败, ID: " + id, e);
|
Log.e(TAG, "删除应用失败, ID: " + id, e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Log.i("AppListProcessor", "成功删除 " + ids.size() + " 个未安装应用");
|
Log.i(TAG, "成功删除 " + ids.size() + " 个未安装应用");
|
||||||
}
|
}
|
||||||
}, ASYNC_EXECUTOR);
|
}, ASYNC_EXECUTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 第三步:处理新应用(插入操作) - 增加空值和异常处理
|
// 处理新安装的应用(插入操作)- 非首次场景
|
||||||
private CompletableFuture<Void> processNewApps() {
|
private CompletableFuture<Void> processNewApps() {
|
||||||
return CompletableFuture.runAsync(() -> {
|
return CompletableFuture.runAsync(() -> {
|
||||||
try {
|
try {
|
||||||
List<ResolveInfo> resolveInfos = ApkUtils.getAllLauncherResolveInfo(mContext);
|
List<ResolveInfo> resolveInfos = ApkUtils.getAllLauncherResolveInfo(mContext);
|
||||||
if (resolveInfos.isEmpty()) {
|
if (resolveInfos.isEmpty()) {
|
||||||
Log.w("AppListProcessor", "未获取到启动器应用列表");
|
Log.w(TAG, "未获取到启动器应用列表,跳过新应用处理");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DesktopSortApp> appList = resolveInfos.stream()
|
List<DesktopSortApp> newApps = resolveInfos.stream()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.map(resolveInfo -> {
|
.map(this::resolveInfoToDesktopApp)
|
||||||
try {
|
|
||||||
String packageName = resolveInfo.activityInfo.packageName;
|
|
||||||
String className = resolveInfo.activityInfo.name;
|
|
||||||
ComponentName componentName = new ComponentName(packageName, className);
|
|
||||||
return new DesktopSortApp(mContext, componentName);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("AppListProcessor", "创建DesktopSortApp失败", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.sorted(new Comparator<DesktopSortApp>() {
|
.filter(app -> ApkUtils.isInstalled(mContext, app.getPackageName()))
|
||||||
@Override
|
.filter(app -> !isAppExists(app)) // 过滤已存在的应用
|
||||||
public int compare(DesktopSortApp o1, DesktopSortApp o2) {
|
.sorted(getAppComparator())
|
||||||
return Collator.getInstance(Locale.CHINESE).compare(o1.getLabel(), o2.getLabel());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
List<DesktopSortApp> filterApp = appList.stream()
|
if (!newApps.isEmpty()) {
|
||||||
.filter(desktopSortApp -> ApkUtils.isInstalled(mContext, desktopSortApp.getPackageName()))
|
newApps.forEach(app -> app.setPosition(mAppRepository.getTotalCount()));
|
||||||
.filter(desktopSortApp -> {
|
newApps.forEach(app -> {
|
||||||
try {
|
|
||||||
return mAppRepository.checkAppInfoExists(
|
|
||||||
desktopSortApp.getPackageName(), desktopSortApp.getClassName()) <= 0;
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("AppListProcessor", "检查应用存在性失败", e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
if (!filterApp.isEmpty()) {
|
|
||||||
filterApp.forEach(desktopSortApp -> {
|
|
||||||
desktopSortApp.setPosition(mAppRepository.getTotalCount());
|
|
||||||
try {
|
try {
|
||||||
mAppRepository.insert(desktopSortApp);
|
mAppRepository.insert(app);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e("AppListProcessor", "插入应用失败: " + desktopSortApp.getPackageName(), e);
|
Log.e(TAG, "插入新应用失败: " + app.getPackageName(), e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Log.i("AppListProcessor", "成功插入 " + filterApp.size() + " 个新应用");
|
Log.i(TAG, "成功插入 " + newApps.size() + " 个新应用");
|
||||||
} else {
|
} else {
|
||||||
Log.i("AppListProcessor", "没有需要插入的新应用");
|
Log.i(TAG, "没有需要插入的新应用");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e("AppListProcessor", "处理新应用时发生异常", e);
|
Log.e(TAG, "处理新应用时发生异常", e);
|
||||||
|
throw new RuntimeException("新应用处理失败", e);
|
||||||
}
|
}
|
||||||
}, ASYNC_EXECUTOR);
|
}, ASYNC_EXECUTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 第四步:更新应用位置(您提供的方法优化)
|
// 更新应用位置
|
||||||
private CompletableFuture<Void> updatePosition() {
|
private CompletableFuture<Void> updatePosition() {
|
||||||
return CompletableFuture.runAsync(() -> {
|
return CompletableFuture.runAsync(() -> {
|
||||||
try {
|
try {
|
||||||
List<DesktopSortApp> desktopSortApps = getAllDesktopSortApps();
|
List<DesktopSortApp> desktopSortApps = getAllDesktopSortApps();
|
||||||
if (desktopSortApps == null || desktopSortApps.isEmpty()) {
|
if (desktopSortApps.isEmpty()) {
|
||||||
Log.w("AppListProcessor", "无应用数据,跳过位置更新");
|
Log.w(TAG, "无应用数据,跳过位置更新");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用Lambda简化代码
|
|
||||||
List<DesktopSortApp> sortedApps = desktopSortApps.stream()
|
List<DesktopSortApp> sortedApps = desktopSortApps.stream()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.sorted((o1, o2) -> Integer.compare(o1.getPosition(), o2.getPosition()))
|
.sorted(Comparator.comparingInt(DesktopSortApp::getPosition))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
// 批量更新位置
|
|
||||||
IntStream.range(0, sortedApps.size())
|
IntStream.range(0, sortedApps.size())
|
||||||
.forEach(index -> {
|
.forEach(index -> {
|
||||||
DesktopSortApp desktopSortApp = sortedApps.get(index);
|
DesktopSortApp app = sortedApps.get(index);
|
||||||
desktopSortApp.setPosition(index);
|
app.setPosition(index);
|
||||||
try {
|
try {
|
||||||
mAppRepository.update(desktopSortApp);
|
mAppRepository.update(app);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e("AppListProcessor", "更新应用位置失败: " + desktopSortApp.getPackageName(), e);
|
Log.e(TAG, "更新应用位置失败: " + app.getPackageName(), e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Log.i("AppListProcessor", "成功更新 " + sortedApps.size() + " 个应用的位置");
|
Log.i(TAG, "成功更新 " + sortedApps.size() + " 个应用的位置");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e("AppListProcessor", "更新应用位置时发生异常", e);
|
Log.e(TAG, "更新应用位置时发生异常", e);
|
||||||
|
throw new RuntimeException("位置更新失败", e);
|
||||||
}
|
}
|
||||||
}, ASYNC_EXECUTOR);
|
}, ASYNC_EXECUTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateApp(String packageName) {
|
// 工具方法:ResolveInfo转换为DesktopSortApp
|
||||||
List<ResolveInfo> resolveInfos = ApkUtils.getResolveInfoByPackageName(mContext, packageName);
|
private DesktopSortApp resolveInfoToDesktopApp(ResolveInfo resolveInfo) {
|
||||||
if (!resolveInfos.isEmpty()) {
|
ComponentName component = new ComponentName(
|
||||||
resolveInfos.stream().map(new Function<ResolveInfo, DesktopSortApp>() {
|
resolveInfo.activityInfo.packageName,
|
||||||
@Override
|
resolveInfo.activityInfo.name
|
||||||
public DesktopSortApp apply(ResolveInfo resolveInfo) {
|
);
|
||||||
String packageName = resolveInfo.activityInfo.packageName;
|
return new DesktopSortApp(mContext, component);
|
||||||
String className = resolveInfo.activityInfo.name;
|
}
|
||||||
ComponentName componentName = new ComponentName(packageName, className);
|
|
||||||
return new DesktopSortApp(mContext, componentName);
|
// 工具方法:检查应用是否已存在
|
||||||
}
|
private boolean isAppExists(DesktopSortApp app) {
|
||||||
}).filter(new Predicate<DesktopSortApp>() {
|
try {
|
||||||
@Override
|
return mAppRepository.checkAppInfoExists(app.getPackageName(), app.getClassName()) > 0;
|
||||||
public boolean test(DesktopSortApp desktopSortApp) {
|
} catch (Exception e) {
|
||||||
return mAppRepository.checkAppInfoExists(desktopSortApp.getPackageName(), desktopSortApp.getClassName()) <= 0;
|
Log.e(TAG, "检查应用存在性失败: " + app.getPackageName(), e);
|
||||||
}
|
return false;
|
||||||
}).forEach(new Consumer<DesktopSortApp>() {
|
|
||||||
@Override
|
|
||||||
public void accept(DesktopSortApp desktopSortApp) {
|
|
||||||
desktopSortApp.setPosition(mAppRepository.getTotalCount());
|
|
||||||
mAppRepository.insert(desktopSortApp);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getAllApp() {
|
// 工具方法:获取应用排序器(统一排序逻辑)
|
||||||
List<DesktopSortApp> desktopSortApps = mAppRepository.getAllApp();
|
private Comparator<DesktopSortApp> getAppComparator() {
|
||||||
List<Integer> ids = desktopSortApps.stream().filter(new Predicate<DesktopSortApp>() {
|
return Comparator.comparing(DesktopSortApp::getLabel, Collator.getInstance(Locale.CHINESE));
|
||||||
@Override
|
}
|
||||||
public boolean test(DesktopSortApp desktopSortApp) {
|
|
||||||
return !ApkUtils.isInstalled(mContext, desktopSortApp.getPackageName());
|
|
||||||
}
|
|
||||||
}).map(new java.util.function.Function<DesktopSortApp, Integer>() {
|
|
||||||
@Override
|
|
||||||
public Integer apply(DesktopSortApp desktopSortApp) {
|
|
||||||
return mAppRepository.getIdByPackageAndClass(desktopSortApp.getPackageName(), desktopSortApp.getClassName());
|
|
||||||
}
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
ids.stream().forEach(new Consumer<Integer>() {
|
|
||||||
@Override
|
|
||||||
public void accept(Integer integer) {
|
|
||||||
mAppRepository.deleteById(integer);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
List<ResolveInfo> resolveInfos = ApkUtils.getAllLauncherResolveInfo(mContext);
|
public void updateApp(String packageName) {
|
||||||
List<DesktopSortApp> appList = resolveInfos.stream().map(new Function<ResolveInfo, ComponentName>() {
|
List<ResolveInfo> resolveInfos = ApkUtils.getResolveInfoByPackageName(mContext, packageName);
|
||||||
@Override
|
if (resolveInfos.isEmpty()) return;
|
||||||
public ComponentName apply(ResolveInfo resolveInfo) {
|
|
||||||
String packageName = resolveInfo.activityInfo.packageName;
|
|
||||||
String className = resolveInfo.activityInfo.name;
|
|
||||||
ComponentName componentName = new ComponentName(packageName, className);
|
|
||||||
return componentName;
|
|
||||||
}
|
|
||||||
}).map(new Function<ComponentName, DesktopSortApp>() {
|
|
||||||
@Override
|
|
||||||
public DesktopSortApp apply(ComponentName componentName) {
|
|
||||||
DesktopSortApp desktopSortApp = new DesktopSortApp(mContext, componentName);
|
|
||||||
return desktopSortApp;
|
|
||||||
}
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
List<DesktopSortApp> filterApp = appList.stream().filter(new Predicate<DesktopSortApp>() {
|
|
||||||
@Override
|
|
||||||
public boolean test(DesktopSortApp desktopSortApp) {
|
|
||||||
return ApkUtils.isInstalled(mContext, desktopSortApp.getPackageName());
|
|
||||||
}
|
|
||||||
}).filter(new Predicate<DesktopSortApp>() {
|
|
||||||
@Override
|
|
||||||
public boolean test(DesktopSortApp desktopSortApp) {
|
|
||||||
return mAppRepository.checkAppInfoExists(desktopSortApp.getPackageName(), desktopSortApp.getClassName()) > 0;
|
|
||||||
}
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
|
|
||||||
filterApp.stream().forEach(new Consumer<DesktopSortApp>() {
|
resolveInfos.stream()
|
||||||
@Override
|
.map(this::resolveInfoToDesktopApp)
|
||||||
public void accept(DesktopSortApp desktopSortApp) {
|
.filter(Objects::nonNull)
|
||||||
mAppRepository.insert(desktopSortApp);
|
.filter(app -> !isAppExists(app))
|
||||||
|
.forEach(app -> {
|
||||||
|
app.setPosition(mAppRepository.getTotalCount());
|
||||||
|
try {
|
||||||
|
mAppRepository.insert(app);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "更新应用插入失败: " + app.getPackageName(), e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重构getAllApp方法,复用现有处理逻辑
|
||||||
|
public void refreshAllApps() {
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
List<DesktopSortApp> allApps = getAllDesktopSortApps();
|
||||||
|
if (allApps.isEmpty()) {
|
||||||
|
processFirstTimeApps().join();
|
||||||
|
} else {
|
||||||
|
processUninstalledApps(allApps).join();
|
||||||
|
processNewApps().join();
|
||||||
}
|
}
|
||||||
});
|
updatePosition().join();
|
||||||
|
}, ASYNC_EXECUTOR);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDefaultAppList() {
|
public String getDefaultAppList() {
|
||||||
PackageManager packageManager = mContext.getPackageManager();
|
PackageManager pm = mContext.getPackageManager();
|
||||||
List<ResolveInfo> resolveInfos = ApkUtils.getAllLauncherResolveInfo(mContext);
|
List<ResolveInfo> resolveInfos = ApkUtils.getAllLauncherResolveInfo(mContext);
|
||||||
List<ResolveInfo> filter = resolveInfos.stream().filter(new Predicate<ResolveInfo>() {
|
|
||||||
@Override
|
|
||||||
public boolean test(ResolveInfo resolveInfo) {
|
|
||||||
return DEFAULT_APP_PACKAGES.contains(resolveInfo.activityInfo.packageName);
|
|
||||||
}
|
|
||||||
}).sorted(new Comparator<ResolveInfo>() {
|
|
||||||
@Override
|
|
||||||
public int compare(ResolveInfo o1, ResolveInfo o2) {
|
|
||||||
return Collator.getInstance(Locale.CHINESE).compare(o1.activityInfo.loadLabel(packageManager), o2.activityInfo.loadLabel(packageManager));
|
|
||||||
}
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
|
|
||||||
List<DesktopSortApp> desktopSortApps = filter.stream().map(new Function<ResolveInfo, DesktopSortApp>() {
|
List<DesktopSortApp> defaultApps = resolveInfos.stream()
|
||||||
@Override
|
.filter(ri -> DEFAULT_APP_PACKAGES.contains(ri.activityInfo.packageName))
|
||||||
public DesktopSortApp apply(ResolveInfo resolveInfo) {
|
.sorted((o1, o2) -> Collator.getInstance(Locale.CHINESE)
|
||||||
ComponentName componentName = new ComponentName(resolveInfo.activityInfo.packageName,
|
.compare(o1.activityInfo.loadLabel(pm), o2.activityInfo.loadLabel(pm)))
|
||||||
resolveInfo.activityInfo.name);
|
.map(ri -> new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name))
|
||||||
return new DesktopSortApp(mContext, componentName);
|
.map(component -> new DesktopSortApp(mContext, component))
|
||||||
}
|
.sorted((a, b) -> Boolean.compare(
|
||||||
}).sorted(new Comparator<DesktopSortApp>() {
|
ApkUtils.isSystemApp(mContext, b.getPackageName()),
|
||||||
@Override
|
ApkUtils.isSystemApp(mContext, a.getPackageName())))
|
||||||
public int compare(DesktopSortApp o1, DesktopSortApp o2) {
|
.collect(Collectors.toCollection(LinkedList::new));
|
||||||
return Boolean.compare(ApkUtils.isSystemApp(mContext, o2.getPackageName()), ApkUtils.isSystemApp(mContext, o1.getPackageName()));
|
|
||||||
}
|
|
||||||
}).collect(Collectors.toCollection(LinkedList::new));
|
|
||||||
|
|
||||||
for (int i = 0; i < desktopSortApps.size(); i++) {
|
IntStream.range(0, defaultApps.size())
|
||||||
DesktopSortApp desktopSortApp = desktopSortApps.get(i);
|
.forEach(i -> defaultApps.get(i).setPosition(i));
|
||||||
desktopSortApp.setPosition(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GsonUtils.toJSONString(desktopSortApps);
|
return GsonUtils.toJSONString(defaultApps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user