基于cocos2d-x 的JNI 使用
关于 JNI 的参数类型填写信息
java 类型 | 对应的签名 |
boolean | Z |
byte | B |
char | C |
short | S |
int | I |
long | J |
float | F |
double | D |
void | V |
Object | L用/分割包的完整类名; Ljava/lang/String; |
Array | [类型签名 ; 比如 [B [Ljava/lang/String; |
此处我想实现 一个关于打电话 的客户端调用的实例
C++ 端
此函数的调用 我是直接使用的 HelloWorld 中的关闭按钮调用的
void HelloWorld::makeCall(CCObject* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
JniMethodInfo minfo;
bool isHave = JniHelper::getStaticMethodInfo(minfo,
"com/og/common/OGMainActivity",
"makeCall",
"()V");
if (isHave)
{
CCLog("makeCall function is running !!!");
JNIEnv* env = minfo.env;
env->CallStaticVoidMethod(minfo.classID, minfo.methodID);
}
CCLog("makeCall function execute over !!!");
#endif
}
Java 端
public static void makeCall() {
String telNo = "10000";
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"+telNo));
MainActivity.getInstance().startActivity(intent);
}
<strong><span style="font-size:14px;">MainActivity 这是一个类继承自 Cocos2dxActivity 而我之前的那个项目自动生成的类 需要继承这个 MainActivity 类 并且 原来的那个类的信息需要全部搬到 MainActivity 类中 可能你有点晕了 , 没关系 ,看一下目录层次图吧!!!</span></strong>
红色区域是默认生成的类,现在该类中的代码如下: 我现在让他继承了 MainActivity 类
package com.cocos2dx.TestSecond;
import com.og.common.MainActivity;
public class TestSecond extends MainActivity {
}
那 MainActivity 类是怎么写的呢,让我们看一下:
package com.og.common;
import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import android.os.Bundle;
public class MainActivity extends Cocos2dxActivity {
private static MainActivity rtnInstance;
public static MainActivity getInstance() {
return rtnInstance;
}
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
rtnInstance = this;
}
public Cocos2dxGLSurfaceView onCreateView() {
Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
// TestSecond should create stencil buffer
glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
return glSurfaceView;
}
static {
System.loadLibrary("cocos2dcpp");
}
}
就是把原来的 TestSecond 文件中的内容复制并 添加了一个获取该类对象的函数 其实你完全可以再原来的类中实现,根据个人爱好设计
当然,makeCall()函数在 OGMainActivity 中了
上述代码基本就可以实现打电话的逻辑了,但是 Java 还有一些权限需要添加 特别需要注意一下
在 Manifest.xml 文件中添加如下权限信息
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CALL_PHONE" />
如有疑问请参考:http://blog.csdn.net/xiefeifei316948714/article/details/38557625
至此,我们就完成了打电话的功能!!!打包测试一下,看看效果,这里我就不上图了,具体效果还需要你自己动手去做。Good Luck !!!
以上内容是我这篇博客的重点,下面的是一些参考信息(JNI 比较基础的调用),不理解的话可以多看看下面的内容
通过 http://xiaominghimi.blog.51cto.com/2614927/908804 这个地址浏览(Himi博客 很权威)可以更容易理解
当然 function5 我还是有一点费解 希望 看到此文的人可以指点 1 2 , 感激不尽
C++端
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
#include "platform/android/jni/JniHelper.h"
#include <android/log.h>
#endif
void HelloWorld::function1()
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
JniMethodInfo minfo;
bool isHave = JniHelper::getStaticMethodInfo(minfo,
<span style="white-space:pre"> </span>"com/og/common/OGMainActivity",
<span style="white-space:pre"> </span>"testFun1",
"()V");
if( !isHave )
{
CCLog("jni: function testFun1 is not exist !!!");
}
else
{
CCLog("jni: function testFun1 exist ...");
minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID);
}
CCLog("jni: function testFun1 execute over !!!");
#endif
}
void HelloWorld::function2()
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
JniMethodInfo minfo;
bool isHave = JniHelper::getStaticMethodInfo(minfo,
"com/og/common/OGMainActivity",
"testFun2",
"(I)V");
if( !isHave )
{
CCLog("jni: function testFun2 is not exist !!!");
}
else
{
CCLog("jni: function testFun2 exist ...");
minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID, 888);
}
CCLog("jni: function testFun2 execute over !!!");
#endif
}
void HelloWorld::function3()
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
JniMethodInfo minfo;
bool isHave = JniHelper::getStaticMethodInfo(minfo,
"com/og/common/OGMainActivity",
"testFun3",
"(I)I");
jint _int;
if( !isHave )
{
CCLog("jni: function testFun3 is not exist !!!");
}
else
{
CCLog("jni: function testFun3 exist ...");
_int = minfo.env->CallStaticIntMethod(minfo.classID, minfo.methodID, 888);
// 尝试 jint 是否能够正常接收返回的 int 值
JniMethodInfo minfo_ty;
bool isReturn = JniHelper::getStaticMethodInfo(minfo_ty,
"com/og/common/OGMainActivity",
"testFun2",
"(I)V");
if (isReturn)
{
minfo_ty.env->CallStaticVoidMethod(minfo_ty.classID, minfo_ty.methodID, _int);
}
}
CCLog("jni: function testFun3 execute over !!!");
#endif
}
void HelloWorld::function4()
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
JniMethodInfo minfo;
bool isHave = JniHelper::getStaticMethodInfo(minfo,
"com/og/common/OGMainActivity",
"testFun4",
"(I)Ljava/lang/String;"); // "(I)Ljava/lang/String;" 注意 ; 的添加
jobject jobj;
if( !isHave )
{
CCLog("jni: function testFun4 is not exist !!!");
}
else
{
CCLog("jni: function testFun4 exist ...");
jobj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID, 888);
}
CCLog("jni: function testFun4 execute over !!!");
#endif
}
void HelloWorld::function5()
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
JniMethodInfo minfo;
bool isHave = JniHelper::getStaticMethodInfo(minfo,
"com/og/common/OGMainActivity",
"rtnActivity",
"()Ljava/lang/Object;"); // "(I)Ljava/lang/Object;" 注意 ; 的添加
jobject jobj;
if( isHave )
{
jobj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID);
CCLog("123123 !!!");
}
CCLog("testFun5 : get right jobj !!!");
isHave = JniHelper::getMethodInfo(minfo,
"com/og/common/OGMainActivity",
"testFun5",
"()V");
if (isHave)
{
minfo.env->CallVoidMethod(jobj, minfo.methodID);
}
CCLog("jni: function testFun5 execute over !!!");
#endif
}
JAVA 端 对应的函数
package com.og.common;
import android.app.Activity;
import android.util.Log;
public class OGMainActivity {
public static Activity actInstance;
public static Object rtnActivity() {
if (actInstance == null) {
actInstance = (Activity)MainActivity.getInstance();
}
return actInstance;
}
public static void testFun1() {
Log.e("testFun1", "return void");
}
public static void testFun2(int _int) {
Log.e("testFun2", "return int = " + _int);
}
public static int testFun3(int _int) {
Log.e("testFun3", "return int = " + _int);
return _int + 1000;
}
public static String testFun4(int _int) {
Log.e("testFun4", "return String; int = " + _int);
return "return String is OK";
}
public void testFun5() {
Log.e("testFun5", "no static function is OK");
}
}
而 Java 调用 C++ : 则 java 端的写法为:
//首先需要提前声明,参数以实际情况而定
public static native void nativeGetCFunction(String uid, String session);
然后可以直接在java端进行调用 obj.nativeGetCFunction();
C++端实现:
extern "C"
{
//注意类名书写格式 路径---类名---方法名
std::string userID = JniHelper::jstring2string(uid);
}