53

I have this AndroidManifest.xml file:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1" android:versionName="1.0.0.0721"
android:process="com.lily.process" package="com.lily.test">

    <provider android:authorities="com.lily.test"
      android:name="com.lily.test.provider" 
      android:process="com.lily.process">
    </provider>

"android:process" is added both as manifest tag and provider tag, I know if it is added as a provider tag, the provider can be run in the "com.lily.process" process. But what's the usage of it when written as a manifest tag? I have tried, but not all components could be running in the process it identified.

SilentKnight
  • 13,761
  • 19
  • 49
  • 78
jiangyan.lily
  • 932
  • 1
  • 8
  • 16

4 Answers4

131

I would agree that not many people would find android:process to be useful as an attribute of the application tag. However, I have found it to be useful as an attribute of the activity tag.

The purpose of android:process on an activity is to specify that your activity should be launched in a process having a specific name. The choice of that name may be used either to isolate the activity in its own process (different from the one that launched it), or to force it to cohabit in a single process with other activities that use the same name.

Per the Dev Guide (http://developer.android.com/guide/topics/manifest/activity-element.html):

"If the name assigned to this attribute begins with a colon (':'), a new process, private to the application, is created when it's needed and the activity runs in that process. If the process name begins with a lowercase character, the activity will run in a global process of that name, provided that it has permission to do so. This allows components in different applications to share a process, reducing resource usage."

I have recently found this attribute to be useful in solving a problem I had with launching a help activity for an app that, under certain circumstances, was fairly close to the 16MB heap limit that still applies to some devices. Launching its help activity was, in those situations, pushing my app over the limit, resulting in a force close.

By using the android:process tag, I was able to specify that my help activity should be launched in a separate process of its own. This process had its own 16MB heap, and it was not counted against the heap of my main app that launched it. This permanently and completely prevented my app from running out of heap space and crashing when help was launched.

If your launching app has the package name

com.mycompany.mymainapp

and is therefore assigned a process name that is that same string, then, if you use

android:process=":myhelp"

on your launched activity, it will be assigned the process name

com.mycompany.mymainapp:myhelp

and that process will have its own, separate process ID, which you can view (for example in DDMS).

That, at least, has been my experience. My testing has so far been performed on an old Moto Droid running CM6 (Android 2.2.1), configured to have a 16MB heap limit.

In my case, since I did not want the user to perceive the help as being separate from my app, I included the

android:excludeFromRecents="true"

attribute to prevent the help activity from appearing on the recent apps (long-press Home) list. I also included

android:taskAffinity="com.mycompany.mymainapp.HelpActivity"

where HelpActivity is the name of the help activity, to segregate the activity in its own task

I also added:

android:launchMode="singleInstance"

to prevent multiple instances of this app from being created each time the user invoked help.

I also added the flag:

Intent.FLAG_ACTIVITY_NEW_TASK

to the Intent used to launch the help activity.

These parameters may or may not be needed, depending upon the use that you are making of the android:process attribute.

Considering how often one encounters memory limits when developing for Android devices, having a technique that can, in some cases, allow you to break out parts of your app into separate processes, each with its own heap, seems like a wonderful gift. There may be hidden hazards in doing this that I have not yet considered or experienced, but so far, so good, in my particular instance.

Carl
  • 15,445
  • 5
  • 55
  • 53
  • Thanks for your answer, this was very helpful! I'm wondering if you could shed some light on how remote processes are killed when a user swipes away the application in the "recent apps" UI. I read [this question](http://android.stackexchange.com/questions/19987/what-actually-happens-when-you-swipe-an-app-out-of-the-recent-apps-list#_=_) and am curious to see if you've experienced the same behavior. – Steven Wexler Mar 26 '15 at 16:14
  • @Steven: That is very interesting; I had not known about that behavior at all. The Android philosophy has generally been to let the OS decide, other than when the user employs the Back button to get all the way out of an app. I just tried running my own app https://play.google.com/store/apps/details?id=com.goalstate.WordGames.FullBoard.trialsuite (which uses this approach for its Help), and swiping off either the main app's process or the help process seems to kill them both (even though the other remains on the recently used list). You might try this while running DDMS to be sure. – Carl Mar 29 '15 at 03:54
  • I understand the effort you spent for hiding the activity from the Recents. But should it have nothing to do with inflating a new process? – stdout Nov 10 '15 at 14:42
  • I thought that a separate help process on recents would confuse the user, as the Help activity could just as easily have been an included part of my main process, had I not been trying to conserve heap in that process, which is an implementation detail that should not concern the user. – Carl Nov 12 '15 at 05:09
  • 1
    An Android Process is not related with the entries in the Recents (or Overview Screen). They are tasks belongs to the same appilcation (by default) and this screen allows you to control your sub tasks of your application. – stdout Dec 25 '15 at 07:32
  • I think I understand your point; you're saying that my Help process should have been part of the same task as my main application, and therefore should only have one entry on the Recents list by default. Although that makes sense, my use of FLAG_ACTIVITY_NEW_TASK for Help was causing a separate entry on Recents. TBH, I cannot remember why I needed that flag, but there probably was a reason (good or bad) for doing that. – Carl Dec 29 '15 at 05:24
  • Do new processes must be in the form of packageName, then ":" and then some text? Does each app have to have at least one process with the name that's exactly as its package name? – android developer Nov 16 '16 at 17:07
  • A "hidden hazard" could be the fact that static fields on activities that where launched in different process do not share the same value. A good example would be using Crashlytics. If you initialized it on a "normal activity" (one that has no process defined) and try to use it on another one that was launched on a different process, you will realize your Crashlytics is not initialized. The same goes if you initialized it on the Application class. – Leonardo Sibela Oct 10 '19 at 17:44
8

@Carl

There may be hidden hazards:

  • Memory can not be released When there is a background service(e.g:android:process=":myhelp") in the same process.
  • Singleton pattern can not be used.

Ref : http://developer.android.com/training/articles/memory.html#MultipleProcesses

The process has now almost tripled in size, to 4MB, simply by showing some text in the UI. This leads to an important conclusion: If you are going to split your app into multiple processes, only one process should be responsible for UI. Other processes should avoid any UI, as this will quickly increase the RAM required by the process (especially once you start loading bitmap assets and other resources). It may then be hard or impossible to reduce the memory usage once the UI is drawn.

see2851
  • 627
  • 1
  • 9
  • 13
  • In my case, the user accesses help from the app's main activity, and typically exits the help process once help has been consulted, returning to the main activity and its process. So, for a temporary bit of extra memory during the display of help, this works very well. And of course my help process does involve UI, but this does not create a problem. I believe that if the user were to go directly from viewing help to a different app, that the OS would be able to toss both of my own app's processes out of memory in order to provide memory, if needed by that other app. – Carl Jan 24 '14 at 19:32
  • I would note that the help process in my own example is not a service; it is an activity. Also, the help process does not make use of objects created in the main process, so there's nothing preventing the use of a singleton pattern within my main process, and in fact I do use that pattern. – Carl Jan 24 '14 at 19:42
5

android:process should be used with caution

(Quote from the link below)

A little-known and seemingly undocumented behaviour of Android is that each process of an application has is own Application instance.

So, if you have a service which runs in a different process, calling startService() will init the Appplication class for your app.

More info — Starting Service in Android calls Applications onCreate

Veeresh Charantimath
  • 4,641
  • 5
  • 27
  • 36
2

android:process and shareduserid can be used to pass on resources between packages. In my case, this is coming handy now :)

Source code example: https://github.com/ikust/hello-sharedprocess

Richard Lalancette
  • 2,401
  • 24
  • 29