基于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);
}