开始编写Cocosd-x对Java进行调用的测试代码

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

目前计划是这样的, 首先, 在Java代码中写两个测试的函数,JniTestFunction_Static, JniTestFunction.

话说,在VIM还不熟练的时候使用VIM真的是降低效率思密达。VIM和Emacs还是得会一个,考虑到Stalllman的固执己见,我还是觉得VIM更体贴一些。


JniHelper.h中定义了一个结构体JniMethodInfo和一个类JniHelper. 代码如下:

/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __ANDROID_JNI_HELPER_H__
#define __ANDROID_JNI_HELPER_H__

#include <jni.h>
#include <string>
#include "platform/CCPlatformMacros.h"

NS_CC_BEGIN

typedef struct JniMethodInfo_
{
	
//	The env pointer is a structure that contains the interface to the 
//	JVM. It includes all of the functions necessary to interact with 
//	the JVM and to work with Java objects. Example JNI functions are 
//	converting native arrays to/from Java arrays, converting native 
//	strings to/from Java strings, instantiating objects, throwing 
//	exceptions, etc. Basically, anything that Java code can do can be 
//	done using JNIEnv, albeit with considerably less ease.
	
//	env指针是一个包含了JVM接口的指针。他包含了全部必要的用来和JVM进行通讯的函数。比如
//	将本地数组转换成Java数组,将本地字符串转换成Java字符串,实例化对象,抛出异常等等。
//	基本上,任何可以用Java代码实现的功能都可以通过JNIEnv实现,尽管实现的不是那么轻松。
	
//  A JNI interface pointer (JNIEnv*) is passed as an argument for each 
//  native function mapped to a Java method, allowing for interaction 
//  with the JNI environment within the native method. This JNI 
//  interface pointer can be stored, but remains valid only in the 
//  current thread. Other threads must first call AttachCurrentThread() 
//  to attach themselves to the VM and obtain a JNI interface pointer. 
//  Once attached, a native thread works like a regular Java thread 
//  running within a native method. The native thread remains attached 
//  to the VM until it calls DetachCurrentThread() to detach itself.[4]

//	JNI interface pointer (JNIEnv*) 在每一个对应于Java函数的Native函数中都作为
//	一个参数传入,这样做可以让JNI环境和Native函数进行沟通。这个JNI接口会被储存,但是
//	只有在当前线程中有效。其他的线程必须首先调用AttachCurrentThread()来将他们自己
//	附到VM上并且获取一个JNIEnv.一旦附属到VM上,一个Native线程就会像一个Java线程那样
//	运行。本地线程会保持附属直到调用DetachCurrentThread().

//  参见 jni.h
    JNIEnv *    env;
    jclass      classID;
    jmethodID   methodID;
} JniMethodInfo;

class CC_DLL JniHelper
{
public:
    static JavaVM* getJavaVM();
    static void setJavaVM(JavaVM *javaVM);
    static jclass getClassID(const char *className, JNIEnv *env=0);
    static bool getStaticMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);
    static bool getMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);
    static std::string jstring2string(jstring str);

private:
    static JavaVM *m_psJavaVM;
};

NS_CC_END

#endif // __ANDROID_JNI_HELPER_H__

现在我定义一个JniMethodInfo. 然后用getStaticMethodInfo来尝试获得Java里面的jniTestFunction_Static的函数信息

写道HelloWorldScene.cpp中

#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
#include "platform/android/jni/JniHelper.h"
#include <android/log.h>
#endif

using namespace cocos2d;
using namespace CocosDenshion;

