src/android/source/iupandroid_common.c
jobject iupAndroid_GetApplication(JNIEnv* jni_env)
{
	static jobject s_applicationObject = NULL;
	jobject ret_object = NULL;


	if(NULL == s_applicationObject)
	{
		IUPJNI_DECLARE_METHOD_ID_STATIC(IupApplication_getIupApplication);
		jclass java_class;
		jmethodID method_id;

		//	java_class = (*jni_env)->FindClass(jni_env, "br/pucrio/tecgraf/iup/IupApplication");
		java_class = (*jni_env)->NewLocalRef(jni_env, s_classIupApplication);
		method_id = IUPJNI_GetStaticMethodID(IupApplication_getIupApplication, jni_env, java_class, "getIupApplication", "()Lbr/pucrio/tecgraf/iup/IupApplication;");
		ret_object = (*jni_env)->CallStaticObjectMethod(jni_env, java_class, method_id);

		s_applicationObject = (*jni_env)->NewGlobalRef(jni_env, ret_object);
		(*jni_env)->DeleteLocalRef(jni_env, java_class);

	}
	else
	{
		ret_object = (*jni_env)->NewLocalRef(jni_env, s_applicationObject);

	}

	// Note: This is a Local Ref. Caller is expected to call DeleteLocalRef when done.
	return ret_object;

}
/*
*******
FAQ: Why didn't FindClass find my class?
Excerpt: 
If the class name looks right, you could be running into a class loader issue. FindClass wants to start the class search in the class loader associated with your code. It examines the call stack, which will look something like:

    Foo.myfunc(Native Method)
    Foo.main(Foo.java:10)
The topmost method is Foo.myfunc. FindClass finds the ClassLoader object associated with the Foo class and uses that.

This usually does what you want. You can get into trouble if you create a thread yourself (perhaps by calling pthread_create and then attaching it with AttachCurrentThread). Now there are no stack frames from your application. If you call FindClass from this thread, the JavaVM will start in the "system" class loader instead of the one associated with your application, so attempts to find app-specific classes will fail.

There are a few ways to work around this:

Do your FindClass lookups once, in JNI_OnLoad, and cache the class references for later use. Any FindClass calls made as part of executing JNI_OnLoad will use the class loader associated with the function that called System.loadLibrary (this is a special rule, provided to make library initialization more convenient). If your app code is loading the library, FindClass will use the correct class loader.
Pass an instance of the class into the functions that need it, by declaring your native method to take a Class argument and then passing Foo.class in.
Cache a reference to the ClassLoader object somewhere handy, and issue loadClass calls directly. This requires some effort.
*******

Problem: iupAndroid_GetApplication is a very important function that may be used to get a Context from another thread.
And that thread may have been created via pthread_create, 
and then using our iupAndroid_GetEnvThreadSafe() function 
which uses AttachCurrentThread.

So we are vulnerable to the problem described in the FAQ.

Solution: Since this class is special, we will cache it and avoid the FindClass issue that way.
So we need to cache it in JNI_OnLoad.
*/




This usually does what you want. You can get into trouble if you create a thread yourself (perhaps by calling pthread_create and then attaching it with AttachCurrentThread). Now there are no stack frames from your application. If you call FindClass from this thread, the JavaVM will start in the "system" class loader instead of the one associated with your application, so attempts to find app-specific classes will fail.

There are a few ways to work around this.

Do your FindClass lookups once, in JNI_OnLoad, and cache the class references for later use. Any FindClass calls made as part of executing JNI_OnLoad will use the class loader associated with the function that called System.loadLibrary (this is a special rule, provided to make library initialization more convenient). If your app code is loading the library, FindClass will use the correct class loader.
Pass an instance of the class into the functions that need it, by declaring your native method to take a Class argument and then passing Foo.class in.
Cache a reference to the ClassLoader object somewhere handy, and issue loadClass calls directly. This requires some effort.

