android-자바 대상 강 인용 작성

JAVA 는 인용 되 지 않 은 대상 은 가상 컴퓨터 가 메모 리 를 정리 할 때 수 거 하 는 쓰레기 수 거 메커니즘 이 있 기 때문에 자바 대상 을 약 하 게 인용 할 때,실제 영구 대상 으로 호출 할 때 문제 가 발생 할 수 있 습 니 다.그리고 이 문 제 는 무 작위 로 발생 하기 도 한다.이 는 메모리 정리 회수 시기 와 관련 이 있다.
다음은 JNI 에서 JAVA 의 대상 코드 를 사용 하여 작성 하 는 방법 입 니 다.
JAVA 클래스 방법 작성:
public class TestModule{
	static native boolean native_init(WeakReference<TestModule> wo);
	
	/*        JAVA      JNI  */
	public TestModule() {
		native_init(new WeakReference<TestModule>(this));
	}

	...
	
	/*    JNI   JAVA   */
	static String native_callback(Object wo, int i, String json) {
		try {
			WeakReference<CDCAModule> r = (WeakReference<TestModule>) wo;
			CDCAModule m = r.get();
			if (m != null)
				return m.callback.callback(i, json);
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return null;
	}
}

JNI 작성 방법:
static jobject   g_java_peer = NULL;
static jmethodID g_callback = NULL;

/*   JAVA native_init   */
JNIEXPORT jboolean JNICALL Java_com_test_TestModule_native_init(JNIEnv *e,
		jclass clazz, jobject wo) {
	if (wo == NULL)
		throw_runtime_exception(e, "");
		
	/**
	 *     JAVA  ,          ,             ,  
	 *                   
	 */
	if (g_java_peer == NULL)
		g_java_peer = e->NewGlobalRef(wo);

	/*     JAVA       */
	if ((g_callback = e->GetStaticMethodID(clazz, "native_callback",
			"Ljava/lang/Object;ILjava/lang/String")) == NULL)
		return JNI_FALSE;
	return JNI_TRUE;
}

char*jniCallJavaTestModuleMethod(int id, const char*json, char*buf, int len) {
	JNIEnv*e = NULL;
	jstring ret = NULL;
	char *p = NULL;
	int rlen;

	if (id < 0 || buf == NULL || len <= 0)
		return NULL;
	/*     ,JNIEnv          ,    javaAttachThread         Jni    */
	if ((e = javaAttachThread("test-thread")) == NULL)
		return NULL;
		
	/*   JAVA   */
	if ((ret = (jstring) e->CallStaticObjectMethod((jclass)g_java_peer, g_callback,
			json ? e->NewStringUTF(json) : NULL)) == NULL)
		return NULL;
	p = buf;
	if ((rlen = e->GetStringLength(ret)) > len) {
		char*p = (char*)calloc(1,rlen);
		if (p == NULL)
			return NULL;
	}
	e->GetStringUTFRegion(ret, 0, rlen, p);
	return p;
}

JNI 에서 세 가지 유형의 인용 을 제공 합 니 다.
1.Local Reference 로 컬 참조,함수 호출 시 jobject 또는 jni 함수 가 만 든 jobjct 에 들 어 갑 니 다.JNI 층 함수 가 돌아 오 면 jobject 는 쓰레기 로 회수 되 기 때문에 수명 주기 에 주의해 야 합 니 다.즉시 회수 할 수 있 도록 DeleteLocalRef 를 강제로 호출 할 수 있 습 니 다.
       jstring pathStr = env->NewStringUTF(path)
       ....
env->DeleteLocalRef(pathStr);
2.Global Reference 전체 인용,이러한 대상 이 자발적으로 방출 되 지 않 으 면 영원히 쓰레기 회수 되 지 않 습 니 다
      생 성:env->NewGlobalRef(obj);
      방출:env->DeleteGlobalRef(obj)
3.Weak Global Reference 약 한 전역 참조,특수 한 Global Reference 는 운영 과정 에서 쓰레기 에 의 해 회수 되 기 때문에 사용 할 때 반드시 수명 주기 와 수시로 쓰레기 에 의 해 회수 되 는 것 을 주의해 야 합 니 다.예 를 들 어 메모리 가 부족 할 때.
사용 하기 전에 JNIEnv 의 IsSameObject 를 이용 하여 회수 여 부 를 판단 할 수 있 습 니 다.
env->IsSameObject(obj1,obj2);

좋은 웹페이지 즐겨찾기