CCScene* HelloWorld::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();
    
    // 'layer' is an autorelease object
    HelloWorld *layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !CCLayer::init() )
    {
        return false;
    }

    /////////////////////////////
    // 2. add a menu item with "X" image, which is clicked to quit the program
    //    you may modify it.

    // add a "close" icon to exit the progress. it's an autorelease object
    CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
                                        "CloseNormal.png",
                                        "CloseSelected.png",
                                        this,
                                        menu_selector(HelloWorld::menuCloseCallback) );
    pCloseItem->setPosition( ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20) );

    // create menu, it's an autorelease object
    CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
    pMenu->setPosition( CCPointZero );
    this->addChild(pMenu, 1);

    /////////////////////////////
    // 3. add your codes below...

    // add a label shows "Hello World"
    // create and initialize a label
    CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Thonburi", 34);

    // ask director the window size
    CCSize size = CCDirector::sharedDirector()->getWinSize();

    // position the label on the center of the screen
    pLabel->setPosition( ccp(size.width / 2, size.height - 20) );

    // add the label as a child to this layer
    this->addChild(pLabel, 1);

    // add "HelloWorld" splash screen"
    CCSprite* pSprite = CCSprite::create("HelloWorld.png");

    // position the sprite on the center of the screen
    pSprite->setPosition( ccp(size.width/2, size.height/2) );

    // add the sprite as a child to this layer
    this->addChild(pSprite, 0);
    
    // JNI call test
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判断当前是否为Android平台
    JniMethodInfo minfo;//定义Jni函数信息结构体
    //getStaticMethodInfo 次函数返回一个bool值表示是否找到此函数
    bool isHave = JniHelper::getStaticMethodInfo(minfo,"com/chen/FuckAndroid","JniTestFunction_Static", "()V");
 
    if (!isHave) {
        CCLog("jni:此函数不存在");
    }else{
        CCLog("jni:此函数存在");
        //调用此函数
        minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID);
    }
    CCLog("jni-java函数执行完毕");
#endif
    
    
    return true;
}

void HelloWorld::menuCloseCallback(CCObject* pSender)
{
    CCDirector::sharedDirector()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
}

调用的方法在com.chen.FuckAndroid.java中

/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
package com.chen;

import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.Cocos2dxEditText;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import org.cocos2dx.lib.Cocos2dxRenderer;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ConfigurationInfo;
import android.os.Bundle;
import android.util.Log;
import android.widget.FrameLayout;
import android.view.ViewGroup;

public class FuckAndroid extends Cocos2dxActivity{

	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		
		if (detectOpenGLES20()) {
			// get the packageName,it's used to set the resource path
			String packageName = getApplication().getPackageName();
			super.setPackageName(packageName);
			
            // FrameLayout
            ViewGroup.LayoutParams framelayout_params =
                new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
                                           ViewGroup.LayoutParams.FILL_PARENT);
            FrameLayout framelayout = new FrameLayout(this);
            framelayout.setLayoutParams(framelayout_params);

            // Cocos2dxEditText layout
            ViewGroup.LayoutParams edittext_layout_params =
                new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
                                           ViewGroup.LayoutParams.WRAP_CONTENT);
            Cocos2dxEditText edittext = new Cocos2dxEditText(this);
            edittext.setLayoutParams(edittext_layout_params);

            // ...add to FrameLayout
            framelayout.addView(edittext);

            // Cocos2dxGLSurfaceView
	        mGLView = new Cocos2dxGLSurfaceView(this);

            // ...add to FrameLayout
            framelayout.addView(mGLView);

	        mGLView.setEGLContextClientVersion(2);
	        mGLView.setCocos2dxRenderer(new Cocos2dxRenderer());
            mGLView.setTextField(edittext);

            // Set framelayout as the content view
			setContentView(framelayout);
		}
		else {
			Log.d("activity", "don't support gles2.0");
			finish();
		}	
	}
	
	 @Override
	 protected void onPause() {
	     super.onPause();
	     mGLView.onPause();
	 }

	 @Override
	 protected void onResume() {
	     super.onResume();
	     mGLView.onResume();
	 }
	 
	 private boolean detectOpenGLES20() 
	 {
	     ActivityManager am =
	            (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
	     ConfigurationInfo info = am.getDeviceConfigurationInfo();
	     return (info.reqGlEsVersion >= 0x20000);
	 }
	 
	 //////////////////////////
	 // These functions will be called by C++ code
	 public static void JniTestFunction_Static(){
		 System.out.println("JniTestFunction_Static_Called");
	 }
	 public void JniTestFunction(){
		 System.out.println("JniTestFunction_Called");
	 }
	 /////////////////////////
	 
     static {
         System.loadLibrary("game");
     }
}

调用结果:







Android 踩坑:同一个按钮,第一次有反应,第二次没反应 当页面通过replace()切换后,虽对象引用仍在,但生命周期已终结,回调注册被注销,导致结果“静默丢失”。修复关键在于避免页面销毁——改用add+hide/show叠放式切换,确保页面常驻、回调持续有效。核心教训:“对象活着”≠“可用”,复用实例时需警惕生命周期状态与注册机制的匹配。 阅读详情

相关推荐

android 调试java代码,Android程序调试方法介绍

