假如我们遇到这样一种情况:通过cocos2d-x在Android平台实现一个录音功能或者播放视频功能,当录音结束或者视频播放结束时,Android该如何通知Cocos2d-x呢?
问题等价于如何在Android中调用Coco2d-x中的C++方法
以下的内容并不打算详细说明Android中使用JNI各种方法,只是通过一个简单栗子来了解使用的步骤
1、创建一个Cocos2d-x的C++项目,包名“com.game.UseJni2”
2、在Eclipse中导入项目中的Android工程。
一开始就报错了,还好这个问题我已经遇到无数次了,所以比较淡定。将项目文件UseJni2/cocos2d/cocos/platform/android/java/src/org,也就是这个org文件夹直接拖进上图Eclipse中的src里面,弹出的对话框中选择Copy files and folders,OK。UseJni2/src/org exists.Do you wish to overwrite? Yes. 这样就不报错了。
在src目录下新建一个包“com.game.UseJni2”,在包中新建一个类“JniCallCocos.java”,这个类只是用于声明本地方法,具体的实现是在Cocos2d-x中的C++文件中实现。通过调用“JniCallCocos.java”中的方法来间接调用Cocos2d-x中的方法。
JniCallCocos.java
package com.game.UseJni2;
public class JniCallCocos
{
public static native void HelloCocos();
}
在AppActivity.java中调用JniCallCocos.java中的方法
package org.cocos2dx.cpp;
import org.cocos2dx.lib.Cocos2dxActivity;
import com.game.UseJni2.JniCallCocos;
import android.os.Bundle;
public class AppActivity extends Cocos2dxActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// 通过JNI调用Cocos2d-x的C++函数
JniCallCocos.HelloCocos();
}
}
3、用Xcode打开Cocos2d-x的C++工程,实现在Java中声明的方法
在Cocos2d-x的C++代码中要实现“JniCallCocos.java”中的方法,首先需要有C++函数声明,即写一个C++的头文件。
这个头文件的全名是按照一定规则的:
声明类所在包名(用“_”分隔) + Java中用作声明的类名
于是这个栗子中的头文件名为
“com_game_UseJni2” + “JniCallCocos” 即 “com_game_UseJni2_JniCallCocos.h”
在XCode中新建C++类“com_game_UseJni2_JniCallCocos”
com_game_UseJni2_JniCallCocos.h
//
// com_game_UseJni2_JniCallCocos.h
// UseJni2
//
// Created by try on 14-10-5.
//
//
#ifndef __UseJni2__com_game_UseJni2_JniCallCocos__
#define __UseJni2__com_game_UseJni2_JniCallCocos__
#if defined(ANDROID)
#include "cocos2d.h"
#include <jni.h>
extern "C"
{
/*
* Class: com_game_UseJni2_JniCallCocos
* Method: HelloCocos
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_game_UseJni2_JniCallCocos_HelloCocos(JNIEnv *, jclass);
}
#endif /* #if defined(ANDROID) */
#endif /* defined(__UseJni2__com_game_UseJni2_JniCallCocos__) */
com_game_UseJni2_JniCallCocos.cpp
//
// com_game_UseJni2_JniCallCocos.cpp
// UseJni2
//
// Created by try on 14-10-5.
//
//
#include "com_game_UseJni2_JniCallCocos.h"
#if defined(ANDROID)
USING_NS_CC;
void JNICALL Java_com_game_UseJni2_JniCallCocos_HelloCocos(JNIEnv *, jclass)
{
// 这里只是简单的打印一下日志,表示调用成功
// 这里用Cocos2d-x的消息中心发送消息给当前场景还是很方便滴
log("收到安卓调用^_^");
}
#endif
4、这步可以跳过,这里只是介绍另外一种创建头文件的方式
其实步骤3的头文件我是用这个方式生成的,然后修改,呵呵,自己写太麻烦。。。
打开终端进入项目目录“UseJni2/proj.android/bin/classes”中,在终端中执行“javah -jni com.game.UseJni2.JniCallCocos”,执行成功后可以在“UseJni2/proj.android/bin/classes”目录中看到生成的头文件“com_game_UseJni2_JniCallCocos.h”
可以看到函数命名也是有潜规则的,多看几个就知道了
Java_com_game_UseJni2_JniCallCocos_HelloCocos
“Java_” + 方法所在包名 + 方法所在的类名 + 方法名
自动生成的com_game_UseJni2_JniCallCocos.h,使用时请用步骤3中的修改过头文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_game_UseJni2_JniCallCocos */
#ifndef _Included_com_game_UseJni2_JniCallCocos
#define _Included_com_game_UseJni2_JniCallCocos
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_game_UseJni2_JniCallCocos
* Method: HelloCocos
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_game_UseJni2_JniCallCocos_HelloCocos
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
5、修改UseJni2/proj.android/jni工程目录下的Android.mk文件
添加本地文件com_game_UseJni2_JniCallCocos.cpp
LOCAL_SRC_FILES := hellocpp/main.cpp \
../../Classes/AppDelegate.cpp \
../../Classes/HelloWorldScene.cpp \
../../Classes/com_game_UseJni2_JniCallCocos.cpp
6、打开终端进入UseJni/proj.android目录,执行build_native.py
7、回到Eclipse,刷新安卓工程然后运行,可以在日志中查看运行结果
我还有一篇 “cocos2d-x中通过jni调用android方法” 的文章,有兴趣可以看下
http://blog.youkuaiyun.com/jegeg/article/details/39780861