无法访问AAssetManager从爪哇WallpaperService通过本地code [英] Can't access AAssetManager in native code passed from Java in WallpaperService

查看:177
本文介绍了无法访问AAssetManager从爪哇WallpaperService通过本地code的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从自定义WallpaperService访问的资产在本土code。本机code编译和作品,但试图从传递到本机函数总是AssetManager对象AAssetManager引用返回NULL。

I'm trying to access the the assets in native code from a custom WallpaperService. The native code compiles and works but trying to get the AAssetManager reference from the AssetManager object passed to the native function always returns NULL.

有什么事情做,我使用的是服务,而不是一个活动,结果在AAssetManager参考被空的事实?在Java源AssetManager传递给本机的功能是有效的,不为空。

Is it something to do with the fact that I am using a Service rather than an Activity that results in the AAssetManager reference being NULL? In the Java source the AssetManager being passed to the native function is valid and is not null.

要测试这一点,我用他们CubeLiveWallpaper演示从所提供的样品和定位API级别10.下面是相关code添加到CubeWallpaper1类以访问本机的功能:

To test this I used them CubeLiveWallpaper demo from the samples provided and targeting API level 10. Here is the relevant code added to the CubeWallpaper1 class in order to access the native functionality:

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

private static native void load(AssetManager mgr);

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

    AssetManager mgr = getResources().getAssets();
    load(mgr);
}

下面是JNI code我使用的尝试,并获得一个有效的AAssetManager参考:

Here is the JNI code I'm using to try and acquire a valid AAssetManager reference:

#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");
    }

}

这已经复制的一对夫妇的设备,但大多数的测试已经做了一个HTC Desire的运行2.3.7。

This has been replicated on a couple of devices but most testing has been done on a HTC Desire running 2.3.7.

推荐答案

阅读里面asset_manager_jni.h的评论说:请注意,调用者负责获取和保持VM参考jobject以prevent它被当作垃圾收集而原生对象正在使用中。

Read the comments inside asset_manager_jni.h: "Note that the caller is responsible for obtaining and holding a VM reference to the jobject to prevent its being garbage collected while the native object is in use."

在Java中,要传递一个对象(经理),可能会被垃圾收集器被释放,一旦本地回调被调用。为prevent这一点,你可以,例如,创建经理变量作为类的私人属性,然后通过负载的方法传递,像这样的:

In Java, you are passing an object (mgr) that may be freed by the garbage collector once the native callback is called. To prevent this, you could, for example, create the mgr variable as a private attribute in your class and then pass it through the load method, such as this:

private static native void load(AssetManager mgr);

private AssetManager mgr;

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

  mgr = getResources().getAssets();
  load(mgr);
}

另外,我觉得你必须更换你的本地C ++回调:

Also, I think you must replace your native C++ callback with:

void Java_com_example_android_livecubes_cube1_CubeWallpaper1_load
     (JNIEnv *env, jobject obj, jobject assetManager) 

这篇关于无法访问AAssetManager从爪哇WallpaperService通过本地code的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