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

May*_*ank 8 android android-manifest android-service android-contentprovider android-activity

在这里阅读了以下陈述

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

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

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

谢谢

Man*_*ani 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" />
Run Code Online (Sandbox Code Playgroud)

这是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
Run Code Online (Sandbox Code Playgroud)

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

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

如果名称以<android:process>start开头:,那么它将成为该应用程序的私有名称,就像chrome的渲染引擎(com.android.chrome:sandboxed_process5)一样.它意味着应用程序除了com.android.chrome无法与此呈现引擎通信.

如果名称<android:process>以小写字符开头,则变为全局进程.来自docs:

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

福利摘要:

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

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

更新1:添加@Budius评论

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


Y.S*_*Y.S 1

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

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

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

<service android:process=":my_private_process"
Run Code Online (Sandbox Code Playgroud)

或者它可以是全局的:

<service android:process="my_global_process"
Run Code Online (Sandbox Code Playgroud)

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

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

  • 事实是,典型的 Android 应用程序开发人员很少使用“android:process”标签。该标签由 AOSP 深处的本机 Android 类使用。应用程序级别的全局流程既没有详细记录,也没有在实践中广泛使用。事实上,这就是为什么我只写“服务”。我什至从未听说过“Activity”、“BroadcastReceiver”或“ContentProvider”在单独的私有进程中使用,更不用说单独的全局进程了。我给你的建议是不要太深入,因为你几乎永远不需要使用它。 (3认同)