如何决定何时在单独的进程中运行不同的Android应用程序组件

时间:2014-06-09 06:22:05

标签: android android-activity android-service android-manifest android-contentprovider

我已阅读以下陈述here

By default, all components of the same application run in the same process and most applications should not change this. However, if one needs to control which process a certain component belongs to, he can do so in the manifest file. The manifest entry for each type of component element—<activity>, <service>, <receiver>, and <provider>—supports an android:process attribute that can specify a process in which that component should run. One can set this attribute so that each component runs in its own process or so that some components share a process while others do not.

我想知道开发人员想要在哪些场景中执行此操作并在不同的进程中运行不同的组件,这样做会带来什么好处?

我读过的另一个陈述是

The <application> element in the manifest file also supports an android:process attribute, to set a default value that applies to all components

关于上述声明我想知道为什么开发人员会这样做,默认情况下已经有一个进程与一个应用程序关联,并且所有组件都在该进程内运行。

任何人都可以为我澄清这些事情,因为我在其他任何地方都没有得到任何细节

感谢

3 个答案:

答案 0 :(得分:16)

让我们以Google Chrome browser为例,充分利用android:process属性。在此之前,让我们了解为什么考虑多进程架构。

记住那些古老的日子,当我们使用合作多任务操作系统时。有一个单一的流程和应用程序用于在该单个流程中轮流运行。该架构的问题是,如果一个应用程序错误地通过使整个系统停止而导致单个进程死亡。

现在是一个现代化的操作系统,在自己的流程中运行应用程序。如果一个应用程序行为不当,托管它的进程就会消失,并且不会影响系统的其余部分。

同样适用于浏览器。如果一个网页出现异常,则会在其他选项卡中打开的网页不可用,从而将整个浏览器关闭。因此建立了多进程架构。

浏览器选项卡使用单独的进程来保护浏览器应用程序免受渲染引擎中的错误的影响。每个渲染过程在单独的进程中作为android服务运行。这是通过使用android:process元素的<service>标记来完成的。用于渲染引擎进程的另一个重要标志是android:isolateProcess。此标志确保渲染进程无法访问网络,显示和文件系统等系统资源,从而使浏览器应用程序具有高度安全性。

以下是chrome的清单文件的片段:

 <service android:name="org.chromium.content.app.SandboxedProcessService0" android:permission="com.google.android.apps.chrome.permission.CHILD_SERVICE" android:exported="false" android:process=":sandboxed_process0" android:isolatedProcess="true" />

以下是adb shell的输出:

USER     PID   PPID  VSIZE  RSS     WCHAN    PC         NAME
u0_a14    12926 317   694380 102828 ffffffff 00000000 S com.android.chrome
u0_i16    26875 317   590860 59012 ffffffff 00000000 S com.android.chrome:sandboxed_process5
u0_i17    27004 317   577460 47644 ffffffff 00000000 S com.android.chrome:sandboxed_process6
  

清单文件中的元素也支持   android:process属性,用于设置适用于所有的默认值   部件

默认情况下,应用程序进程的名称将是<manifest>标记中指定的包名称。这可以通过在android:process标记的<application>属性中指定名称来覆盖。一个用例:如果多个应用程序想要在同一进程中运行,只要这些应用程序由相同的证书签名并共享用户ID。

如果<android:process>的名称以:开头,则它会变为该应用程序的私有名称,就像chrome的呈现引擎(com.android.chrome:sandboxed_process5)一样。它意味着除com.android.chrome之外的应用程序无法与此呈现引擎通信。

如果<android:process>的名称以小写字符开头,则它将成为全局进程。来自docs

  

这允许不同应用程序中的组件共享进程,   减少资源使用。

福利摘要:

  • 提高整体应用程序稳定性(崩溃/挂起)。一个服务进程崩溃不会导致整个应用程序崩溃。
  • 通过阻止访问系统的其余部分来实现安全性。
  • 通过在流程中运行组件并在不同的应用程序之间共享来减少资源使用。

基本上,您应该能够分离关注点并决定应用多进程架构是否有意义。

更新1 :添加@Budius评论

每个进程只有一定数量的可用内存。在我工作的应用程序中,我们在大型内存阵列中进行计算密集型处理。那些计算我们总是在一个单独的过程中触发,以确保我们有足够的内存来完成整个事情而不会崩溃OutOfMemory。

答案 1 :(得分:2)

人们可能想要这样做的原因是因为Android可以关闭您的应用程序进程以随时释放系统中的内存,并且您可能希望缓解这种情况。

假设你有一段真正非常重要的代码,需要很长时间才能完成,在它工作的中间杀死是非常糟糕的(例如,银行软件中的金融交易)。将此段代码放在与其他应用程序代码分开的进程中运行的Service中,可确保Android不会终止可能仍在运行的Service用户退出您的应用程序后。

来自文档:

  

在决定杀死哪些进程时,Android系统会对其进行权衡   对用户的相对重要性。例如,它更容易关闭   下载不再可见的活动的进程   屏幕,与托管可见活动的进程相比。决定   因此,是否终止进程取决于状态   在该过程中运行的组件。

您可以阅读更多here

答案 2 :(得分:1)

通常,当您希望非UI任务需要相当长的时间才能完成时,会使用Service。未保留在前台的Activity很可能被操作系统终止,而Service可以无限期地继续运行。

当您不希望垃圾收集器影响其工作时,会在单独的进程中创建Service。在这种情况下,垃圾收集器将仅影响应用程序进程。此外,单独进程中的Service具有额外的优势,即它将比在主应用程序进程中消耗的内存略少。

您在单独进程中声明的Service可以是应用程序的私有:

<service android:process=":my_private_process"

或者它可以是全球性的:

<service android:process="my_global_process"

在后一种情况下,没有冒号前缀。私有进程中的Service只能与您的应用程序进行交互,而公共进程中的Service也可以处理其他应用程序。这主要是在单独的进程中应该使用Service时:您希望应用程序与其他应用程序共享数据或功能,以及在后台执行它而不受操作系统或GC的干扰。引用文档:

This allows components in different applications to share a process, reducing resource usage.