我有基本的ndk项目:
NdkTest.java
类和ndk.cpp
文件。现在我有一个C ++对象应该被创建一次,并在应用程序被终止或关闭时被销毁。
所以我的NdkTest.java
看起来像这样:
NdkTest {
static {
System.loadLibrary("testLib");
}
public static native method1();
public static native method2();
}
ndk.cpp
看起来像这样:
#include <jni.h>
extern "C" {
void packageName_ClassName_method1(Env *, class);
void packageName_ClassName_method2(Env *, class);
}
ManagerClass *manager = NULL; //this is actually in .h file but for simplicity of this example I put it here
void packageName_ClassName_method1(Env *env, class clazz) {
if(manager==NULL) {
manager = new Manager();
}
manager->method1();
}
void packageName_ClassName_method2(Env *env, class clazz) {
if(manager==NULL) {
manager = new Manager();
}
manager->method2();
}
现在......经理应该只创建一次,它应该被我所有的本机方法使用。此代码将编译并工作但它将导致内存泄漏,因为管理器永远不会被销毁。应该在哪里销毁?
当然我可以创建像createManager()
和destroyManager()
这样的java方法,但我不想这样做。它甚至可能吗?
我尝试将Manager对象全局化为:
ManagerClass manager;
void packageName_ClassName_method1(Env *env, class clazz) {
manager.method1();
}
void packageName_ClassName_method2(Env *env, class clazz) {
manager.method2();
}
它也有效,但我不知道它的析构函数是否被调用过。我把登录放在那里,但它从未显示过。
所以我的问题是:在Android原生开发中处理释放内存的最佳方法是什么?有什么好的模式吗?如果唯一的方法是创建java方法createManager()
和destroyManager()
那么我应该在哪里调用destroyManager()? Java finalize()不被保证被调用,所以我应该把它放在哪里?
我找到了关于这个主题的精彩视频:
约31分钟。是最好的部分:)
答案 0 :(得分:1)
使用Android内存管理模型,无法保证将调用任何析构函数。本书唯一的保证是将为前台活动调用onPause()
方法。
OTOH,Linux内核负责释放已正常关闭或强制关闭的进程使用的所有资源。
因此,除非你的Singleton锁定了一些内核无法自动回收的特殊系统资源,否则你不必担心它是析构函数。但如果确实如此(例如它锁定了相机),你需要一个防弹机制来尽早解锁这个资源,最好是onPause()
。
所有这些讨论都不适用于创建Singleton。您可以使用上述任何方法,并选择最适合您的体系结构的方法。只有当仍然在创建Manager对象时才开始应用程序销毁序列的竞争情况(仅在多线程场景中)。