Kann nicht auf AAssetManager in nativen code übergeben von Java in WallpaperService
Ich versuche, auf die die Vermögenswerte in nativen code aus einer benutzerdefinierten WallpaperService. Die native-code kompiliert und funktioniert, aber versuchen, um die AAssetManager Verweis aus dem AssetManager-Objekt, das an die native Funktion immer NULL zurück.
Ist es etwas mit der Tatsache zu tun, dass ich Service und nicht als eine Tätigkeit, die Ergebnisse in der AAssetManager Referenz NULL? In der Java-Quellcode der AssetManager wird an die native Funktion übergeben, ist gültig und ist nicht null.
Um dies zu testen habe ich CubeLiveWallpaper demo von den mustern und targeting API level 10. Hier ist der entsprechende code Hinzugefügt, um die CubeWallpaper1 Klasse, um Zugriff auf die native Funktionalität:
static {
System.loadLibrary("renderer");
}
private static native void load(AssetManager mgr);
@Override
public void onCreate() {
super.onCreate();
AssetManager mgr = getResources().getAssets();
load(mgr);
}
Hier ist die JNI-code, den ich verwende, um zu versuchen und zu erwerben ein gültiges AAssetManager Referenz:
#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");
}
}
Dieser repliziert wurde, auf ein paar Geräte, aber die meisten Tests wurden durchgeführt auf einem HTC Desire läuft 2.3.7.
Ja, dabei ein Protokoll.v auf
mgr
im Java-Berichte android.content.res.AssetManager@405185e8
im DDMS.InformationsquelleAutor cshaw | 2012-06-08
Du musst angemeldet sein, um einen Kommentar abzugeben.
Lesen Sie die Kommentare in asset_manager_jni.h: "Beachten Sie, dass der Aufrufer ist verantwortlich für die Beschaffung und das halten einer VM Verweis auf die jobject um zu verhindern, dass deren Müll gesammelt, während das systemeigene Objekt ist in Gebrauch".
In Java, übergeben Sie ein Objekt (mgr), die möglicherweise vom garbage collector freigegeben, sobald der nativen callback wird aufgerufen. Um dies zu verhindern, könnte man zum Beispiel schaffen, den mgr Variablen als private attribute in der Klasse und dann führen Sie es durch die load-Methode, wie diese:
Außerdem denke ich, dass Sie ersetzen müssen, Ihre nativen C++ - callback mit:
Wie Sie dies tun, indem Sie einen SCHLUCK?
InformationsquelleAutor Dani