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
相关推荐
似霰8 小时前
传统 Hal 开发笔记6----App 访问硬件服务
android·framework·hal
爱装代码的小瓶子8 小时前
【c++知识铺子】封装map和set(详细版)
android·java·c++
私人珍藏库8 小时前
AutoGLM无需豆包手机,让AI自动帮你点外卖-刷视频
android·ai·智能手机·工具·软件·辅助·autoglm
孤舟簔笠翁9 小时前
【Android驱动14】Android系统Crash工具使用方法和分析
android
帅得不敢出门10 小时前
MTK Android11 APP调用OTA升级
android·java·开发语言·framework
2501_9159090610 小时前
苹果应用加密方案的一种方法,在没有源码的前提下,如何处理 IPA 的安全问题
android·安全·ios·小程序·uni-app·iphone·webview
用户20187928316710 小时前
Android App 换肤原理:用 "装修小房子" 故事浅谈
android
百锦再10 小时前
与AI沟通的正确方式——AI提示词:原理、策略与精通之道
android·java·开发语言·人工智能·python·ui·uni-app
2501_9159090610 小时前
iOS 项目中常被忽略的 Bundle ID 管理问题
android·ios·小程序·https·uni-app·iphone·webview