-2
public class GenericApp extends Application {
    // hold the reference to some global object here
    private CustomObj myObjRef;

    public void onCreate() {
        ...
        // initialize it only once!
        myObjRef = new CustomObj();
        ...
    }

    public CustomObj getMyObjReference() {
        return myObjRef;
    }
}

Then in each Activity:

public class ActivityXXX extends Activity {
    private CustomObj savedObjRef;

    public void onCreate() {
        ...
        savedObjRef = ((GenericApp) getApplication()).getMyObjReference();
        ...
    }
}

The reason why I need this is I want to create custom object only once and hold somewhere its reference so that it won't be destroyed when I switch between activities. Each activity runs in its own process (to prevent specific memory leaks; do not suggest me to use the same process instead). But, as explained there, due to process dependence, each Activity starts in different Application. My custom object is too heavy to be Serializable.

Can I declare to use one Application instance for all processes? I think it's impossible. If so, how can I be sure to create only one instance of my custom object to be synchronized by it later among all activities?

Use case: opening Camera each time onResume() is called and closing it in Activity's onPause(). Since opening and closing Camera performs in separate Thread and takes ~300 ms, sometimes Camera doesn't manage to release itself properly in previous Activity before it begins opening via another AsyncTask in another Activity.

Note. I've already tried:

  • Fragments
  • common process
  • Serializable / Parcelable

I think background Service with its own process (android:process=":detector") can handle my task. But since each process spawns new Application, should I consider my Service to be local or remote? Should I use ResultReceiver or BroadcastReceiver?

Update. Simple approach, described above doesn't work. My AndroidManifest.xml (shortened):

<application android:name=".GenericApp">
    <activity android:name=".ActivityOne"
              android:process="process1" />
    <activity android:name=".ActivityTwo"
              android:process="process2" /> 
</application>
Community
  • 1
  • 1
dizcza
  • 630
  • 1
  • 7
  • 19
  • You are specifically asking for each Activity to be opened in its own process (and therefore in its own application). Remove the "Process" attributes and the Activities will share the same Application. You cannot use the same Application class whilst also running each Activity in a separate process. You need to rethink your architecture. If your only reason for using separate processes is to fix memory leaks, you would be better working out where you are leaking memory and fixing that. – Kuffs Nov 11 '15 at 15:16
  • creating Activities in separate processes "to prevent memory leaks" is poor design workaround. You should be able to avoid memory leaks within the same process, period (btw this is not a suggestion). – Leo supports Monica Cellio Oct 01 '17 at 19:21

3 Answers3

3

"Each activity runs in its own process (to prevent specific memory leaks",

it seems to me that you create a very very bad workaround (new processes) for a very dangerous issue (memory leaks) you had and this workaround now is just creating more problems for you.

There's a very good reason why the documentation clearly states that most apps shouldn't use multiple processes and it seems to me that you shouldn't as well.

To direct answer your question: NO, absolutely NOT, you cannot have singletons in different processes. Different processes means they physically are different areas of your memory for ABSOLUTELY EVERYTHING. That's exactly what different processes means.

If you insist going down this road (which it is a very bad idea, I showed to some developers here in the company and they all agree is a bad idea), you must implement an interprocess communication like explained here: https://developer.android.com/guide/components/aidl.html. It's a long hard road with very little to gain from.

Your actual best option is to use LeakCanary (https://github.com/square/leakcanary) to fix those memory leaks and stop using bad workarounds for serious issues.

Budius
  • 39,391
  • 16
  • 102
  • 144
0

According to the official documentation the Application class:

Base class for those who need to maintain global application state. You can provide your own implementation by specifying its name in your AndroidManifest.xml's tag, which will cause that class to be instantiated for you when the process for your application/package is created.

The onCreate method:

Called when the application is starting, before any activity, service, or receiver objects (excluding content providers) have been created.

So, the Application class should meet your requirements. I use this class myself to save data globally, one should only be aware of the garbage collector, your App should be able to be restarted without the values in Application class.

yennsarah
  • 5,467
  • 2
  • 27
  • 48
  • No, It wouldn't. I've already tried using `GenericApp extends Application`, like I described above, and that solution spawns new instance of `GenericApp` before `Activity.onCreate()`. – dizcza Nov 11 '15 at 15:02
  • Amy is correct in everything she says so you need to clarify your "No It Wouldn't" comment. All of your Activities share the same application class. The application will only be instantiated for the first Activity opened. All subsequent Activities will use the same Application class. – Kuffs Nov 11 '15 at 15:05
  • Amy is correct. But it cannot be applied with my AndroidManifest.xml, though. – dizcza Nov 11 '15 at 15:27
0

Yes you can do this by specifying the name of your custom application class in the manifest.

The documentation actually steers you away from this solution though.

There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton.

Reference: http://developer.android.com/reference/android/app/Application.html

You could also look into IPC communication which allows different processes to "talk" to each other.

Kuffs
  • 35,581
  • 10
  • 79
  • 92