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
相关推荐
_李小白30 分钟前
【android opencv学习笔记】Day 17: 目标追踪(MeanShift)
android·opencv·学习
用户86022504674721 小时前
AI 分析头部APP系统优化框架
android
用户86022504674721 小时前
AI分析头部APP优化框架
android
2501_916007474 小时前
iOS开发中抓取HTTPS请求的完整解决方法与步骤详解
android·网络协议·ios·小程序·https·uni-app·iphone
lvronglee7 小时前
【数字图传第四步】Android App查看图传视频
android·音视频
90后的晨仔7 小时前
Android 程序入口与核心组件详解
android
90后的晨仔7 小时前
Kotlin 简介与开发环境搭建
android
BU摆烂会噶7 小时前
【LangGraph】House_Agent 实战(四):预定流程 —— 中断与人工干预
android·人工智能·python·langchain
AI玫瑰助手7 小时前
Python运算符:比较运算符(等于不等等于大于小于)与返回值
android·开发语言·python
new_dev8 小时前
Python实现Android自动化打包工具:加固、签名、多渠道一键完成
android·python·自动化