按Home键,后台应用启动Activity需要等待5s原因分析

视频播放选择悬浮窗播放,按home键回到Launcher,此时悬浮窗视频再切换成全屏播放,需要等待5秒原因分析

问题现象:

视频播放选择悬浮窗播放,按home键回到Launcher,此时悬浮窗视频再切换成全屏播放,需要等待5秒左右。

问题分析:

//Home进入Launcher

03-05 15:43:58.047   620   840 I ActivityManager: ->startActivity for ActivityRecord{52345cc u0 com.android.launcher3/.Launcher t483} result:2

//从悬浮窗启动全屏播放intent

03-05 15:43:59.782   620   982 I ActivityManager: START u0 {act=android.intent.action.VIEW dat=content://media/external/video/media/1190 flg=0x10000001 cmp=com.android.gallery3d/com.sprd.gallery3d.app.Video (has extras)} from uid 10025, pid 1497

03-05 15:43:59.785   620   982 W ActivityManager: Activity start request from 10025 stopped

//此时AMS返回START_SWITCHES_CANCELED

03-05 15:43:59.786   620   982 I ActivityManager: ->startActivity for Intent { act=android.intent.action.VIEW dat=content://media/external/video/media/1190 flg=0x10000001 cmp=com.android.gallery3d/com.sprd.gallery3d.app.Video (has extras) }, return START_SWITCHES_CANCELED

//5秒后又一次发送全屏播放的intent

03-05 15:44:02.932   620   707 I ActivityManager: ->startActivity for ActivityRecord{136e33d u0 com.android.gallery3d/com.sprd.gallery3d.app.Video t484} result:0


AMS分析为google原生行为:


如果App想马上启动,不被pending 5s,需要在App的AndroidManifest.xml内申请如下permission:

android.permission.STOP_APP_SWITCHES

并且需要在frameworks/base/data/etc/privapp-permissions-platform.xml

申明,不然会导致CTS不过:


代码分析:

ActivityStarter.java startActivityLocked()方法中:

说到如果启动Activity和当前resumedUID不相同就会检查app switches权限

// If we are starting an activity that is not from the same uid as the currently resumed one, check whether app switches are allowed.  

if (voiceSession == null && (stack.getResumedActivity() == null  

Launcher主界面从悬浮窗回到全屏播放,此时resumed uid是Launcher,但是realCallingUid却是Gallery,所以会进入checkAppSwitchAllowedLocked流程

        || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {  

    if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,  

            realCallingPid, realCallingUid, "Activity start")) {  

        mController.addPendingActivityLaunch(new PendingActivityLaunch(r,  

                sourceRecord, startFlags, stack, callerApp));  

        ActivityOptions.abort(checkedOptions);  

        Slog.i(TAG, "->startActivity for " + intent + ", return START_SWITCHES_CANCELED");  

        return ActivityManager.START_SWITCHES_CANCELED;  

    }  

}  

看看checkAppSwitchAllowedLocked()是如何检查权限的:

boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,  

        int callingPid, int callingUid, String name) {  

mAppSwitchesAllowedTime 表示按HOME键后,在当前系统的时间上加上5秒,这里判断也就表明按home键5s后,再切回全屏播放就不会出现迟 

   if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {  

        return true;  

    }  


    if (mRecentTasks.isCallerRecents(sourceUid)) {  

        return true;  

    }  

  检查应用是否有android.permission.STOP_APP_SWITCHES权限

    int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);  

    if (perm == PackageManager.PERMISSION_GRANTED) {  

        return true;  

    }  

    if (checkAllowAppSwitchUid(sourceUid)) {  

        return true;  

    }  


    // If the actual IPC caller is different from the logical source, then  

    // also see if they are allowed to control app switches.  

    if (callingUid != -1 && callingUid != sourceUid) {  

        perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);  

        if (perm == PackageManager.PERMISSION_GRANTED) {  

            return true;  

        }  

        if (checkAllowAppSwitchUid(callingUid)) {  

            return true;  

        }  

    }  


    Slog.w(TAG, name + " request from " + sourceUid + " stopped");  

    return false;  

}  

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容