【发布时间】:2012-12-17 16:37:57
【问题描述】:
我正在尝试制作一个使用一些 jni 代码的 android 应用程序。
这个 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,活动也可以被销毁(这很清楚,我找到了很多对此的解释)并且该过程仍在运行(通过使用时间线、ps 命令和 getpid jni 调用等应用程序进行验证)。该进程正在运行,因此保持分配的内存似乎是合乎逻辑的。
问题是,在哪里分配内存。我不能使用onCreate,因为它可以在进程生命周期内多次调用,因此可能会发生内存泄漏。我也不想使用 onStart 进行分配和使用 onStop 进行释放,因为这是不必要的工作。我尝试了单例设计,它似乎可以工作,但我不想使用它,因为我需要 MyJniClass 是可重入的(我也想在服务中使用它)。所以我的问题是 - 是否有一些推荐的方法如何在 jni 应用程序中进行内存管理?
编辑: 我看到我没有足够清楚地描述这其中最令人困惑的部分。以下是事件的顺序:
1) 我使用启动器中的图标启动应用程序
2) 新活动被创建(构造)
3) onCreate 被调用
4) onStart 被调用
5) onResume 被调用
6) 我按下主页按钮
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 */ }块)。 -
不,它没有,pid 还是一样的。我还在活动类中添加了一个简单的静态计数器,每次调用 onCreate 时都会递增,并且递增。静态构造函数中的代码只被调用一次(当进程启动时)。
标签: android memory java-native-interface