iupAndroid_GetApplication is a very important function that may be used to get a Context from another thread.
And that thread may have been created via pthread_create,
and then using our iupAndroid_GetEnvThreadSafe() function
which uses AttachCurrentThread.

So we are vulnerable to the problem described in the FAQ.

Since this class is special, we will cache it and avoid the FindClass issue that way.
So we need to cache it in JNI_OnLoad.
This usually does what you want . You can get into trouble if you create a thread yourself ( perhaps by calling pthread_create and then attaching it with AttachCurrentThread ) . Now there are no stack frames from your application . If you call FindClass from this thread the JavaVM will start in the " system " class loader instead of the one associated with your application so attempts to find app - specific classes will fail . There are a few ways to work around this . Do your FindClass lookups once in JNI_OnLoad and cache the class references for later use . Any FindClass calls made as part of executing JNI_OnLoad will use the class loader associated with the function that called System . loadLibrary ( this is a special rule provided to make library initialization more convenient ) . If your app code is loading the library FindClass will use the correct class loader . Pass an instance of the class into the functions that need it by declaring your native method to take a Class argument and then passing Foo . class in . Cache a reference to the ClassLoader object somewhere handy and issue loadClass calls directly . This requires some effort . iupAndroid_GetApplication is a very important function that may be used to get a Context from another thread . And that thread may have been created via pthread_create and then using our iupAndroid_GetEnvThreadSafe () function which uses AttachCurrentThread . So we are vulnerable to the problem described in the FAQ . Since this class is special we will cache it and avoid the FindClass issue that way . So we need to cache it in JNI_OnLoad .
jobject iupAndroid_GetApplication(JNIEnv* jni_env)
{
	static jobject s_applicationObject = NULL;
	jobject ret_object = NULL;
	if(NULL == s_applicationObject)
	{
		IUPJNI_DECLARE_METHOD_ID_STATIC(IupApplication_getIupApplication);
		jclass java_class;
		jmethodID method_id;
		java_class = (*jni_env)->NewLocalRef(jni_env, s_classIupApplication);
		method_id = IUPJNI_GetStaticMethodID(IupApplication_getIupApplication, jni_env, java_class, "getIupApplication", "()Lbr/pucrio/tecgraf/iup/IupApplication;");
		ret_object = (*jni_env)->CallStaticObjectMethod(jni_env, java_class, method_id);
		s_applicationObject = (*jni_env)->NewGlobalRef(jni_env, ret_object);
		(*jni_env)->DeleteLocalRef(jni_env, java_class);
	}
	else
	{
		ret_object = (*jni_env)->NewLocalRef(jni_env, s_applicationObject);
	}
	return ret_object;
}
jobject iupAndroid_GetApplication ( JNIEnv * jni_env ) { static jobject s_applicationObject = NULL ; jobject ret_object = NULL ; if ( NULL == s_applicationObject ) { IUPJNI_DECLARE_METHOD_ID_STATIC ( IupApplication_getIupApplication ) ; jclass java_class ; jmethodID method_id ; java_class = ( * jni_env ) -> NewLocalRef ( jni_env , s_classIupApplication ) ; method_id = IUPJNI_GetStaticMethodID ( IupApplication_getIupApplication , jni_env , java_class , " " , " " ) ; ret_object = ( * jni_env ) -> CallStaticObjectMethod ( jni_env , java_class , method_id ) ; s_applicationObject = ( * jni_env ) -> NewGlobalRef ( jni_env , ret_object ) ; ( * jni_env ) -> DeleteLocalRef ( jni_env , java_class ) ; } else { ret_object = ( * jni_env ) -> NewLocalRef ( jni_env , s_applicationObject ) ; } return ret_object ; }
FAQ: Why didn't FindClass find my class?
FAQ : Why didn ' t FindClass find my class?
//	java_class = (*jni_env)->FindClass(jni_env, "br/pucrio/tecgraf/iup/IupApplication"); // Note: This is a Local Ref. Caller is expected to call DeleteLocalRef when done.