[工作积累] Android system dialog with native callback
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, use data block for each call.
2.Use primitive long(64bit) in Java to store native callback pointer, for 64 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:
public static native void nativeOnSystemDialogResult(long nativeFuncAddr);
class DialogRunnable implements Runnable {
public String mTitle;
public String mMessage;
public String mYes;
public String mNo;
public long mOnYesAddr;
public long mOnNoAddr;
public boolean mTwoButton;
//////////////////////////////////////////////////////////////////////////
///title, message, localized Yes No
DialogRunnable(String tittle, String message, String locYes, String locNo, long onYesAddr, long onNoAddr, boolean twoButton)
{
mTitle = tittle;
mMessage = message;
mYes = locYes;
mNo = locNo;
mOnYesAddr = onYesAddr;
mOnNoAddr = onNoAddr;
mTwoButton = twoButton;
}
//////////////////////////////////////////////////////////////////////////
public void run() {
if( mTwoButton ) {
Dialog dialog = new AlertDialog.Builder( GameActivity.getInstance() )
.setTitle(mTitle)
.setMessage(mMessage)
.setPositiveButton( mYes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
GameActivity.getInstance().nativeOnSystemDialogResult( mOnYesAddr );
}
})
.setNegativeButton( mNo, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
GameActivity.getInstance().nativeOnSystemDialogResult( mOnNoAddr );
}
})
.setCancelable(false)
.create();
dialog.show();
}else {
Dialog dialog = new AlertDialog.Builder( GameActivity.getInstance() )
.setTitle(mTitle)
.setMessage(mMessage)
.setPositiveButton( mNo, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
GameActivity.getInstance().nativeOnSystemDialogResult( mOnYesAddr );
}
})
.setCancelable(false)
.create();
dialog.show();
}
}
}
//////////////////////////////////////////////////////////////////////////
//Cooperate with native code. DO NOT call on Java
//////////////////////////////////////////////////////////////////////////
public void showDialogYesNo(String title, String showText, String locYes, String locNo, long onYesAddr, long onNoAddr) {
this.runOnUiThread( new DialogRunnable(title, showText, locYes, locNo, onYesAddr, onNoAddr, true) );
}
C (for C++, JNI calls are simpler & different)
JNIEXPORT void JNICALL Java_com_org_package_GameActivity_nativeOnSystemDialogResult(JNIEnv *env, jobject thiz, jlong functionAddr)
{
typedef void(*FUNCPTR)(void);
FUNCPTR ptr = (FUNCPTR)(void*)function;
if( ptr != null )
ptr();
}
//////////////////////////////////////////////////////////////////////////
//Note: onOK & onCancel can be NULL
void Android_SystemDialog(const char* title, const char* message, const char* yes, const char* no, void(*onOK)(void), void(*onCancel)(void) )
{
android_app* app = GetApp();
JNIEnv* env = app->activity->env;
//note: we need to attach dalvik VM to current thread, as it is not main thread
JavaVM* vm = app->activity->vm;
if ( (*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6) < )
(*vm)->AttachCurrentThread(vm, &env, NULL); jclass ActivityClass = (*env)->GetObjectClass(env, app->activity->clazz);
jmethodID java_method = (*env)->GetMethodID(env, ActivityClass,
(char8*)"showDialogYesNo",
(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) );
//Note: jlong is 64 bit
jlong 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);
(*env)->DeleteLocalRef(env, jMsg);
(*env)->DeleteLocalRef(env, jOK);
(*env)->DeleteLocalRef(env, jCancel);
(*env)->DeleteLocalRef(env, ActivityClass);
}
native usage sample:
static void OnExit()
{
exit();
} void Android_Confirm_Exit()
{
const char* title = "Quit";
const char* message = "Unsaved progress will be lost.\nAre you sure you want to quit game?";
const char* yes = "Ok";
const char* no = "Cancel";
Android_SystemDialog(title, message, yes, no, &OnExit, NULL);
}
[工作积累] Android system dialog with native callback的更多相关文章
- [工作积累] android 中添加libssl和libcurl
1. libssl https://github.com/guardianproject/openssl-android 然后执行ndk-build 2.libcurl 源代码组织结构, 下面的mak ...
- [工作积累] Android dynamic library & JNI_OnLoad
Bionic libc doesn't load dependencies for current .so file (diff from Windows or Linux) so a explici ...
- [工作积累] Android: Hide Navigation bar 隐藏导航条
https://developer.android.com/training/system-ui/navigation.html View decorView = getWindow().getDec ...
- Android PopupWindow Dialog 关于 is your activity running 崩溃详解
Android PopupWindow Dialog 关于 is your activity running 崩溃详解 [TOC] 起因 对于 PopupWindow Dialog 需要 Activi ...
- Android 封装Dialog
package com.example.myandroid01; import android.support.v7.app.ActionBarActivity; import android.os. ...
- [工作记录] Android OpenGL ES: non-square texture - continue
previous: [工作记录] Android OpenGL ES 2.0: square texture not supported on some device recently I found ...
- at android.view.Surface.unlockCanvasAndPost(Native Method)
at android.view.Surface.unlockCanvasAndPost(Native Method) 在绘制动画特效的时候点击back键会报以上异常. 主要原因:当点击back按钮时A ...
- Android Theme.Dialog 到光 AppCompatDialog
我用在我的 style.xml 作为主要应用程序主题 <style name="AppTheme" parent="Theme.AppCompat.Light&qu ...
- Error处理: android.media.MediaRecorder.start(Native Method) 报错:start failed: -19【转】
本文转载自:http://blog.csdn.net/netwalk/article/details/17686993 Error处理: android.media.MediaRecorder.sta ...
随机推荐
- 关于js一般对象与标配对象
当一个js函数对象被创建时,Function 构造器产生的函数对象会运行类似这样的一些代码 this.prototype={constructor:this} 新函数被赋予了一个prototype属性 ...
- (转)最强Android模拟器genymotion的安装与配置
Android开发人员都知道,原生的模拟器启动比较慢,操作起来也不流畅,还会出现莫名的问题.当然很多人都会选择直接使用android手机来开发,但是有时候需要在投影仪上演示程序的时候手机不太好做到吧. ...
- SqlBulkCopy 插入100W条数据时 属性BatchSize的作用
(1)100W条insert语句在一个连接内一句一句加 花了01:17:19.0542805 (2) SqlBulkCopy 插入100W条数据 设置BatchSize=500 耗时:00:03:29 ...
- EF经验分享_jimmyzzc
刚刚接触EF,总结了一些在实际工作中的心德经验,与大家分享一下. 一.Excression表达式树 表达式目录树在LINQ中用于表示分配给类型为Expression<TDelegate>的 ...
- linuxok6410的I2C驱动分析---用户态驱动
3 i2c-dev 3.1 概述 之前在介绍I2C子系统时,提到过使用i2c-dev.c文件在应用程序中实现我们的I2C从设备驱动.不过,它实现的是一个虚拟,临时的i2c_client,随着设备文件 ...
- [原创]PostgreSQL中十进制、二进制、十六进制之间的相互转换
在PostgreSQL中,二进制.十进制.十六进制之间的转换是非常方便的,如下: 十进制转十六进制和二进制 mydb=# SELECT to_hex(10); to_hex -------- a (1 ...
- libcurl 安装使用一
一.下载libcurl http://curl.haxx.se/download/curl-7.21.1.tar.gz 二.安装 指定了安装目录 /usr/local/curl 命令1: ...
- mvc4 http错误403.14 forbidden
1. 检查服务器上是否安装了“HTTP重定向”功能和“静态内容压缩”功能(在添加/删除程序或增加角色处安装). 2. 应用程序池要被配置为“集成” 3. 把.net 4.0安装在iis上 4. 确保自 ...
- 浅谈dynamic的简单使用用法
今天看了博客园里面的dynamic用法,我犹豫从来没接触过,今天恶补了一下,把我对dynamic的认识分享了出来,大家一起学习. Visual C# 2010 引入了一个新类型 dynamic. 该类 ...
- 35.在PCB中删除元件
在PCB Editor里面,如果想进行什么操作,首先得点击这个命令,再点击你要操作的区域/元件,最后右键选择"Done",这样你才能完成一个操作.