静态调试适用于:通过打印变量的值来查看某一时刻值是否正确Toast(Snackbar)打印法一般的Android开发人员最爱的调试法,使用简便,仅需一行代码,轻松打印:Toast.makeText(MainActivity.this, "Toast调试", Toast.LENGTH_SHORT).show();方便是挺方便的,不过有一点要注意:Android 5.0后,如果把「消息通知的权限」 关...

weixin_35838394的博客 473

Android applicationIdSuffix 详解

<think>我们需要根据用户提供的文章内容生成一个≤150字的摘要。文章标题是“Android applicationIdSuffix 详解”,内容很多,需要提炼核心要点。摘要应该涵盖applicationIdSuffix的作用、用法、效果和注意事项。注意字数限制。 思路:先概述概念和用途,再提基本用法和效果,最后点出注意事项。控制在150字以内。 草稿:applicationIdSuffix用于在Application ID后添加后缀,使同一代码库构建出不同包名的应用变体,实现多版本共存。可在build

wolf0706的专栏 264

Cocosd-x对Java进行调用测试代码

目前计划是这样的, 首先, 在Java代码中写两个测试的函数,JniTestFunction_Static, JniTestFunction. 话说,在VIM还不熟练的时候使用VIM真的是降低效率思密达。VIM和Emacs还是得会一个,考虑到Stalllman的固执己见,我还是觉得VIM更体贴一些。 JniHelper.h中定义了一个结构体JniMethodInfo和一个类

peigong_dh的专栏 595

Android 开发中,requestWindowFeature(Window.FEATURE_NO_TITLE); 对于隐藏默认的紫色的标题栏失效

Android 开发中,requestWindowFeature(Window.FEATURE_NO_TITLE); 对于隐藏默认的紫色的标题栏失效

weixin_52173250的博客 57

飞牛 NAS 远程访问实战:星空组网连接 Mac 与安卓,从 Compose 部署到 5G 验证

在 Mac 上装好飞牛虚拟机之后,通过局域网地址打开管理后台很方便。但换成手机移动数据,这个内网地址就不能照搬了。怎样让手机在外面也能访问这台 NAS?这次我用星空组网完成了一次实际接入:飞牛通过 Docker Compose 运行客户端,Mac 安装桌面客户端,安卓手机使用独立成员账号连接,最后在关闭 Wi-Fi 的情况下,通过 5G 打开飞牛登录页面。

稻草人 1万+

Android Compose 开发,使用 ConstraintLayout,但是引入的是旧的 ConstraintLayout

Android Compose 开发,使用 ConstraintLayout,但是引入的是旧的 ConstraintLayout

weixin_52173250的博客 39

Androidiot开发之猫脸识别

Android IoT猫脸识别功能,深度结合物联网设备通信能力与阿里云云端服务能力,通过标准化的设备指令交互、精准的正则数据解析、规范的云端事件拉取与本地化资源处理,稳定实现了猫咪人脸录入、删除、识别监测、事件图片留存、状态实时反馈等核心业务。整套方案逻辑清晰、异常适配完善、交互体验良好,代码可复用性与扩展性强,完整满足智能宠物IoT设备的猫脸识别业务需求,实现了移动端、设备端、云端三方的数据高效协同。目前只是简单测试阶段,没有处理多只猫咪的情况,是和硬件部门联调后固定放一只猫,当然在手机上把猫咪头像对着

u012556114的博客 236

android Binder 应用层开发 详解

android Binder 应用层开发 详解

maoning20080808的专栏 286

查立得万用查分安卓版(web环境+查询系统免安装单文件一键运行包)

查立得万用查分安卓版(web环境+查询系统免安装单文件一键运行包),也就是双击软件(单文件)就部署完成可以访问了。

易查薪 258

WebView 完整篇:从嵌入浏览器到JS Bridge,覆盖Android / iOS / 桌面三大端

WebView 完整篇:从嵌入浏览器到 JS Bridge,覆盖 Android / iOS / 桌面三大端 做混合应用或「套壳」工具时,最先碰到的词是 **WebView**:在原生窗口里嵌一个浏览器引擎,用 HTML/CSS/JS 画界面,必要时再和原生代码通话。很多人把它等同于「打开一个网页」,结果在权限、进程、更新、安全上踩坑。 本文把 **WebView 是什么、和系统浏览器有何不同、各平台实现、与原生通信、安全与性能** 讲全,并落到 Android、iOS/macOS、Windows、Linu

qq_35223473的博客 132

基于STM32的鱼缸水质检测系统

