Jni:invoke Java dialog with native callback:
Store native function address in Java, and invoke native another method to this function.
Key points:
1.Store callback function pointer (address) in Java:to support multiple calls, with data block for each call.
2.Use Primitive long(64bit) in Java to store native callback pointer, for a bit native compatibility
3.intptr_t for pointer in native.
4.Show dialog in UI thread (activity.runonuithread)
5.optional:let the native code to handle localization (minimize Java code)
Java:
1 Public Static native voidNativeonsystemdialogresult (Longnativefuncaddr);2 3 4 classDialogrunnableImplementsRunnable {5 PublicString Mtitle;6 PublicString mmessage;7 PublicString Myes;8 PublicString MNo;9 Public Longmonyesaddr;Ten Public Longmonnoaddr; One Public BooleanMtwobutton; A - ////////////////////////////////////////////////////////////////////////// - ///title, message, localized Yes No theDialogrunnable (string tittle, String message, String Locyes, String locno,LongONYESADDR,LongONNOADDR,BooleanTwobutton) - { -Mtitle =Tittle; -Mmessage =message; +Myes =Locyes; -MNo =Locno; +MONYESADDR =onyesaddr; AMONNOADDR =onnoaddr; atMtwobutton =Twobutton; - } - - ////////////////////////////////////////////////////////////////////////// - Public voidrun () { - in if(Mtwobutton) { -Dialog Dialog =NewAlertdialog.builder (Gameactivity.getinstance ()) to . Settitle (mtitle) + . Setmessage (mmessage) -. Setpositivebutton (Myes,NewDialoginterface.onclicklistener () { the Public voidOnClick (Dialoginterface Dialog,intWhichbutton) { * gameactivity.getinstance (). Nativeonsystemdialogresult (Monyesa DDR); $ }Panax Notoginseng }) -. Setnegativebutton (MNo,NewDialoginterface.onclicklistener () { the Public voidOnClick (Dialoginterface Dialog,intWhichbutton) { + gameactivity.getinstance (). Nativeonsystemdialogresult (Monnoad DR); A } the }) +. setcancelable (false) - . Create (); $ dialog.show (); $}Else { -Dialog Dialog =NewAlertdialog.builder (Gameactivity.getinstance ()) - . Settitle (mtitle) the . Setmessage (mmessage) -. Setpositivebutton (MNo,NewDialoginterface.onclicklistener () {Wuyi Public voidOnClick (Dialoginterface Dialog,intWhichbutton) { the gameactivity.getinstance (). Nativeonsystemdialogresult (Monyesa DDR); - } Wu }) -. setcancelable (false) About . Create (); $ dialog.show (); - } - } - } A + the ////////////////////////////////////////////////////////////////////////// - //cooperate with native code. do not call on Java $ ////////////////////////////////////////////////////////////////////////// the Public voidShowdialogyesno (string title, String Showtext, String Locyes, String locno,LongONYESADDR,Longonnoaddr) { the This. Runonuithread (NewDialogrunnable (title, Showtext, Locyes, Locno, Onyesaddr, ONNOADDR,true) ); the } the - in the
C (for C + +, JNI calls is simpler & different)
1 void Jnicall Java_com_org_package_gameactivity_nativeonsystemdialogresult (jnienv *env, jobject thiz, Jlong FUNCTIONADDR)2{3 void(*funcptr) (void); 4 Funcptr ptr = (funcptr) (void*) function; 5 if NULL )6 ptr (); 7 }
1 //////////////////////////////////////////////////////////////////////////2 //Note:onok & OnCancel can be NULL3 voidAndroid_systemdialog (Const Char* Title,Const Char* Message,Const Char* Yes,Const Char* No,void(*onok) (void),void(*oncancel) (void) )4 {5android_app* app =Getapp ();6jnienv* env = app->activity->env;7 //note:we need to attach Dalvik VM-to-current thread, as it's not main thread8javavm* VM = app->activity->VMs;9 if((*VM)->getenv (VM, (void* *) &env, jni_version_1_6) <0 )Ten(*VM)->attachcurrentthread (VM, &env, NULL); One AJclass Activityclass = (*env)->getobjectclass (env, app->activity->clazz); -Jmethodid Java_method = (*env)Getmethodid (env, Activityclass, -(char8*)"Showdialogyesno", the(char8*)"(ljava/lang/string; ljava/lang/string; ljava/lang/string; ljava/lang/string; JJ) V"); -ASSERT (Java_method! =NULL); - -Jstring Jtitle = (*env)Newstringutf (env, title, strlen (title)); +Jstring jmsg = (*env)Newstringutf (env, message, strlen (message)); -Jstring JOK = (*env)Newstringutf (env, yes, strlen (yes)); +Jstring Jcancel = (*env)Newstringutf (env, no, strlen (No)); A //Note:jlong is a bit atJlong Jonok =(intptr_t) OnOK; -Jlong Joncancel =(intptr_t) onCancel; - //invoke UI Dialog in another thread -(*env)->callvoidmethod (env, app->activity->Clazz, Java_method, Jtitle, jmsg, JOK , Jcancel, Jonok, Joncancel); - -(*env)deletelocalref (env, jtitle); in(*env)deletelocalref (env, jmsg); -(*env)deletelocalref (env, JOK); to(*env)deletelocalref (env, jcancel); +(*env)deletelocalref (env, activityclass); -}
Native Usage Sample:
1 Static voidOnExit ()2 {3Exit0);4 }5 6 voidandroid_confirm_exit ()7 {8 Const Char* title ="Quit";9 Const Char* Message ="unsaved progress would be lost.\nare do sure you want to quit game?";Ten Const Char* Yes ="Ok"; One Const Char* No ="Cancel"; AAndroid_systemdialog (title, message, yes, no, &onexit, NULL); -}
[Work accumulation] Android System dialog with native callback