image.png
目录
Android之zygote源码剖析(一)
Android之zygote源码剖析(二)
Android之zygote源码剖析(三)
Android之SystemServer介绍(一)
Android之SystemServer介绍(二)
Android之Launcher介绍(一)
Android之Launcher介绍(二)
Launcher启动
上文讲到Launcher的Activity被启动。
接下来就执行Activity的生命周期。
代码Launcher.java中:
protected void onCreate(Bundle savedInstanceState) {
……
super.onCreate(savedInstanceState);
// 调用LauncherAppState实例
LauncherAppState app = LauncherAppState.getInstance(this);
mDeviceProfile = app.getInvariantDeviceProfile().getDeviceProfile(this);
if (isInMultiWindowModeCompat()) {
Display display = getWindowManager().getDefaultDisplay();
Point mwSize = new Point();
display.getSize(mwSize);
mDeviceProfile = mDeviceProfile.getMultiWindowProfile(this, mwSize);
}
mSharedPrefs = Utilities.getPrefs(this);
mIsSafeModeEnabled = getPackageManager().isSafeMode();
// 将Launcher传入LauncherAppState实例
mModel = app.setLauncher(this);
mModelWriter = mModel.getWriter(mDeviceProfile.isVerticalBarLayout());
mIconCache = app.getIconCache();
mAccessibilityDelegate = new LauncherAccessibilityDelegate(this);
……
}
进入LauncherAppState.java
中看一下。
getInstance函数和LauncherAppState的构造函数:
public static LauncherAppState getInstance(final Context context) {
if (INSTANCE == null) {
if (Looper.myLooper() == Looper.getMainLooper()) {
// 创建实例
INSTANCE = new LauncherAppState(context.getApplicationContext());
} else {
try {
return new MainThreadExecutor().submit(new Callable() {
@Override
public LauncherAppState call() throws Exception {
return LauncherAppState.getInstance(context);
}
}).get();
} catch (InterruptedException|ExecutionException e) {
throw new RuntimeException(e);
}
}
}
return INSTANCE;
}
private LauncherAppState(Context context) {
……
mInvariantDeviceProfile = new InvariantDeviceProfile(mContext);
mIconCache = new IconCache(mContext, mInvariantDeviceProfile);
mWidgetCache = new WidgetPreviewLoader(mContext, mIconCache);
// 创建LauncherModel对象
mModel = new LauncherModel(this, mIconCache,
Utilities.getOverrideObject(AppFilter.class, mContext, R.string.app_filter_class));
LauncherAppsCompat.getInstance(mContext).addOnAppsChangedCallback(mModel);
……
}
setLauncher函数:
LauncherModel setLauncher(Launcher launcher) {
getLocalProvider(mContext).setLauncherProviderChangeListener(launcher);
mModel.initialize(launcher);
return mModel;
}
setLauncherhan函数中调用了LauncherModel对象的initialize函数,传入的变量就是Launcer对象。
进入LauncherModel看下:
public void initialize(Callbacks callbacks) {
synchronized (mLock) {
Preconditions.assertUIThread();
// Remove any queued UI runnables
mHandler.cancelAll();
mCallbacks = new WeakReference<>(callbacks);
}
}
因为Launcer类是继承了Callbacks类的,所以这里将Launcer封装成了一个弱引用对象。
继续看Launcher的onCreate函数:
protected void onCreate(Bundle savedInstanceState) {
……
super.onCreate(savedInstanceState);
// 将Launcher传入LauncherAppState实例
mModel = app.setLauncher(this);
mModelWriter = mModel.getWriter(mDeviceProfile.isVerticalBarLayout());
……
if (!mModel.startLoader(currentScreen)) {
mDragLayer.setAlpha(0);
} else {
mWorkspace.setCurrentPage(currentScreen);
setWorkspaceLoading(true);
}
}
会获取LauncherModel后,执行startLoader函数, 不过之前先看一段代码:
@Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
static {
sWorkerThread.start();
}
@Thunk static final Handler sWorker = new Handler(sWorkerThread.getLooper());
这段代码就是创建一个具有消息循环的HandlerThread,主要用来处理消息。
startLoader函数:
public boolean startLoader(int synchronousBindPage) {
InstallShortcutReceiver.enableInstallQueue();
synchronized (mLock) {
if (mCallbacks != null && mCallbacks.get() != null) {
final Callbacks oldCallbacks = mCallbacks.get();
runOnMainThread(new Runnable() {
public void run() {
oldCallbacks.clearPendingBinds();
}
});
stopLoaderLocked();
// 执行LoaderTask函数
mLoaderTask = new LoaderTask(mApp.getContext(), synchronousBindPage);
if (synchronousBindPage != PagedView.INVALID_RESTORE_PAGE
&& mModelLoaded && !mIsLoaderTaskRunning) {
mLoaderTask.runBindSynchronousPage(synchronousBindPage);
return true;
} else {
sWorkerThread.setPriority(Thread.NORM_PRIORITY);
// 将mLoaderTask传入到消息线程中处理
sWorker.post(mLoaderTask);
}
}
}
return false;
}
当消息被执行时候会调用LoaderTask类的run函数:
private class LoaderTask implements Runnable {
……
public void run() {
synchronized (mLock) {
if (mStopped) {
return;
}
mIsLoaderTaskRunning = true;
}
try {
if (DEBUG_LOADERS) Log.d(TAG, "step 1.1: loading workspace");
// Set to false in bindWorkspace()
mIsLoadingAndBindingWorkspace = true;
// 加载桌面
loadWorkspace();
verifyNotStopped();
if (DEBUG_LOADERS) Log.d(TAG, "step 1.2: bind workspace workspace");
// 绑定桌面
bindWorkspace(mPageToBindFirst);
if (DEBUG_LOADERS) Log.d(TAG, "step 1 completed, wait for idle");
waitForIdle();
verifyNotStopped();
if (DEBUG_LOADERS) Log.d(TAG, "step 2.1: loading all apps");
// 加载所有的app
loadAllApps();
verifyNotStopped();
if (DEBUG_LOADERS) Log.d(TAG, "step 2.2: Update icon cache");
updateIconCache();
if (DEBUG_LOADERS) Log.d(TAG, "step 2 completed, wait for idle");
waitForIdle();
verifyNotStopped();
if (DEBUG_LOADERS) Log.d(TAG, "step 3.1: loading deep shortcuts");
loadDeepShortcuts();
verifyNotStopped();
if (DEBUG_LOADERS) Log.d(TAG, "step 3.2: bind deep shortcuts");
bindDeepShortcuts();
if (DEBUG_LOADERS) Log.d(TAG, "step 3 completed, wait for idle");
waitForIdle();
verifyNotStopped();
if (DEBUG_LOADERS) Log.d(TAG, "step 4.1: loading widgets");
refreshAndBindWidgetsAndShortcuts(getCallback(), false /* bindFirst */,
null /* packageUser */);
synchronized (mLock) {
mModelLoaded = true;
mHasLoaderCompletedOnce = true;
}
} catch (CancellationException e) {
// Loader stopped, ignore
} finally {
mContext = null;
synchronized (mLock) {
if (mLoaderTask == this) {
mLoaderTask = null;
}
mIsLoaderTaskRunning = false;
}
}
}
……
}
其中会执行加载桌面和加载app。
之后再loadAllApps函数中:
private void loadAllApps() {
……
mHandler.post(new Runnable() {
public void run() {
final long bindTime = SystemClock.uptimeMillis();
final Callbacks callbacks = tryGetCallbacks(oldCallbacks);
if (callbacks != null) {
// 绑定apps
callbacks.bindAllApplications(added);
if (DEBUG_LOADERS) {
Log.d(TAG, "bound " + added.size() + " apps in "
+ (SystemClock.uptimeMillis() - bindTime) + "ms");
}
} else {
Log.i(TAG, "not binding apps: no Launcher activity");
}
}
});
……
}
因为callbacks就是之前传进来的Launcher对象,所以这里就将app传给了Launcher对象。
bindAllApplication函数中:
public void bindAllApplications(final ArrayList apps) {
if (waitUntilResume(mBindAllApplicationsRunnable, true)) {
mTmpAppsList = apps;
return;
}
if (mAppsView != null) {
mAppsView.setApps(apps);
}
if (mLauncherCallbacks != null) {
mLauncherCallbacks.bindAllApplications(apps);
}
}
这里就将app信息传递给了mAppsView界面。这样基本就将app显示出来了。
image.png