悬浮窗启动应用延迟: Activity start request from 10144 stopped

1.问题
进入百度地图,开启导航,按home键回到桌面,此时在桌面出现一个百度地图的悬浮窗,点击小窗口进入百度地图;进入到百度地图主界面用时较长。

2.log及分析
按home键回到桌面,在桌面出现一个百度地图的悬浮窗:表示APP在后台运行;
按Home键回到桌面,在桌面点击百度地图图标进入,不会延时启动;
//点击悬浮窗
10-22 09:01:10.040  6357  6357 I View    : performClick  --this:android.widget.LinearLayout{403ca7b VFE...C.. ...P..I. 0,0-392,104}--mContext:com.baidu.baidumaps.MapsActivity@69b06dc--packageName:com.baidu.BaiduMap--getCall:android.view.View.performClickInternal:7249 android.view.View.access$3600:808 android.view.View$PerformClick.run:27932 android.os.Handler.handleCallback:883 android.os.Handler.dispatchMessage:100 android.os.Looper.loop:221 android.app.ActivityThread.main:7552 java.lang.reflect.Method.invoke:-2 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run:492 com.android.internal.os.ZygoteInit.main:935 
//走到ActivityStarter中的startActivity(在这个方法中会调用checkAppSwitchAllowedLocked)
10-22 09:01:10.042   820  2866 I ActivityTaskManager: START u0 {flg=0x10200000 pkg=com.baidu.BaiduMap cmp=com.baidu.BaiduMap/com.baidu.baidumaps.MapsActivity} from uid 10144 of 6357
//请求被拒
10-22 09:01:10.047   820  2866 W ActivityTaskManager: Activity start request from 10144 stopped
Activity start request from 10144 stopped是在ActivityTaskManagerService的checkAppSwitchAllowedLocked方法中输出:

boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
		int callingPid, int callingUid, String name) {
	if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
		return true;
	}

	if (getRecentTasks().isCallerRecents(sourceUid)) {
		return true;
	}

	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;
}

checkAppSwitchAllowedLocked是在ActivityStarter的startActivity中被调用:

// 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
		|| stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
	if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
			realCallingPid, realCallingUid, "Activity start")) {
		if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {
			mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
					sourceRecord, startFlags, stack, callerApp));
		}
		ActivityOptions.abort(checkedOptions);
		return ActivityManager.START_SWITCHES_CANCELED;
	}
}

当通过home键将当前activity置于后台时,任何在后台startActivity的操作都将会延迟5秒,除非该应用获取了"android.permission.STOP_APP_SWITCHES"权限。
<!-- 按了home键再点击悬浮窗startactivity不用等5s的权限,系统层 -->
<uses-permission android:name="android.permission.STOP_APP_SWITCHES" /> 

3.解决方式
(1)增加android.permission.STOP_APP_SWITCHES权限
<uses-permission android:name="android.permission.STOP_APP_SWITCHES" /> 
(2)使用以下方式启动Activity
Intent intent = new Intent(this, xxx.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pi = PendingIntent.getActivity(context, 0, intent, 0);
pi.send();

猜你喜欢

转载自blog.csdn.net/hanhan1016/article/details/109226855