cocos2d-x 通过JNI实现c/c++和Android的java层函数交互

cocos2d-x 通过JNI实现c/c++和Android的java层函数交互

1.JNI


JNI是Java Native Interface的缩写,中文为JAVA本地调用。从Java1.1开始,Java Native Interface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。


JNI实现流程:


\


2.C++与java交互流程图:

\


注:对于跨平台的 cocos2d-x 来说,除非必要,否则可不必深究其理,比如想要使用 Android 平台固有的特性等,那就需要更多的了解 Jni 使用方法,以及 Android 操作系统的更多细节。


3.实例:


实现功能:

(1)通过Android sdk的API得到应用程序的包名(PackageName),然后传递给c++层函数。
(2)通过c++函数调用Android的java层函数,显示一个对话框,点击按钮退出程序。


4.实现步骤:


4.1 使用cocos2d-x创建工程DialogBox及搭配android环境


android环境,如图:


\


4.2 c++部分


先到win32环境,编写提供android调用c++接口:

JniTest.h

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef JNI_TEST_H
#define JNI_TEST_H
  
#include "cocos2d.h"
  
using namespace cocos2d;
  
void setPackageName( const char *packageName)
{
     CCLog( "packageName: %s" , packageName);  
}
  
void exitApp()
{
     CCDirector::sharedDirector()->end();
}
#endif

调用android API接口:

HelloWorldScene.cpp

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "HelloWorldScene.h"
# if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "../proj.android/jni/hellocpp/test.h"
#endif
USING_NS_CC;
  
void HelloWorld::menuCloseCallback(CCObject* pSender)
{
# if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
     showTipDialog( "exit" , "alexzhou,really go?" );
#endif
  
# if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
     exit( 0 );
#endif
}

注:只需要更改下HelloWorldScene就OK了。


接着转到android平台,编写jni层代码:

test.h

?
1
2
3
4
5
6
7
8
#ifndef TEST_H
#define TEST_H
  
extern "C"
{
void showTipDialog( const char *title, const char *msg);
}
#endif
test.cpp

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "cocos2d.h"
#include <JNI.H>
#include "platform/android/jni/JniHelper.h"
#include "test.h"
#include "JniTest.h"
  
#define CLASS_NAME "com/DialogBox/org/JniTestHelper"
  
using namespace cocos2d;
  
extern "C"
{
void showTipDialog( const char *title, const char *msg)
{
     JniMethodInfo t;
     if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "showTipDialog" , "(Ljava/lang/String;Ljava/lang/String;)V" ))
     {
         jstring jTitle = t.env->NewStringUTF(title);
         jstring jMsg = t.env->NewStringUTF(msg);
         t.env->CallStaticVoidMethod(t.classID, t.methodID, jTitle, jMsg);
         t.env->DeleteLocalRef(jTitle);
         t.env->DeleteLocalRef(jMsg);
     }
}
  
void Java_com_DialogBox_org_JniTestHelper_setPackageName(JNIEnv *env, jobject thiz, jstring packageName)
{
     const char *pkgName = env->GetStringUTFChars(packageName, NULL);
     setPackageName(pkgName);
     env->ReleaseStringUTFChars(packageName, pkgName);
}
  
void Java_com_DialogBox_org_JniTestHelper_exitApp(JNIEnv *env, jobject thiz)
{
     exitApp();
}
  
}

注:这里必须加上extern “C”,声明以c语言的方式进行编译,因为c++和c在编译时生成的函数签名不一样,可以在网上查找相关资料,不然运行的时候会出现链接错误。


4.3 Java部分:

c++函数调用java层函数,显示一个对话框:

JniTestHelper.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.DialogBox.org;
  
import org.cocos2dx.lib.Cocos2dxHandler.DialogMessage;
  
import android.os.Handler;
import android.os.Message;
  
public class JniTestHelper {
     private static Handler mHandler;
     public static void init(Handler handler)
     {
         JniTestHelper.mHandler = handler;
     }
      
     public static native void setPackageName(String packageName);
      
     public static native void exitApp();
     //c++函数调用java层函数,显示一个对话框
     private static void showTipDialog( final String title, final String text)  
     {
         Message msg = mHandler.obtainMessage();  
         msg.what = DialogBox.SHOW_DIALOG;  
         DialogMessage dm = new DialogMessage(title, text);  
         msg.obj = dm;  
         msg.sendToTarget();  
     }
      
}
创建一个DialogMessage.java,封装dialog要显示的数据:

?
1
2
3
4
5
6
package com.DialogBox.org;
  
public class DialogMessage {
     public String title;
     public String msg;
}
修改主程序DialogBox.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class DialogBox extends Cocos2dxActivity{
      
     public static final int SHOW_DIALOG = 0x0001 ;
      
     protected void onCreate(Bundle savedInstanceState){
         super .onCreate(savedInstanceState); 
         JniTestHelper.init(mHandler);
         JniTestHelper.setPackageName( this .getPackageName());
     }
  
     public Cocos2dxGLSurfaceView onCreateView() {
         Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView( this );
         // GuideLayer should create stencil buffer
         glSurfaceView.setEGLConfigChooser( 5 , 6 , 5 , 0 , 16 , 8 );
          
         return glSurfaceView;
     }
  
     static {
         System.loadLibrary( "cocos2dcpp" );
     }    
      
     //显示对话框的函数
     private Handler mHandler = new Handler()
     {
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what)
             {
             case SHOW_DIALOG:
                 DialogMessage dm = (DialogMessage)msg.obj;
                 new AlertDialog.Builder(DialogBox. this )
                 .setTitle(dm.titile)
                 .setMessage(dm.message).setNegativeButton( "cancle" , new DialogInterface.OnClickListener() {
                      
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
                         dialog.dismiss();
                     }
                 })
                 .setPositiveButton( "Ok"
                         new DialogInterface.OnClickListener() {
  
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
                         dialog.dismiss();
                         JniTestHelper.exitApp();
                     }
                 })
                 .create().show();
                 break ;
             }
         }
     };
}

编译运行,效果如下:


[�棣m�堋丕倆0r堋�,佘鬏殕窡html

转载地址: http://www.2cto.com/kf/201404/290498.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值