How to decide when to run different android applications components in a separate process
Asked Answered
C

3

8

I have read the following statements 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.

I want to know in which scenarios a developer would like to do so and run different components in different processes and what advantage will he get by doing so?

Another statement that I have read is

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

Regarding the above statement I want to know Why would a developer do that, there is already one process associated with one application by default and all the components run inside that process.

Can anyone clarify these things for me as I am not getting any details on this anywhere else

thanks

Coolth answered 9/6, 2014 at 6:22 Comment(2)
Care to give us the link you read that at? I'm wondering if context would make it clearer.Levulose
link added for ur reference @GabeSechanCoolth
C
16

Let us take the example of Google Chrome browser which has made best use of android:process attribute. Before that let us understand why multi-process architecture was considered.

Remember those age old days, when we were using co-operative multi-tasking operating system. There was one single process and applications used to run in that single process turn by turn. Problem with that architecture was, if one application misbehaves that single process dies off there by bringing entire system down.

Now a days modern operation system, run applications in their own processes. If one application misbehaves, the process hosting it dies off and does not affect rest of the system.

Same applies to the browser. If one web-page misbehaves, it brings down the entire browser there by making web-pages opened in other tabs unavailable. Hence multi-process architecture was built.

Separate processes are used for browser tabs to protect the browser application from bugs in the rendering engine. Each render process is run as an android service in separate process. This is done by using android:process tag of <service> element. Another important flag used for rendering engine process is android:isolateProcess. This flag ensures render process does not have access to the system resources like network, display and file system, there by making the browser application highly secure.

Here is the snippet of chrome's manifest file:

 <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" />

Here is the output of 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

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

By default the name of the application process will be the package name specified in <manifest> tag. This can be overridden by specifying the name in the android:process attribute of the <application> tag. One use case : if multiple applications want to run in the same process, provided those applications are signed by same certificate and share the user ID.

If the name of <android:process> starts with :, it becomes private to that application, as in case of chrome's rendering engine (com.android.chrome:sandboxed_process5). It implies applications except com.android.chrome cannot communicate with this rendering engine.

If the name of <android:process> starts with lowercase character, it becomes global process. From docs:

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

Summary of benefits:

  • To improve overall application stability (crashes / hangs). One service process crash does not bring down entire application.
  • Security by preventing access to the rest of the system.
  • Reduce resource usage, by running component in a process and sharing it among different applications.

Basically you should be able to separate the concerns and decide whether it makes sense to apply multi-process architecture.

Update 1: Adding @Budius comment

Each process have only a certain amount of memory available. In the app I work at, we do computational intensive processing in large memory arrays. Those computational we always fire in a separate process to make sure we'll have enough memory for the whole thing to happen and not crash with OutOfMemory.

Cloud answered 31/8, 2014 at 3:48 Comment(11)
I would add it to your answer memory constrains as well. Each process have only a certain amount of memory available. In the app I work at, we do computational intensive processing in large memory arrays. Those computational we always fire in a separate process to make sure we'll have enough memory for the whole thing to happen and not crash with OutOfMemory.Protist
@Protist Thanks for sharing valuable information. If it is ok with you, can I append your comment to the answer, giving you the credit.Cloud
@Budius: You could use a largeHeap for that.Kutuzov
@ManishMulimani: good answer. Anyway, I don't get fully the first point: what would be the advantage to span multiple services instead of having one service with a thread pool and an appropriate exception handlers? And for the third point, do you have any practical example? I definitely see some value here, but I cannot picture a concrete scenarioKutuzov
@Gil it's an app on Google Play with 700 thousand active users. Those users devices range from the latest flagships all the way down to Samsung disposable crapware and super cheap supermarket branded devices. Just large heap unfortunately is not enough. Even in a new process with large heap we still have to try{} catch(OutOfMemory){} to avoid crashing.Protist
@Budius: ahah crazy :)Kutuzov
@Gil For the first point, i added one more statement. WRT to chrome, What I meant is one malformed html does not bring down entire browser app. Only that specific tab displaying the html file becomes unresponsive or crashes. Regarding 3rd point, I haven't come across any practical example. Efforts are on to find one.Cloud
@ManishMulimani: regarding the 1st point, I understood what you say, but what is the advantage of your multiple process approach over rendering each page in one thread in a thread pool, handling eventual crashes with exception handlers?Kutuzov
@ManishMulimani: hmm depends I guess. The whole idea of process killing is that the system tries to kill processes that are not important for the user, I don't think it has an idea of a wasteful process (I might be wrong here). So if the javascript code is hanging but still relevant to the user then it won't be killed. Anyhow, I'm thinking that it can be a way to organize a big app: Chrome probably uses multiple threads for the rendering, say a couple for the images, one for text etc... Coordinating this across multiple pages in a thread pool would be a messKutuzov
@Gil One extreme scenario, consider a javascript function with infinite loop. The process executing the javascript function will eventually become unresponsive and will be killed. Now a days web pages are not just static pages, they are infact applications. A not well written application can bring entire system down, if all execute in same process. Here browser is equivalent to android system, both run multiple applications and should protect each from other.Cloud
@Gil You can go through the chrome architecture docs and also I've worked on Android chrome application. That is the reason I gave this example.Cloud
R
2

The reason one might want to do this is because Android can shut down your application process to free up memory in the system any time it wants to, and you may want to mitigate the situation.

Suppose you have a really, really important piece of code that takes a long while to complete that would be very bad to kill in the middle of it working (for instance, a financial transaction in bank software). Putting this piece of code in a Service that runs in a separate process from the rest of the application code will ensure Android doesn't kill your Service that is potentially still running after the user exited your application.

From the docs:

When deciding which processes to kill, the Android system weighs their relative importance to the user. For example, it more readily shuts down a process hosting activities that are no longer visible on screen, compared to a process hosting visible activities. The decision whether to terminate a process, therefore, depends on the state of the components running in that process.

You can read more here

Ruth answered 31/8, 2014 at 2:47 Comment(0)
S
1

In general, a Service is used when you expect a non-UI task to take a fairly long time to complete. An Activity that does not remain in the foreground can in all probability be terminated by the OS, while a Service can continue to run indefinitely.

A Service is created in a separate process when you don't want the garbage collector to affect its working. The garbage collector will, in that case, affect only the application process. Moreover, a Service in a separate process has the added advantage that it will consume slightly less memory than what it would if it were in the main application process.

The Service that you declare in a separate process can be either private to the application:

<service android:process=":my_private_process"

or it can be global:

<service android:process="my_global_process"

In the latter case there is no colon prefix. A Service in a private process can only interact with your application, while a Service in a public process can deal with other applications as well. This is mainly when a Service should be used in a separate process: when you want your application to share data or functionality with other applications, and to do it in the background without being disturbed by the OS or the GC. To quote the documentation:

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

Schmitt answered 9/6, 2014 at 6:40 Comment(2)
your answer is specific to the Service, can you explain about other components.Coolth
The truth is, typical Android app developers rarely if ever use the android:process tag. This tag is used by native Android classes deep in the AOSP. Global processes at the application level are neither well documented nor widely used in practice. In fact, thats why I've only written about Service. I never even heard of Activity, BroadcastReceiver` or ContentProvider being used in a separate private process, leave alone a separate global process. My advice to you is not go too deep into this as you will practically never need to use it.Schmitt

© 2022 - 2024 — McMap. All rights reserved.