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