No se puede acceder a AAssetManager en código nativo pasado de Java en WallpaperService
Estoy intentando tener acceso a los activos en código nativo de un WallpaperService personalizado. El código nativo se compila y funciona, pero intenta obtener la referencia AAssetManager del objeto AssetManager pasado a la función nativa devuelve siempre NULL.
¿Tiene algo que ver con el hecho de que estoy utilizando un servicio en lugar de una actividad que resulta en la referencia AAssetManager que es NULL? En la fuente Java, AssetManager que se pasa a la función nativa es válido y no es nulo.
- Depuración del código Android NDK C / C ++ en Eclipse: los puntos de interrupción no se alcanzan
- Cómo agregar un servicio de sistema a Android Framework
- Asignación simple que viene con valor incorrecto
- Excepción actualizando juego a cocos2d-x v2.0
- La aplicación se bloquea al cambiar de actividad de cocos2d-x a otra actividad en Android
Para probar esto utilicé la demostración CubeLiveWallpaper de los ejemplos proporcionados y el API de nivel de orientación 10. Aquí está el código relevante añadido a la clase CubeWallpaper1 para acceder a la funcionalidad nativa:
static { System.loadLibrary("renderer"); } private static native void load(AssetManager mgr); @Override public void onCreate() { super.onCreate(); AssetManager mgr = getResources().getAssets(); load(mgr); }
Aquí está el código JNI que estoy usando para intentar adquirir una referencia válida de AAssetManager:
#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"); } }
Esto se ha replicado en un par de dispositivos, pero la mayoría de las pruebas se ha realizado en un HTC Desire con 2.3.7.
- Android Studio 1.5 Gradle Experimental: no se puede generar código JNI
- Cómo crear jni y Android.mk?
- Android JNI - Llamar AttachCurrentThread sin DetachCurrentThread
- No se pudo cargar libfoo: findLibrary returned null
- Cómo incluir bibliotecas compartidas precompiladas en apk con eclipse
- Detección de fugas de memoria nativas en el código JNI de Android
- ¿Cómo hago que el método JNI no llame estático cuando se usan objetos nativos de C ++?
- Java.lang.UnsatisfiedLinkError: Método nativo no encontrado: Error en jni ()
Lea los comentarios dentro de asset_manager_jni.h: "Tenga en cuenta que la persona que llama es responsable de obtener y mantener una referencia de VM al jobject para evitar que se recoja basura mientras el objeto nativo está en uso."
En Java, está pasando un objeto (mgr) que puede ser liberado por el recolector de basura una vez que se llame la llamada nativa. Para evitar esto, podría, por ejemplo, crear la variable mgr como un atributo privado en su clase y luego pasarlo por el método de carga, como esto:
private static native void load(AssetManager mgr); private AssetManager mgr; @Override public void onCreate() { super.onCreate(); mgr = getResources().getAssets(); load(mgr); }
Además, creo que debe reemplazar su devolución de llamada nativa de C ++ con:
void Java_com_example_android_livecubes_cube1_CubeWallpaper1_load (JNIEnv *env, jobject obj, jobject assetManager)
- Cómo Calibrar el Acelerómetro Android y Reducir el Ruido, Eliminar la Gravedad
- Nombre de icono de la aplicación Android escogido de la etiqueta de actividad que de la etiqueta de la aplicación