Android活动生命周期和JNI内存管理

3

我正在尝试制作一个Android应用程序,其中使用了一些JNI代码。
这些JNI代码会分配一些内存,需要释放。假设我有一个包含此代码的类:

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

}

我的问题是,在活动生命周期的哪个阶段调用jni_init和jni_destroy。所以我开始研究活动生命周期的工作原理,但结果让我有点困惑。我想这是因为我试图深入了解Linux进程的层次。但我正在使用JNI,所以这有一定道理。
我创建了一个简单的活动,实现了所有的生命周期回调,并在其中添加了一些日志记录。我也对构造函数做了同样的事情,并添加了JNI代码,记录了进程的pid。
所以,我发现 -即使没有调用onDestroy,活动也可以被销毁(这很清楚,我找到了很多关于此的解释),进程仍在运行(由类似Usage Timelines、ps命令和getpid jni调用验证)。进程正在运行,因此保留分配的内存似乎是合乎逻辑的。
问题是在哪里分配内存。我不能使用onCreate,因为它可能在进程生命周期中被多次调用,因此可能会出现内存泄漏。我也不想使用onStart进行分配,使用onStop进行释放,因为这是不必要的工作。我尝试了单例设计,它似乎可以工作,但我不想使用它,因为我需要MyJniClass具有可重入性(我也想在服务中使用它)。因此,我的问题是——在JNI应用程序中是否有一些推荐的内存管理方法?
编辑: 我看到我没有清楚地描述这个最令人困惑的部分。以下是事件的顺序:
1)我使用启动器中的图标启动应用程序
2)创建了一个新的活动(构造)
3)调用onCreate 4)调用onStart
5)调用onResume 6)我按下Home键
7)调用onSaveInstanceState 8)调用onPause 9)调用onStop 10)我使用启动器中的图标启动应用程序(与步骤1相同)
11)创建了一个新的活动(构造)
12)调用onCreate 13)调用onStart
14)调用onResume 令人困惑的步骤是11)和12),因为进程(pid)仍然相同,但根据文档,如果发生11)和12),则应杀死前一个进程。
谢谢,对所有语法错误表示抱歉。

如果发生11)和12),则应该终止前一个进程。-> 这没有发生吗? 还有一个测试可以进行,检查类的静态构造函数何时被调用(在类级别的任何static { /* code here */ }块中)。 - Geoffroy
不,它并没有改变,pid仍然是相同的。我还在activity类中添加了一个简单的静态计数器,每次调用onCreate时都会增加它的值。静态构造函数中的代码仅在进程启动时调用一次。 - Pavel
1个回答

2

来自这里

android:finishOnTaskLaunch

该属性用于控制在用户再次启动任务 (即在主屏幕上选择任务) 时是否关闭 (结束) 活动的现有实例 - 如果应关闭,则为“true”,如果不应关闭,则为“false”。默认值为“false”。

它清楚地指出,如果您希望活动仅存在一次,则应更改AndroidManifest.xml中的此值。

还有其他可以更改的值,这些值将影响活动的生命周期行为。


谢谢。它有点帮助。问题是,只有从图标启动活动才能正常工作,而不是从另一个应用程序的意图中启动。但这可能已经足够了。另一件事是该进程仍然存在,但我想我无法控制这个情况。我还尝试了android:launchMode="singleTop",似乎更好,但只适用于我的应用程序中只有一个活动。我将此标记为已解决。 - Pavel
如果你找到了更好的解决方案,请告诉我! - Geoffroy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接