5

I'm using AIDL service in my app. I also want to run it another process, so I use android:process=":remote" in service declaration in the manifest.

My problem is that when the :remote process starts it apparently recreates Application object.

I really do not with that as I override application object and call lots of client stuff in the onCreate() method. Yet I want the service code to reside in the same apk with the client.

Can I achieve that? Is Application object always recreated when new process starts?

Appreciate your help. Thanks!

Vasily Kabunov
  • 6,511
  • 13
  • 49
  • 53
ivy_the
  • 280
  • 5
  • 14

2 Answers2

4

I also want to run it another process

Why? What value does that add to the user, to offset the additional RAM, CPU, and battery cost? Very few apps need more than one process.

My problem is that when the ':remote' process starts it apparently recreates Application object

Of course. Each process gets its own.

I really do not with that as I override application object and call lots of client stuff in the 'onCreate()' method

Then get rid of android:process=":remote". Your users will thank you.

Yet I want the service code to reside in the same apk with the client.

What service?

Is Application object always recreated when new process starts?

Yes.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • then why android:process=":remote" property can be set for each component? I mean isnt it to let components to be ran in different processes? I actually want this flexibility in case if remote service crashes so it will not crash my client too. – ivy_the Mar 21 '13 at 13:41
  • 1
    @user1986565: "I actually want this flexibility in case if remote service crashes so it will not crash my client too" -- talented developers use other techniques, such as uncaught exception handlers, to address this, rather than wasting their users' CPU, RAM, and battery. – CommonsWare Mar 21 '13 at 13:46
  • does remote service waste more CPU RAM and battery than the local one? I mean - it executes the same code. So CPU and the battery uses are same. It has its own heap, but heap is growing so it should not be too wasteful. Am I wrong? – ivy_the Mar 21 '13 at 14:07
  • @user1986565: "So CPU and the battery uses are same" -- inter-process communication is substantially more expensive than communication within a process. "It has its own heap, but heap is growing so it should not be too wasteful" -- it will still use more system RAM than will a single process. – CommonsWare Mar 21 '13 at 14:13
  • Yeah, I see. Still I have to run it in a different process - the code service runs is native and is not guaranteed to throw exception, but can just crash its process. But thanks for the inputs. – ivy_the Mar 21 '13 at 14:15
  • 1
    @user1986565: Then you will need to consider moving your stuff out of `Application` and into other singletons, ones that are not automatically created and used in both processes. – CommonsWare Mar 21 '13 at 14:17
  • It is not possible to always recover in an uncaught exception handler, because sometimes your main looper is dead and standard Android functionality like showing an Activity will not work. Worse, you cannot perform any long running operations for a main thread crash because not passing the exception on to the default uncaught exception handler for long enough will cause an Application Not Responding Error, whereas passing it on will cause a Force Close dialog where the user clicks Close and kills the process, often before any background threads can do some given network or file operation. – Lance Nanek Oct 21 '14 at 16:10
  • 1
    This answer somewhat overlooks that Android is heavily based around well engineered IPC and the efficiencies of shared copy-on-write memory pages to begin with. Of course there is *some* penalty in adding yet another process, but it's not as large as one might assume. And there are limitations which having a distinct process can work around - particularly where the issue is in code that can't be modified by the app developer. – Chris Stratton Mar 06 '15 at 20:32
2

As already mentioned by CommonsWare, each of the processes gets its own Application object.

In your Application.onCreate() method you can check whether the method is being called from within the main process or from within the remote process and initialize different stuff accordingly.

@Override
public void onCreate()
{
    super.onCreate();

    if(isRemoteProcess(this))
    {
        // initialize remote process stuff here
    }
    else
    {
        // initialize main process stuff here
    }
}

private boolean isRemoteProcess(Context context)
{
    Context applicationContext = context.getApplicationContext();
    long myPid = (long) Process.myPid();
    List<RunningAppProcessInfo> runningAppProcesses = ((ActivityManager) applicationContext.getSystemService("activity")).getRunningAppProcesses();
    if (runningAppProcesses != null && runningAppProcesses.size() != 0)
    {
        for (RunningAppProcessInfo runningAppProcessInfo : runningAppProcesses)
        {
            if (((long) runningAppProcessInfo.pid) == myPid && "YOUR_PACKAGE_NAME:remote".equals(runningAppProcessInfo.processName))
            {
                return true;
            }
        }
    }
    return false;
}
ra3o.ra3
  • 852
  • 1
  • 8
  • 7