Search code examples
androidmemoryjava-native-interface

Android activity lifecycle and jni memory management


I am trying to make an android application, which uses some jni code.
This jni code allocates some memory, which has to be freed. Let`s
suppose I have this class containing this code:

class MyJniClass{

public native void jni_init(); //this allocates some memory
public native void do_something(); //this also allocates some memory,  
which is linked to the memory allocated in jni_init()
public native void jni_destroy(); //this frees all the allocated  
memory in two previous functions

... // some other java code

}

My trouble is, where in activity lifecycle to call jni_init and jni_destroy. So I started some digging how exactly the activity lifecycle works and I am a little bit confused about the results. I suppose that this is caused by the fact, that I am trying to
understand quite deeply to the level of linux processes. But I am using jni, so it makes some sense.

I created a simple activity, implemented all the lifecycle callbacks and put some logging into them. I did the same with the constructor and I also added jni code, which logs the pid of the process.

So, what I found - the activity can be destroyed even if onDestroy is not called (this is clear, I found lots of explanations for this) and the process is still runnig (verified by apps like Usage Timelines, ps command and the getpid jni call). The process is running, so it seems logical to keep the memory allocated.

The problem is, where to allocate the memory. I cannnot use onCreate, because it can called several times during the process lifetime, so memory leaks can happen. I also don't want to use onStart for allocation and onStop for freeing, because it unnecessary work to do. I tried the singleton design, it seems to work, but I don't want to use it, because I need MyJniClass to be reentrant (I want to use it also in a service). So my question is - is there some recommended way how to do memory management in jni apps?

Edit: I see I didn`t describe the most confusing part of this clearly enough. Here is the sequens of events:

1) I start the app using the icon in launcher

2) new activity is created (constructed)

3) onCreate is called

4) onStart is called

5) onResume is called

6) I press the home button

7) onSaveInstanceState is called

8) onPause is called

9) onStop is called

10) I start the app using the icon in launcher (as in step 1)

11) new activity is created (constructed)

12) onCreate is called

13) onStart is called

14) onResume is called

The confusing steps are 11) and 12) because the process (pid) is still the same, but as I understand from documentation, the previous process should be killed if 11) and 12) happen.

Thanks and sorry for all the grammar mistakes.


Solution

  • From here

    android:finishOnTaskLaunch

    Whether or not an existing instance of the activity should be shut down (finished) >whenever the user again launches its task (chooses the task on the home screen) — "true" if >it should be shut down, and "false" if not. The default value is "false".

    It clearly states that you should change this value in AndroidManifest.xml if you want your activity to exist only once.

    There are also other value you can change which will impact the activity life cycle behavior.