关于在 Service 或 BroadcastReceiver 中 startActivity 的问题

时间:2022-04-14 22:39:22
1. 不从后台启动 Activity 准则:
在谷歌的 Android API Guides 中,特意提醒开发者不要在后台启动 activity,包括在 Service 和 BroadcastReceiver 中,这样的设计是为了避免在用户毫不知情的情况下突然中断用户正在进行的工作,在  http://developer.android.com/guide/practices/seamlessness.html#interrupt 中有如下解释:
That is, don't call startActivity() from BroadcastReceivers or Services running in the background. Doing so will interrupt whatever application is currently running, and result in an annoyed user. Perhaps even worse, your Activity may become a "keystroke bandit" and receive some of the input the user was in the middle of providing to the previous Activity. Depending on what your application does, this could be bad news.
2. 需要违反“不从后台启动 Activity”准则的特例:
特例:即便如此,手机厂商的开发者们在开发基于系统级的应用的时候,可能仍然需要有从 Service 或 BroadcastReceiver 中 startActivity 的需求,往往这样的前提是连这样的 Service 或 BroadcastReceiver 也是由用户的某些操作而触发的,Service 或 BroadcastReceiver 只是充当了即将启动 activity 之前的一些代理参数检查工作以便决定是否需要 start 该 activity。
除非是上述笔者所述的特殊情况,应用开发者都应该遵循 “不要从后台启动 Activity”准则。
一个需要特别注意的问题是,特例中所述的情况还会遇到一个问题,就是当通过 home 键将当前 activity 置于后台时,任何在后台startActivity 的操作都将会延迟 5 秒,除非该应用获取了 "android.permission.STOP_APP_SWITCHES" 权限。
关于延迟 5 秒的操作在 com.android.server.am.ActivityManagerService 中的 stopAppSwitches() 方法中,系统级的应用当获取了 "android.permission.STOP_APP_SWITCHES" 后将不会调用到这个方法来延迟通过后台启动 activity 的操作,事实上 android 原生的 Phone 应用就是这样的情况,它是一个获取了"android.permission.STOP_APP_SWITCHES" 权限的系统级应用,当有来电时,一个从后台启动的 activity 将突然出现在用户的面前,警醒用户有新的来电,这样的设计是合理的。 
所以,当你需要开发类似 Phone 这样的应用时,需要做如下工作:
  1. root 你的手机;
  2. 在 AndroidManifest.xml 中添加 "android.permission.STOP_APP_SWITCHES"  用户权限;
  3. 将你开发的应用程序 push 到手机的 /system/app 目录中。

3.参考资料:
  1. 无缝的设计之——不要中断你的用户: http://developer.android.com/guide/practices/seamlessness.html#interrupt
  2. * 中关于后台 startActivity 被延迟 5 秒的探讨: http://*.com/questions/5600084/starting-an-activity-from-a-service-after-home-button-pressed-without-the-5-seco