问题
In Android JAVA code:
public native int addRenderer(int channel, Object glSurface);
Context context = getApplicationContext();
SurfaceView svRemotePartyA = new SurfaceView(context);
SurfaceView svRemotePartyB = new SurfaceView(context);
addRenderer(0, svRemotePartyA);
addRenderer(1, svRemotePartyB);
In Android JNI C++ code:
extern "C" jint JNIEXPORT JNICALL Java_addRenderer(
JNIEnv* jni,
jobject j_vie,
jint channel,
jobject surface) {
LOG(LS_INFO) << "Java_addRenderer(): surface=" << surface;
// some processing
}
When I run the programme, I always read the following log! both SurfaceView object have same value in JNI C++ code log output:
(render_manager.cc:175): Java_addRenderer(): surface==0xbeed6120
(render_manager.cc:175): Java_addRenderer(): surface==0xbeed6120
What's the problem?
回答1:
You look at local references, which should never be used beyond the context of the same JNI method. If you get a global reference for this jobject, you will get 2 different ones.
回答2:
You should not attempt to associate a meaning with the specific bit pattern of a JNI reference.
For example, in Dalvik, local references are just indices into a table on the stack. If you make the same call several times with different objects, you will see the same "value" for the reference each time, because the object reference is sitting in the same place in the local reference table.
(It's not quite that simple -- Dalvik actually tucked a trivial serial number into the reference to make it easier to tell when a local ref was used after it had been reclaimed -- but you get the idea.)
Similarly, you cannot make the assumption about global references. If you create two global references to the same object, it's very likely that those references will have different 32-bit values.
Every VM is different. Old (pre-ICS) versions of Dalvik actually passed raw pointers around, and you could compare the reference values to determine if two objects were the same. The switch to indirect references required fixing up a few things.
If you want to tell if two objects are the same, you need to have references to both, and use the JNI IsSameObject()
function.
Some additional background is here.
来源:https://stackoverflow.com/questions/31209999/android-jni-c-code-always-get-same-jobject-value-for-2-different-surfaceview