Android系统启动篇
4,《Android SystemServer进程启动流程》
Android系统开发准备篇
3,《Android Framework代码IDE加载和调试》
Android系统开发实践篇
4,《android单独编译framework模块并push》
Android系统开发核心知识储备篇
1,《Android编译系统-envsetup和lunch代码篇》
6,《Android中Activity、View和Window关系详解》
11,《android中AMS进程通知Zygote进程fork新进程的通信方式》
Android核心功能详解篇
2,《Android 手势导航(从下往上滑动进入多任务页面)》
3,《android手势分析(应用界面左往右边滑动退出应用)》
———————————————————————————————————————————
一,背景介绍
上一篇文章《android系统导航栏视图分析》 可知,点击底部导航栏会进入系统多任务界面,背后的流程接下来会重点介绍。
二,流程分析
根据导航栏视图布局,点击多任务按钮,对应的id是recent_apps,
见文件recent_apps.xml,
<com.android.systemui.statusbar.policy.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/recent_apps"
android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:layout_weight="0"
android:scaleType="center"
android:contentDescription="@string/accessibility_recent"
android:paddingStart="@dimen/navigation_key_padding"
android:paddingEnd="@dimen/navigation_key_padding"
/>
NavigationBarFragment.java注册了click事件,
private void prepareNavigationBarView() {
mNavigationBarView.reorient();
ButtonDispatcher recentsButton = mNavigationBarView.getRecentsButton();
//注册recentsclick事件
recentsButton.setOnClickListener(this::onRecentsClick);
recentsButton.setOnTouchListener(this::onRecentsTouch);
recentsButton.setLongClickable(true);
recentsButton.setOnLongClickListener(this::onLongPressBackRecents);
ButtonDispatcher backButton = mNavigationBarView.getBackButton();
backButton.setLongClickable(true);
ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
homeButton.setOnTouchListener(this::onHomeTouch);
homeButton.setOnLongClickListener(this::onHomeLongClick);
ButtonDispatcher accessibilityButton = mNavigationBarView.getAccessibilityButton();
accessibilityButton.setOnClickListener(this::onAccessibilityClick);
accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick);
updateAccessibilityServicesState(mAccessibilityManager);
updateScreenPinningGestures();
}
当点击recents button时,执行
private void onRecentsClick(View v) {
if (LatencyTracker.isEnabled(getContext())) {
LatencyTracker.getInstance(getContext()).onActionStart(
LatencyTracker.ACTION_TOGGLE_RECENTS);
}
mStatusBarLazy.get().awakenDreams();
//命令队列
mCommandQueue.toggleRecentApps();
}
发送MSG_TOGGLE_RECENT_APPS 消息队列,处理在CommandQueue.java文件中,
case MSG_TOGGLE_RECENT_APPS:
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).toggleRecentApps();
}
break;
调用到文件Recents.java
public void toggleRecentApps() {
// Ensure the device has been provisioned before allowing the user to interact with
// recents
if (!isUserSetup()) {
return;
}
mImpl.toggleRecentApps();
}
OverviewProxyRecentsImpl.java,核心语句是通过binder机制,执行服务端TouchInteractionService.java的onOverviewToggle函数。
public void toggleRecentApps() {
// If connected to launcher service, let it handle the toggle logic
IOverviewProxy overviewProxy = mOverviewProxyService.getProxy();
if (overviewProxy != null) {
final Runnable toggleRecents = () -> {
try {
if (mOverviewProxyService.getProxy() != null) {
//执行代理服务端的onOverviewToggle
mOverviewProxyService.getProxy().onOverviewToggle();
mOverviewProxyService.notifyToggleRecentApps();
}
} catch (RemoteException e) {
Log.e(TAG, "Cannot send toggle recents through proxy service.", e);
}
};
// Preload only if device for current user is unlocked
if (mStatusBarLazy != null && mStatusBarLazy.get().isKeyguardShowing()) {
mStatusBarLazy.get().executeRunnableDismissingKeyguard(() -> {
// Flush trustmanager before checking device locked per user
mTrustManager.reportKeyguardShowingChanged();
mHandler.post(toggleRecents);
}, null, true /* dismissShade */, false /* afterKeyguardGone */,
true /* deferred */);
} else {
toggleRecents.run();
}
return;
} else {
// Do nothing
}
}
通过binder实现跨进程通信,由systemui调用了launcher3的OverviewCommandHelper.java
public void run() {
long elapsedTime = mCreateTime - mLastToggleTime;
mLastToggleTime = mCreateTime;
if (handleCommand(elapsedTime)) {
// Command already handled.
return;
}
if(mActivityInterface.switchToRecentsIfVisible(this::onTransitionComplete)) {
// If successfully switched, then return
//在launcher页面点击recents button时的逻辑
return;
}
// Otherwise, start overview.
mListener = mActivityInterface.createActivityInitListener(this::onActivityReady);
//非launcher页面,点击recents button的逻辑
mListener.registerAndStartActivity(mOverviewComponentObserver.getOverviewIntent(),
new RemoteAnimationProvider() {
@Override
public AnimatorSet createWindowAnimation(
RemoteAnimationTargetCompat[] appTargets,
RemoteAnimationTargetCompat[] wallpaperTargets) {
return RecentsActivityCommand.this.createWindowAnimation(appTargets,
wallpaperTargets);
}
}, mContext, MAIN_EXECUTOR.getHandler(),
mAnimationProvider.getRecentsLaunchDuration());
}
最终打开QuickstepLauncher.java这个activity,展示多任务页面。如下图,