Android Can';t在服务中从Java传递的本机代码中访问AAssetManager

Android Can';t在服务中从Java传递的本机代码中访问AAssetManager,android,android-ndk,java-native-interface,Android,Android Ndk,Java Native Interface,我正在尝试从自定义服务访问本机代码中的资产。本机代码可以编译并工作,但尝试从传递给本机函数的AssetManager对象获取AAssetManager引用时,始终返回NULL 这是否与我使用的是导致AAssetManager引用为NULL的服务而不是活动有关?在Java源代码中,传递给本机函数的AssetManager有效且不为null 为了测试这一点,我使用了他们提供的示例中的CubeliveWallper演示,目标是API级别10。以下是添加到CubeWallpaper1类中的相关代码,用于

我正在尝试从自定义服务访问本机代码中的资产。本机代码可以编译并工作,但尝试从传递给本机函数的AssetManager对象获取AAssetManager引用时,始终返回NULL

这是否与我使用的是导致AAssetManager引用为NULL的服务而不是活动有关?在Java源代码中,传递给本机函数的AssetManager有效且不为null

为了测试这一点,我使用了他们提供的示例中的CubeliveWallper演示,目标是API级别10。以下是添加到CubeWallpaper1类中的相关代码,用于访问本机功能:

static {
    System.loadLibrary("renderer");
}

private static native void load(AssetManager mgr);

@Override
public void onCreate() {
    super.onCreate();

    AssetManager mgr = getResources().getAssets();
    load(mgr);
}
以下是我用来尝试获取有效AAssetManager引用的JNI代码:

#include <jni.h>
#include <android/log.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>

#define TAG "CubeWallpaper1.c"

void
Java_com_example_android_livecubes_cube1_CubeWallpaper1_load(JNIEnv *env,
                                                             jobject assetManager) {

    AAssetManager *mgr = AAssetManager_fromJava(env, assetManager);
    if (mgr == NULL) {
        __android_log_print(ANDROID_LOG_ERROR, "CubeWallpaper1.c", "error loading asset   maanger");
    } else {
        __android_log_print(ANDROID_LOG_VERBOSE, "CubeWallpaper1.c", "loaded asset  manager");
    }

}
#包括
#包括
#包括
#包括
#定义标签“CubeWallpaper1.c”
无效的
Java_com_示例_android_livecubes_cube1_CubeWallpaper1_load(JNIEnv*env,
jobject资产管理器){
AAssetManager*mgr=AAssetManager_fromJava(env,assetManager);
if(mgr==NULL){
__安卓日志打印(安卓日志错误,“CubeWallpaper1.c”,“加载资产时出错”);
}否则{
__android_log_print(android_log_VERBOSE,“CubeWallpaper1.c”,“加载的资产管理器”);
}
}

这已经在一些设备上进行了复制,但大多数测试都是在运行2.3.7的HTC Desire上进行的。

阅读asset_manager_jni.h中的注释:“注意,调用方负责获取并保存对jobject的VM引用,以防止在使用本机对象时对其进行垃圾收集。”

在Java中,您传递的是一个对象(mgr),一旦调用本机回调,垃圾收集器就可以释放该对象。为了防止出现这种情况,例如,您可以在类中创建mgr变量作为私有属性,然后通过load方法传递它,例如:

private static native void load(AssetManager mgr);

private AssetManager mgr;

@Override
public void onCreate() {
  super.onCreate();

  mgr = getResources().getAssets();
  load(mgr);
}
也,我认为您必须用< /P>替换您的本机C++回调。
void Java_com_example_android_livecubes_cube1_CubeWallpaper1_load
     (JNIEnv *env, jobject obj, jobject assetManager) 

Java代码中的mgr变量是否包含null以外的内容?是的,在Java reports
android.content.res中的
mgr
上执行Log.v。AssetManager@405185e8
在DDMS中。成功!该问题是由JNI方法声明中没有jobject obj参数引起的。也感谢您提醒我们需要保留对AssetManager作业对象的引用。如何使用SWIG实现这一点?