cocos2dx JNI (win32 + VS12 + cocos2dx-2.2.1)

时间:2022-03-24 12:11:23

基于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>

cocos2dx JNI (win32 + VS12 + cocos2dx-2.2.1)

红色区域是默认生成的类,现在该类中的代码如下:  我现在让他继承了 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"

{

//注意类名书写格式  路径---类名---方法名

JNIEXPORT void JNICALL Java_com_og_common_OGMainActivity_nativeGetCFunction(JNIEnv* env, jclass obj, jstring uid, jstring session) 
{
  std::string sessionKey = JniHelper::jstring2string(session);
std::string userID = JniHelper::jstring2string(uid);
// 接下来使用本地方法就可以了
}

}