android JNI 与cocos结合篇(二)

来源:互联网 发布:淘宝延时收货多少天 编辑:程序博客网 时间:2024/06/08 02:14

整理来源:http://www.2cto.com/kf/201404/290498.html

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;
 
voidsetPackageName(constchar *packageName)
{
    CCLog("packageName: %s", packageName); 
}
 
voidexitApp()
{
    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;
 
voidHelloWorld::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"
{
voidshowTipDialog(constchar *title, constchar *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"
{
voidshowTipDialog(constchar *title, constchar *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);
    }
}
 
voidJava_com_DialogBox_org_JniTestHelper_setPackageName(JNIEnv *env, jobject thiz, jstring packageName)
{
    constchar *pkgName = env->GetStringUTFChars(packageName, NULL);
    setPackageName(pkgName);
    env->ReleaseStringUTFChars(packageName, pkgName);
}
 
voidJava_com_DialogBox_org_JniTestHelper_exitApp(JNIEnv *env, jobject thiz)
{
    exitApp();
}
 
}</jni.h>

注:这里必须加上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
packagecom.DialogBox.org;
 
importorg.cocos2dx.lib.Cocos2dxHandler.DialogMessage;
 
importandroid.os.Handler;
importandroid.os.Message;
 
publicclass JniTestHelper {
    privatestatic Handler mHandler;
    publicstatic void init(Handler handler)
    {
        JniTestHelper.mHandler = handler;
    }
     
    publicstatic native void setPackageName(String packageName);
     
    publicstatic native void exitApp();
    //c++函数调用java层函数,显示一个对话框
    privatestatic void showTipDialog(finalString title, finalString text) 
    {
        Message msg = mHandler.obtainMessage(); 
        msg.what = DialogBox.SHOW_DIALOG; 
        DialogMessage dm = newDialogMessage(title, text); 
        msg.obj = dm; 
        msg.sendToTarget(); 
    }
     
}
创建一个DialogMessage.java,封装dialog要显示的数据:

?
1
2
3
4
5
6
packagecom.DialogBox.org;
 
publicclass DialogMessage {
    publicString title;
    publicString 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
publicclass DialogBox extendsCocos2dxActivity{
     
    publicstatic final int SHOW_DIALOG = 0x0001;
     
    protectedvoid onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        JniTestHelper.init(mHandler);
        JniTestHelper.setPackageName(this.getPackageName());
    }
 
    publicCocos2dxGLSurfaceView onCreateView() {
        Cocos2dxGLSurfaceView glSurfaceView = newCocos2dxGLSurfaceView(this);
        // GuideLayer should create stencil buffer
        glSurfaceView.setEGLConfigChooser(5,6,5,0,16,8);
         
        returnglSurfaceView;
    }
 
    static{
        System.loadLibrary("cocos2dcpp");
    }   
     
    //显示对话框的函数
    privateHandler mHandler = newHandler()
    {
        @Override
        publicvoid handleMessage(Message msg) {
            switch(msg.what)
            {
            caseSHOW_DIALOG:
                DialogMessage dm = (DialogMessage)msg.obj;
                newAlertDialog.Builder(DialogBox.this)
                .setTitle(dm.titile)
                .setMessage(dm.message).setNegativeButton("cancle",newDialogInterface.OnClickListener() {
                     
                    @Override
                    publicvoid onClick(DialogInterface dialog, intwhich) {
                        dialog.dismiss();
                    }
                })
                .setPositiveButton("Ok",
                        newDialogInterface.OnClickListener() {
 
                    @Override
                    publicvoid onClick(DialogInterface dialog, intwhich) {
                        dialog.dismiss();
                        JniTestHelper.exitApp();
                    }
                })
                .create().show();
                break;
            }
        }
    };
}

编译运行,效果如下:


<img src="http://www.2cto.com/uploadfile/Collfiles/20140403/2014040309145653.jpg" alt="[�棣m�堋丕倆0r堋�,佘鬏殕窡" http:="" www.2cto.com="" kf="" qianduan="" css="" "="" target="_blank" class="keylink" style="border-width: 0px; padding: 0px; margin: 0px; list-style: none; width: 630px; height: 408.254px;">html

1 0