基于STM32与三传感器(DS18B20、SEN0189、PH-4502C)构建鱼缸水质监测系统,实现水温、浑浊度、pH实时监测与超标报警、自动换水及手机远程查看。

weixin_45732499的博客 201

【KMP】-KMP 项目commonMain、androidMain、iosMain 到底放什么?

Source Set职责commonMain所有目标共享:数据模型、Result 封装、业务规则、Repository、UseCase、网络逻辑、数据解析、表单校验Android Log、DataStore 实现、Android 平台信息、Android SDK 适配、Android 网络与存储实现iosMainiOS 日志、Keychain/NSUserDefaults 实现、Apple 平台信息、iOS SDK 适配、Apple Framework 调用

m0_61164038的博客 346

Android 系统层扫盲 05:Android 开机后发生了什么?从 Bootloader 到 Launcher

<think>我们只需要根据内容生成摘要,不超过150字。内容是关于Android开机流程的概述。摘要需简洁,涵盖关键阶段。</think>Android开机是一场接力赛:BootROM→Bootloader→Linux Kernel→init→Zygote→system_server→System Services→Launcher。init是用户空间启动总管,Zygote是预热好的ART/Java进程底座,通过fork产生system_server和App进程,SystemSer

Mark Wu 的博客 161

53 极物科技 | KNX协议 - CEMI报文帧格式详解

一句话概述:本文回答"CEMI帧每个字节是什么含义",CEMI(Common External Message Interface)是KNX报文在IP通道上传输的标准封装格式,看懂它就等于拿到了KNX报文的"解剖图"。 本文详解KNX CEMI报文帧格式:消息码、附加信息区、控制域、源/目的地址、NPDU与TPCI/APCI字段,配以L_Data帧逐字节示例与地址字节序换算,并给出代码级解析片段。

weixin_43951955的博客 323

AndroidKMP之网络请求

基于 **Kotlin Multiplatform + Compose Multiplatform (M3) + Ktor + MVI 架构** 实现跨平台玩 Android文章列表Demo,一套代码同时运行在 **Android、JVM 桌面、iOS、JS、WasmJs** 五个平台。 采用分层架构:`data数据实体`‑`net多平台网络工厂`‑`http仓库层Repository`‑`viewmodel(MVI)`‑`ui界面层`;利用`expect‑actual`完成平台差异化实现;`compo

u012556114的博客 216

Android 系统级失效问题 → 内核根因映射梳理

结合工作区本地内核源码节选(,Linux 6.18 主线)与 Android 17.0.0_r1 代码检索站https://xrefandroid.com/android-17.0.0_r1/xref/ 整理。:上层问题一旦变成"系统级失效",就会牵扯内核。不是 Java/业务逻辑本身错,而是它把Framework、HAL、native 服务一路推到最后落在 Linux / ACK / GKI / vendor 驱动或内核子系统上。

weixin_43228946的博客 68

App WebView 加载 M3U8 流媒体踩坑,安卓 iOS 混合开发播放异常定位

WebView内嵌HLS播放常因内核配置、Cookie策略、混合内容拦截、硬件解码等与手机浏览器表现不一致,导致黑屏、鉴权失效、直播停刷等问题。排查应先以原生浏览器做基准测试,区分流源或WebView配置问题;安卓需检查WebSettings及Cookie,iOS注意页面节流与实例销毁。建议开启必要配置、升级HTTPS

2608_96729545的博客 228

Android 开发问题:android.permission.CAMERA...duplicated with element declared at

Android 开发问题:android.permission.CAMERA...duplicated with element declared at

weixin_52173250的博客 43

穿山甲 + 腾讯短剧短视频聚合广告平台|Android+SpringBoot+Vue+Docker 完整部署指南

<think>我们只需要根据用户提供的长文生成不超过150字的摘要。摘要要简洁概括主要内容和价值。注意用户要求“根据以下内容,生成≤150字的文章摘要”,所以我们需要提炼核心:短剧短视频聚合广告平台源码,支持多广告渠道,包含Android、后端、Vue管理后台,需要替换占位符参数,提供部署流程和排查。字数要严格限制。</think>本文介绍一套短剧短视频聚合广告平台源码,支持穿山甲、腾讯等广告渠道。文章完整梳理Android客户端、SpringBoot后端、Vue管理后台的架构与部署

2603_96706877的博客 192
上一篇: Cocos2d-x调用Java
下一篇: Cocos2d-x调用Java最终实例代码
垃圾桶
博客等级 码龄14年 20粉丝 18原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值