在Android10.0上,Recents功能分布在SystemUI和Launcher3里面集成.
一.初始化
跟Android8.1类似,先看初始化入口:
1.Recents.java
Recents继承SystemUI,进程启动后会在Dependency里面通过@Inject进行初始化,然后在SystemUIService里面调用SystemUIApplication的startServicesIfNeeded()里面进行启动:
private final RecentsImplementation mImpl @Override public void start() { //加入callback mCommandQueue.addCallback(this); mImpl.onStart(mContext); }
RecentsImplementation替代了之前的RecentsImpl,是一个interface,由其实现类OverviewProxyRecentsImpl来执行操作,关于该类的实例化用到了dagger2,不懂的同学可以去学习一下;
2.OverviewProxyRecentsImpl.java
private OverviewProxyService mOverviewProxyService; @Override public void onStart(Context context) { mOverviewProxyService = Dependency.get(OverviewProxyService.class); }
根据调用关系,在onStart()里面创建了OverviewProxyService对象,看一下具体实现:
3.OverviewProxyService.java
中间类,在该类内部去绑定远端的service:
@Inject public OverviewProxyService(Context context, CommandQueue commandQueue, NavigationBarController navBarController, NavigationModeController navModeController, NotificationShadeWindowController statusBarWinController, SysUiState sysUiState, PipUI pipUI, Optional<Divider> dividerOptional, Optional<Lazy<StatusBar>> statusBarOptionalLazy, BroadcastDispatcher broadcastDispatcher) { super(broadcastDispatcher); mRecentsComponentName = ComponentName.unflattenFromString(context.getString( com.android.internal.R.string.config_recentsComponentName)); mQuickStepIntent = new Intent(ACTION_QUICKSTEP) .setPackage(mRecentsComponentName.getPackageName()); // Connect to the service updateEnabledState(); startConnectionToCurrentUser(); }
public void startConnectionToCurrentUser() { if (mHandler.getLooper() != Looper.myLooper()) { mHandler.post(mConnectionRunnable); } else { internalConnectToCurrentUser(); } }
private void internalConnectToCurrentUser() { Intent launcherServiceIntent = new Intent(ACTION_QUICKSTEP) .setPackage(mRecentsComponentName.getPackageName()); try { mBound = mContext.bindServiceAsUser(launcherServiceIntent, mOverviewServiceConnection, Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, UserHandle.of(getCurrentUserId())); } }
private IOverviewProxy mOverviewProxy; private final ServiceConnection mOverviewServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mOverviewProxy = IOverviewProxy.Stub.asInterface(service); } }
跟随调用关系来看,在构造方法内部,会去执行startConnectionToCurrentUser来调用bindServiceAsUser()去启动service,在onServiceConnected中,通过IOverviewProxy.Stub.asInterface(service)来获取IOverviewProxy实例,后续会用到;
Service对应的Intent为android.intent.action.QUICKSTEP_SERVICE,R.string.config_recentsComponentName对应如下,用来获取远端服务的应用包名:
<string name="config_recentsComponentName" translatable="false" >com.android.launcher3/com.android.quickstep.RecentsActivity</string>
从ComponentName可以看到,被bind的service是在Launcher3里面,接下来一起看一下对应的远端Service;
4.TouchInteractionService.java
Launcher3内的入口类,通过该类来调用相关逻辑:
private final IBinder mMyBinder = new IOverviewProxy.Stub() { @BinderThread @Override public void onOverviewToggle() { mOverviewCommandHelper.onOverviewToggle(); } } @Override public IBinder onBind(Intent intent) { return mMyBinder; }
可以看到,TouchInteractionService里面创建了IOverviewProxy.Stub实例,然后在onBind()返回;
TouchInteractionService是一个Service,在onCreate()里面进行了一些初始化相关的调用:
@Override public void onCreate() { super.onCreate(); mDeviceState.runOnUserUnlocked(this::onUserUnlocked); sConnected = true; } @UiThread public void onUserUnlocked() { mOverviewComponentObserver = new OverviewComponentObserver(this, mDeviceState); mOverviewCommandHelper = new OverviewCommandHelper(this, mDeviceState, mOverviewComponentObserver); }
可以看到,在TouchInteractionService启动后,会创建OverviewComponentObserver实例和OverviewCommandHelper实例,一起看一下这两个类的实现:
5.OverviewComponentObserver.java
public OverviewComponentObserver(Context context, RecentsAnimationDeviceState deviceState) { ComponentName fallbackComponent = new ComponentName(mContext, RecentsActivity.class); mFallbackIntent = new Intent(Intent.ACTION_MAIN) .addCategory(Intent.CATEGORY_DEFAULT) .setComponent(fallbackComponent) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); updateOverviewTargets(); }
可以看到,在构造方法内部会创建mFallbackIntent,从组成来看,通过该Intent启动RecentsActivity;接下来看一下 updateOverviewTargets():
private void updateOverviewTargets() { mActivityInterface = FallbackActivityInterface.INSTANCE; mIsHomeAndOverviewSame = false; mOverviewIntent = mFallbackIntent; }
在该方法内部,会将mFallbackIntent赋值给mOverviewIntent,后续启动Recents会用到mOverviewIntent;
6.OverviewCommandHelper.java
启动Recents的直接入口类,最终实现了onOverviewToggle():
public OverviewCommandHelper(Context context, RecentsAnimationDeviceState deviceState, OverviewComponentObserver observer) { mRecentsModel = RecentsModel.INSTANCE.get(mContext); mOverviewComponentObserver = observer; } @BinderThread public void onOverviewToggle() { ActivityManagerWrapper.getInstance() .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS); MAIN_EXECUTOR.execute(new RecentsActivityCommand<>()); }
以上就是Recents功能在初始化过程中涉及到的关键类,用一张流程图总结一下:
二.启动
前面分析了初始化涉及到的关键类,系统启动后会启动SystemUI进程,然后进行一系列初始化,接下来看一下进入Recents的流程:
关于手势或Key按键触发这一块逻辑处理跟Android8.1处理是一样的,入口都是在PhoneWindowManager,咱们从Recents接收toggleRecentApps()分析:
1.Recents.java
@Override public void toggleRecentApps() { mImpl.toggleRecentApps(); }
2.OverviewProxyRecentsImpl.java
@Override 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) { mOverviewProxyService.getProxy().onOverviewToggle(); mOverviewProxyService.notifyToggleRecentApps(); } } catch (RemoteException e) { Log.e(TAG, "Cannot send toggle recents through proxy service.", e); } }; //启动runnable } }
在runnable内部会通过OverviewProxyService的getProxy()来获取到Launcher3端实现的IOveriewProxy对象引用,然后调用onOverviewToggle()方法:
3.TouchInteractionService.java
@BinderThread @Override public void onOverviewToggle() { mOverviewCommandHelper.onOverviewToggle(); }
4.OverviewCommandHelper.java
@BinderThread public void onOverviewToggle() { ActivityManagerWrapper.getInstance() .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS); MAIN_EXECUTOR.execute(new RecentsActivityCommand<>()); }
可以看到,在执行onOverviewToggle()后,实际上是通过Executoe执行了RecentsActivityCommand:
private class RecentsActivityCommand<T extends StatefulActivity<?>> implements Runnable { public RecentsActivityCommand() { mActivityInterface = mOverviewComponentObserver.getActivityInterface(); //预加载,Android8.1也有相同的逻辑 mRecentsModel.getTasks(null); } @Override public void run() { // Otherwise, start overview. mListener = mActivityInterface.createActivityInitListener(this::onActivityReady); 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()); }
可以看到,最终是通过registerAndStartActivity()来启动了intent,前面分析到mOverviewComponentObserver.getOverviewIntent()对应的就是mFallbackIntent,最终启动了RecentsActivity;
用一张流程图总结一下: