【Anroid8.0源码】SystemUI之Recent近期任务部分

  • EventBus未掌握
  • 事件的处理具体流程未解

启动之预加载

从状态栏上的recent图标入手

StatusBar.java

statusbar上设置recentbutton

makeStatusBarView()

protected void makeStatusBarView(){
    ...
    if(StatusBar.atcEnhancementSupport()){
        setRecentsButton();
        ...    
    }
}
setRecentsButton()
private void setRecentsButton(){
    if(mStatusBarView!=null&&getStatusBarViewRecentsButton()!=null){//判断状态栏是否为空以及状态栏是否有添加近期任务的控件
        getStatusBarViewRecentsButton().setOnClickListener(mRecentsClickListener);//添加点击监听事件
        getStatusBarViewRecentsButton().setOnTouchListener(new View.OnTouchListener(){//添加触摸监听事件
            @Override
            public boolean onTouch(View v,MotionEvent event){
                int action = event.getAction()&MotionEvent.ACTION_MASK;
                if(action == MotionEvent.ACTION_DOWN){
                    mCommandQueue.preloadRecentApps();//预加载近期任务
                }else if(action == MotionEvent.ACTION_CANCEL){
                    mCommandQueue.cancelPreloadRecentApps();                
                }else if(action == MotionEvent.ACTION_UP){
                    if(!v.isPressed()){
                        mCommandQueue.cancelPreloadRecentApps();                    
                    }                
                }
                return false;
            }
        });
    }
}
mRecentsClickListener
private View.OnClickListener mRecentsClickListener = new View.OnClickListener(){
    public void onClick(View v){
        awakenDreams();
        mCommandQueue.toggleRecentApps();
    }
}

CommandQueue.java

toggleRecentApps()

public void toggleRecentApps(){
    synchronized(mLock){
        mHandler.removeMessages(MSG_TOGGLE_RECENT_APPS); //移除之前的,确保消息最新
        Message msg = mHandler.obtainMessage(MSG_TOGGLE_RECENT_APPS,0,0,null);//发送消息,自己接收并处理
        msg.setAsynchronous(true);
        msg.sendToTarget();
    }
}
....
case MSG_TOGGLE_RECENT_APPS:
    for(int i =0; i<mCallbacks.size();i++){
        mCallbacks.get(i).toggleRecentApps();//在Recents.java中调用toggleRecentApps
    }
    break;
toggleRecentApps()

Recents.java

@Override
public void toggleRecentApps(){
    ....
    int currentUser = sSystemServicesProxy.getCurrentUser();
    if(sSystemServicesProxy.isSystemUser(currentUser)){
        mImpl.toggleRecents(growTarget);    
    }else{
        ...    
    }
}
toggleRecents()

RecentsImpl.java

public void toggleRecents(int growTarget){
    ...
    //start the recents activity,启动近期任务
    ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
    startRecentsActivity(runningTask,isHomeStackVisible.value,true,growTarget);
    ...
}

preloadRecentApps()

public void preloadRecentApps(){
    synchronized(mLock){
        mHandler.removeMessages(MSG_PRELOAD_RECENT_APPS);
        mHandler.obtainMessage(MSG_PRELOAD_RECENT_APPS,0,0,null).sendToTarget();
    }
}
...
case MSG_PRELOAD_RECENT_APPS:
    for(int i =0; i<mCallbacks.size();i++){
        mCallbacks.get(i).preloadRecentApps();//在主线程回调
    }
    break;

Recents.java

在systemui启动的时候,就通过SystemUIApplication.java中的mService[i].start()对Recents.java进行初始化

preloadRecentApps()

@Override
public void preloadRecentApps(){
    ...
    int currentUser = sSystemServicesProxy.getCurrentUser();
    if (sSystemServicesProxy.isSystemUser(currentUser)) {//系统用户
        mImpl.preloadRecents();//RecentsImpl.java
    } else {
        if (mSystemToUserCallbacks != null) {
            IRecentsNonSystemUserCallbacks callbacks =
                mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
        if (callbacks != null) {
            try {
                callbacks.preloadRecents();
            } catch (RemoteException e) {
                Log.e(TAG, "Callback failed", e);
            }
        } else {
            Log.e(TAG, "No SystemUI callbacks found for user: " + currentUser);
            }
        }
    }
}

RecentsImpl.java

preloadRecents()

public void preloadRecents(){
    ...
    mHandler.post(()->{
        ...
        RecentsTaskLoader loader = Recents.getTaskLoader();//获取Recents.start()中初始化的RecentsTaskLoader对象
        sInstanceLoadPlan = loader.createLoadPlan(mContext);//返回RecentsTaskLoadPlan对象
        loader.preloadTasks(sInstanceLoadPlan,runningTask.id,!isHomeStackVisible.value);//调用RecentsTaskLoadPlan的preloadPlan()方法预加载所有近期任务,并存入TaskStack中,初始化mStack(TaskStack)
        TaskStack stack = sInstanceLoadPlan.getTaskStack();//获取上面初始化的mStack
        if(stack.getTaskCount()>0){
            preloadIcon(runningTask.id);
            updateHeaderBarLayout(stack,null);
        }
    });
}
preloadTasks()

RecentsTaskLoader.java

public synchronized void preloadTasks(RecentsTaskLoadPlan plan,int runningTaskId,boolean includeFrontMostExcludedTask){
    try{
        plan.preloadPlan(this,runningTaskId,includeFrontMostExcludedTask);    
    }finally{
        Trace.endSection();    
    }
}
preloadPlan()
void preloadPlan(RecentsTaskLoader loader,int runningTaskId,boolean includeFrontMostExcludedTask){
    ...
    if(mRawTasks == null){
        preloadRawTasks(includeFrontMostExcludedTask);    
    }
    ...
    int taskCount = mRawTasks.size();
    for(int i = 0; i < taskCount; i++){
        ActivityManager.RecentTaskInfo t = mRawTasks.get(i);
        Task.TaskKey taskKey = new Task.TaskKey(t.persistentId,t.stackId,t.baseIntent
                                    t.userId,t.firstActiveTime,t.lastActiveTime);//为task生成taskKey
    }
    ...
    ActivityInfo info = loader.getAndUpdateActivityInfo(taskKey);//通过taskKey获取活动信息
    /*加载图标、标题、颜色等信息*/
    Task task = new Task(taskKey,t.affiliatedTaskId, t.affiliatedTaskColor, icon,
        thumbnail, title, titleDescription, dismissDescription, appInfoDescription,
        activityColor, backgroundColor, isLaunchTarget, isStackTask, isSystemApp,
        t.supportsSplitScreenMultiWindow, t.bounds, t.taskDescription, t.resizeMode, t.topActivity,
        isLocked);//新生成task,将获取的信息加载进去
        /*将生成的task添加到allTasks栈中*/
    allTasks.add(task);
    affiliatedTaskCounts.put(taskKey.id, affiliatedTaskCounts.get(taskKey.id, 0) + 1);
    affiliatedTasks.put(taskKey.id, taskKey);
    ...
    mStack = new TaskStack();
    mStack.setTasks(mContext,allTasks,false);//一次性设置多个任务
}
preloadRawTasks()
void preloadRawTasks(boolean includeFrontMostExcludedTask) {
    SystemServicesProxy ssp = Recents.getSystemServices();
    int currentUserId = ssp.getCurrentUser();
    updateCurrentQuietProfilesCache(currentUserId);
    mPreloadedUserId = currentUserId;
    mRawTasks = ssp.getRecentTasks(ActivityManager.getMaxRecentTasksStatic(),
            currentUserId, includeFrontMostExcludedTask, mCurrentQuietProfiles);
    // Since the raw tasks are given in most-recent to least-recent order, we need to reverse it
    Collections.reverse(mRawTasks);
}
setTasks()

当stack中的任务发生变化时调用(remove、add)

public void setTasks(Context context,List<Task> tasks,boolean notifyStackChanges){
    ...
    int removedTaskCount = removedTasks.size();
    Task newFrontMostTask = getStackFrontMostTask(false);
    for(int i =0;i<removedTaskCount;i++){
        mCb.onStackTaskRemoved(this,removedTasks.get(i),newFrontMostTask,AnimationProps.IMMEDIATE,false,true);    
    }
    int addedTaskCount = addedTasks.size();
    for(int i = 0;i < addedTaskCount;i++){
        mCb.onStackTaskAdded(this,addedTasks.get(i));    
    }
}

启动

RecentsImpl.java

startRecentsActivity()

protected void startRecentsActivity(ActivityManager.RunningTaskInfo runningTask,
        boolean isHomeStackVisible,boolean animate,int growTarget){
            ...
            if(!animate){//传入过来的时候animate=true,所以不执行
                startRecentsActivity(ActivityOptions.makeCustomAnimation(mContext,-1,-1),null);
                return ;            
            }
            Pair<ActivityOptions,AppTransitionAnimationSpecsFuture> pair;
            if(isBlacklisted){
                pair = new Pair<>(getUnknowTransitionActivityOptions(),null);
            }else if(useThumbnailTransition){
                pair = getThumbnailTransitionActivityOptions(runningTask,windowOverrideRect);            
            }else{
                pair = new Pair<>(hasRecentTasks?getHomeTransitionActivityOptions():getUnknownTransitionActivityOptions(),null);            
            }
            startRecentsActivity(pair.first,pair.second);
        }
startRecentsActivity()
public final static String RECENTS_PACKAGE = "com.android.systemui";
public final static String RECENTS_ACTIVITY = "com.android.systemui.recents.RecentsActivity";
private void startRecentsActivity(ActivityOptions opts,final AppTransitionAnimationSpecsFuture future){
    Intent intent = new Intent();
    intent.setClassName(RECENTS_PACKAGE,RECENTS_ACTIVITY);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
            |Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
            |Intent.FLAG_ACTIVITY_TASK_ON_HOME);
    HidePipMenuEvent hideMenuEvent = new HidePipMenuEvent();
    hideMenuEvent.addPostAnimationCallback(()->{
        Recents.getSystemServices().startActivityAsUserAsync(intent,opts);
        EventBus.getDefault().send(new RecentsActivityStartingEvent());
        if(future!=null){
            future.precacheSpecs();        
        }
    });
    EventBus.getDefault().send(hideMenuEvent);
}

RecentsActivity.java

onCreate()

@Override
public void onCreate(Bundle savedInstanceState){
    ...
    EventsBus.getDefault().register(this,EVENT_BUS_PRIORITY);//向EventBus注册此活动
    ...
    setContentView(R.layout.recents);
    takeKeyEvents(true);
    mRecentsView = findViewById(R.id.recents_view);
    ...
    //Reload the stack view
    reloadStackView();
}
RecentView.java

加载recents布局时调用

public class RecentsView extends FrameLayout{
    private TaskStackView mTaskStackView;//近期任务视图
    private TextView mStackActionButton;//清空所有任务
    private TextView mEmptyView;//无近期任务时显示文本
    ...
    public RecentsView(Context context,AttributeSet attrs,int defStyleAttr,int defStyleRes){
        ...
        //加载控件
        LayoutInflater inflater = LayoutInflater.from(context);
        mEmptyView = (TextView) inflater.inflate(R.layout.recents_empty,this,false);
        addView(mEmptyView);
        if(RecentsDebugFlags.Static.EnableStackActionButton){//true,执行
        if(mStackActionButton!=null){
            removeView(mStackActionButton);//移除视图
            }
        mStackActionButton = (TextView) inflater.inflate(Recents.getConfiguration().isLowRamDevice
                                                ?R.layout.recents_low_raw_stack_action_button
                                                :R.layout.recents_stack_action_button,
                                                this,false);
        }
        ...
        addView(mStackActionButton);
    }
    reevaluateStyles();//适配更改style
}
reloadStackView()
private void reloadStackView(){
    RecentsTaskLoader loader = Recents.getTaskLoader();
    RecentsTaskLoadPlan loadPlan = RecentsImpl.consumeInstanceLoadPlan();
    ...
    loader.loadTasks(this,loadPlan,loadOpts);
    TaskStack stack = loadPlan.getTaskStack();
    mRecentsView.onReload(stack,mIsVisible);
    ...
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值