Launcher3 如何获取系统上的所有应用程序?

Launcher3 如何获取系统上的所有应用程序?

通过 LoaderTask

在 Launcher#onCreate 中,运行 LoaderTask。

Java 复制代码
protected void onCreate(Bundle savedInstanceState) {
    mModel.addCallbacksAndLoad(this)
}

在 LauncherModel#addCallbacksAndLoad 中,使用 HandlerThread launcher-loader 运行 LoaderTask。

Kotlin 复制代码
fun addCallbacksAndLoad(callbacks: BgDataModel.Callbacks): Boolean {
    synchronized(mLock) {
        addCallbacks(callbacks)
        return startLoader(arrayOf(callbacks))
    }
}

private fun startLoader(newCallbacks: Array<BgDataModel.Callbacks>): Boolean {
    mLoaderTask = LoaderTask(mBgAllAppsList)
    MODEL_EXECUTOR.post(mLoaderTask)
}

在 model.LoaderTask#run 中加载所有应用程序。

Java 复制代码
public class LoaderTask implements Runnable {
    public void run() {
        Trace.beginSection("LoadAllApps");
        List<LauncherActivityInfo> allActivityList;
        try {
            allActivityList = loadAllApps();
        } finally {
            Trace.endSection();
        }
    }

    private List<LauncherActivityInfo> loadAllApps() {
        final List<UserHandle> profiles = mUserCache.getUserProfiles();
        List<LauncherActivityInfo> allActivityList = new ArrayList<>();
        for (UserHandle user : profiles) {
            final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
            allActivityList.addAll(apps);
        }
        return allActivityList;
    }
}

产生以下两个问题。

问题一:UserHandle 有哪些?

全部来自 UserCache。

Java 复制代码
UserCache mUserCache = UserCache.INSTANCE.get(mApp.getContext());
final List<UserHandle> profiles = mUserCache.getUserProfiles();

pm.UserCache#getUserProfiles

Java 复制代码
public List<UserHandle> getUserProfiles() {
    return List.copyOf(mUserToSerialMap.keySet());
}

mUserToSerialMap 里的 Key 来自哪里?

Java 复制代码
private void updateCache() {
    mUserToSerialMap = ApiWrapper.INSTANCE.get(mContext).queryAllUsers();
}

util.ApiWrapper#queryAllUsers

Java 复制代码
public Map<UserHandle, UserIconInfo> queryAllUsers() {
    UserManager um = mContext.getSystemService(UserManager.class);
    Map<UserHandle, UserIconInfo> users = new ArrayMap<>();
    List<UserHandle> usersActual = um.getUserProfiles();
    if (usersActual != null) {
        for (UserHandle user : usersActual) {
            // UserIconInfo info
            users.put(user, info);
        }
    }
    return users;
}

即通过 UserManager 获取 UserHandle。

问题二:mLauncherApps 如何获取?

Java 复制代码
LauncherApps mLauncherApps = mApp.getContext().getSystemService(LauncherApps.class);

Context#getSystemService 即通过跨进程调用。

总结

  • android.os.UserManager#getUserProfiles
  • android.content.pm.LauncherApps#getActivityList(String packageName, UserHandle user)
  • android.content.pm.LauncherActivityInfo
相关推荐
tangweiguo030519879 分钟前
ProcessLifecycleOwner 完全指南:优雅监听应用前后台状态
android·kotlin
介一安全1 小时前
【Frida Android】基础篇15(完):Frida-Trace 基础应用——JNI 函数 Hook
android·网络安全·ida·逆向·frida
吞掉星星的鲸鱼1 小时前
android studio创建使用开发打包教程
android·ide·android studio
陈老师还在写代码1 小时前
android studio 签名打包教程
android·ide·android studio
csj501 小时前
android studio设置
android
hifhf1 小时前
Android Studio gradle下载失败报错
android·ide·android studio
陈老师还在写代码1 小时前
android studio,java 语言。新建了项目,在哪儿设置 app 的名字和 logo。
android·java·android studio
2501_916007473 小时前
Fastlane 结合 开心上架(Appuploader)命令行实现跨平台上传发布 iOS App 的完整方案
android·ios·小程序·https·uni-app·iphone·webview
listhi5205 小时前
Vue.js 3的组合式API
android·vue.js·flutter
用户69371750013846 小时前
🚀 Jetpack MVI 实战全解析:一次彻底搞懂 MVI 架构,让状态管理像点奶茶一样丝滑!
android·android jetpack