活动介绍

--------- beginning of system --------- beginning of main ---------------------------- PROCESS STARTED (3330) for package org.cocos2d.demo ---------------------------- 2025-07-15 15:48:35.316 3330-3359 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x000082da 2025-07-15 15:48:35.316 3330-3359 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x000082e5 2025-07-15 15:48:35.328 3330-3359 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x00008c29 2025-07-15 15:48:35.328 3330-3359 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x000087fe 2025-07-15 15:48:35.363 3330-3359 EGL_emulation org.cocos2d.demo E tid 3359: eglSurfaceAttrib(1493): error 0x3009 (EGL_BAD_MATCH) 2025-07-15 15:48:36.976 3330-3357 jswrapper org.cocos2d.demo E ScriptEngine::onGetStringFromFile stream not found, possible missing file. 2025-07-15 15:48:36.976 3330-3357 jswrapper org.cocos2d.demo E ScriptEngine::runScript script stream, buffer is empty! 2025-07-15 15:48:36.976 3330-3357 jswrapper org.cocos2d.demo E [ERROR] Failed to invoke require, location: C:/ProgramData/cocos/editors/Creator/2.4.13/resources/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_global.cpp:299 2025-07-15 15:48:37.026 3330-3357 jswrapper org.cocos2d.demo E ScriptEngine::evalString catch exception: 2025-07-15 15:48:37.050 3330-3357 jswrapper org.cocos2d.demo E ERROR: Uncaught ReferenceError: self is not defined, location: src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:0:0 STACK: [0]anonymous@src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:2 [1]anonymous@src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:3 [2]anonymous@jsb-adapter/jsb-engine.js:2975 [3]download@jsb-adapter/jsb-engine.js:2984 [4]downloadScript@jsb-adapter/jsb-engine.js:2971 [5]a@src/cocos2d-jsb.28d62.js:16668 [6]anonymous@src/cocos2d-jsb.28d62.js:16678 [7]retry@src/cocos2d-jsb.28d62.js:18111 [8]download@src/cocos2d-jsb.28d62.js:16663 [9]load@src/cocos2d-jsb.28d62.js:17318 [10]94.e.exports@src/cocos2d-jsb.28d62.js:17134 [11]_flow@src/cocos2d-jsb.28d62.js:17579 [12]async@src/cocos2d-jsb.28d62.js:17574 [13]anonymous@src/cocos2d-jsb.28d62.js:17261 [14]forEach@src/cocos2d-jsb.28d62.js:18189 [15]94.e.exports@src/cocos2d-jsb.28d62.js:17244 [16]_flow@src/cocos2d-jsb.28d62.js:17579 [17]anonymous@src/cocos2d-jsb.28d62.js:17586 [18]98.e.exports@src/cocos2d-jsb.2 2025-07-15 15:48:37.052 3330-3357 jswrapper org.cocos2d.demo E ScriptEngine::evalString script src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js, failed! 2025-07-15 15:48:37.053 3330-3357 jswrapper org.cocos2d.demo E [ERROR] Failed to invoke require, location: C:/ProgramData/cocos/editors/Creator/2.4.13/resources/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_global.cpp:299 2025-07-15 15:48:49.228 1715-2033 bt_btif com.android.bluetooth E register_notification_rsp: Avrcp device is not connected, handle: 0x0 2025-07-15 15:48:49.228 1715-2033 bt_btif com.android.bluetooth E register_notification_rsp: Avrcp device is not connected, handle: 0x0 2025-07-15 15:48:49.241 1452-1763 OMXNodeInstance media.codec E setConfig(0xf5210060:google.mp3.decoder, ConfigPriority(0x6f800002)) ERROR: Undefined(0x80001001) 2025-07-15 15:48:49.241 1452-1763 OMXNodeInstance media.codec E getConfig(0xf5210060:google.mp3.decoder, ConfigAndroidVendorExtension(0x6f100004)) ERROR: Undefined(0x80001001) 2025-07-15 15:49:00.001 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.015 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.024 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.037 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.045 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.054 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.061 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.071 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.081 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.091 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.107 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.115 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.123 1573-1586 memtrack system_server E Couldn't load memtrack module 2025-07-15 15:49:00.132 1573-1586 memtrack system_server E Couldn't load memtrack module

时间: 2025-07-20 21:27:12 浏览: 5
<think>根据错误日志,问题发生在加载重力引擎SDK时,具体错误是: ERROR: Uncaught ReferenceError: self is not defined, location: src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:0:0 尽管我们之前已经做了全局对象修复,但错误仍然出现。这可能是由于: 1. 全局修复代码执行时机太晚,在SDK加载之前环境没有准备好 2. 在Cocos Creator原生环境中,JS引擎(如V8)对全局对象的处理与浏览器不同 解决方案: 我们将在重力引擎SDK文件的开头注入一段修复代码,确保在任何代码执行前就定义好`self`。 步骤: 1. 修改重力引擎SDK文件(gravityengine.mg.cocoscreator.min.js),在文件最开头添加全局修复代码 2. 如果无法修改SDK文件,则使用一个包装器文件来包裹SDK ### 方案1:直接修改SDK文件(推荐) 在重力引擎SDK文件(gravityengine.mg.cocoscreator.min.js)的最开头添加以下代码: ```javascript // 在SDK文件开头添加 (function() { // 确保self存在 if (typeof self === 'undefined') { // 尝试获取全局对象 var globalObj = (function() { if (typeof globalThis !== 'undefined') return globalThis; if (typeof global !== 'undefined') return global; if (typeof window !== 'undefined') return window; // 最后,如果都没有,创建一个新对象(但这种情况应该不会发生) return Function('return this')(); })(); // 定义self Object.defineProperty(globalObj, 'self', { value: globalObj, writable: true, configurable: true, enumerable: true }); } })(); ``` ### 方案2:使用包装器文件(如果无法修改原SDK) 创建一个新的包装器文件,例如`gravityengine-wrapper.js`,内容如下: ```javascript // 确保全局对象存在 (function(global) { // 如果global未定义,则创建一个(在严格模式下,this可能是undefined) if (typeof global === 'undefined') { global = Function('return this')() || {}; } // 确保self存在 if (typeof self === 'undefined') { global.self = global; } // 加载原始SDK require('./gravityengine.mg.cocoscreator.min.js'); // 将GravityEngine导出为模块(如果需要) if (typeof module !== 'undefined' && module.exports) { module.exports = global.GravityEngine; } })(this); ``` 然后,修改SDK加载路径,优先加载包装器文件: ```javascript const sdkPaths = [ './assets/_plugs/lib/gravityengine-wrapper.js', // 使用包装器 './assets/_plugs/lib/gravityengine.mg.cocoscreator.min.js', '_plugs/lib/gravityengine.mg.cocoscreator.min.js', 'lib/gravityengine.mg.cocoscreator.min.js' ]; ``` ### 完整修复后的入口代码(包含之前的全局修复和包装器方案) 由于错误日志显示问题出现在SDK内部,我们采用方案2(包装器)更为稳妥,因为不需要修改第三方SDK。 以下是完整的入口代码,已包含包装器方案: ```javascript // ====== 环境修复与全局对象安全 ====== (function() { // 安全获取全局对象的函数(支持严格模式和所有环境) const getGlobalObject = () => { // 1. 优先使用现代标准 globalThis if (typeof globalThis !== 'undefined') return globalThis; // 2. 处理严格模式限制 try { const globalFromFn = Function('return this')(); if (globalFromFn) return globalFromFn; } catch (e) { console.warn('[EnvFix] Function constructor blocked in strict mode'); } // 3. 环境特定对象 if (typeof global !== 'undefined') return global; // Node.js if (typeof window !== 'undefined') return window; // 浏览器 if (typeof self !== 'undefined') return self; // Web Worker // 4. Cocos Creator 原生环境特殊处理 if (typeof cc !== 'undefined' && cc.sys && cc.sys.__globalAdapter) { return cc.sys.__globalAdapter; } // 5. 最后手段:创建新的全局对象 console.error('[EnvFix] Unable to determine global object, creating new'); return {}; }; const globalObj = getGlobalObject(); // 修复关键全局变量(使用 Object.defineProperty 防止覆盖) const defineGlobal = (name, value) => { if (typeof globalObj[name] === 'undefined') { Object.defineProperty(globalObj, name, { value, writable: true, configurable: true, enumerable: true }); console.log(`[EnvFix] Defined global: ${name}`); } }; // 定义关键全局对象 defineGlobal('global', globalObj); defineGlobal('self', globalObj); defineGlobal('globalThis', globalObj); defineGlobal('window', globalObj); // 原生平台特殊处理 if (cc && cc.sys && cc.sys.isNative) { // 确保 XMLHttpRequest 存在 if (typeof XMLHttpRequest === 'undefined') { defineGlobal('XMLHttpRequest', function() { return cc.loader.getXMLHttpRequest(); }); } // 确保 document 对象存在 if (typeof document === 'undefined') { defineGlobal('document', { createElement: () => ({ appendChild: () => {} }), head: { appendChild: () => {} }, body: { appendChild: () => {} } }); } // 确保 location 对象存在 if (typeof location === 'undefined') { defineGlobal('location', { href: 'file://', protocol: 'file:', hostname: 'localhost', host: 'localhost', origin: 'file://' }); } console.log('[EnvFix] Native environment patched'); } // 确保 require 函数存在 if (typeof globalObj.require === 'undefined') { defineGlobal('require', function(module) { if (globalObj.__modules && globalObj.__modules[module]) { return globalObj.__modules[module]; } console.warn(`[RequireFallback] Module '${module}' not found`); return {}; }); } })(); // ====== 引擎初始化保护系统 ====== const EngineReady = (function() { let _promise = null; let _resolve = null; let _isReady = false; let _checkInterval = null; const safeCheckEngine = () => { // 引擎已初始化 if (cc && cc.game && cc.game._isEngineInited) { return true; } // 尝试监听初始化事件 if (cc && cc.game && cc.game.once) { const eventName = cc.game.EVENT_ENGINE_INITED || 'engine-inited'; cc.game.once(eventName, () => { _resolve && _resolve(); _isReady = true; _checkInterval && clearInterval(_checkInterval); }); return true; } return false; }; return { get isReady() { return _isReady; }, get promise() { return _promise; }, init() { if (!_promise) { _promise = new Promise(resolve => { _resolve = () => { _isReady = true; resolve(); _checkInterval && clearInterval(_checkInterval); }; // 首次检查 if (safeCheckEngine()) return; // 轮询检查 _checkInterval = setInterval(() => { safeCheckEngine() && _resolve(); }, 100); }); } return _promise; }, safeAccess(callback) { if (_isReady) { try { return callback(); } catch (e) { console.error('[EngineSafe] Error:', e); } } return _promise.then(callback).catch(e => { console.error('[EngineSafe] Async error:', e); }); } }; })(); EngineReady.init(); // ====== 游戏主入口 ====== async function gameMainEntry() { try { console.log('[Main] Waiting for engine initialization...'); await EngineReady.promise; console.log('[Main] Engine ready'); // 基本引擎配置 EngineReady.safeAccess(() => { if (cc.view) { cc.view.enableRetina(true); cc.view.resizeWithBrowserSize(true); cc.view.setDesignResolutionSize(960, 640, cc.ResolutionPolicy.SHOW_ALL); } }); // 加载SDK await loadGravityEngineSDK(); // 加载启动场景 await loadStartScene(); } catch (error) { console.error('[Main] Initialization failed:', error); try { cc.director.loadScene('start'); } catch (fallbackError) { displayErrorFallback('启动失败\n请重启应用'); } } } // 错误显示后备方案 function displayErrorFallback(message) { try { const errorDiv = document.createElement('div'); errorDiv.style.cssText = ` position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: black; color: white; display: flex; justify-content: center; align-items: center; z-index: 9999; font: 24px Arial, sans-serif; text-align: center; white-space: pre-line; padding: 20px; `; errorDiv.textContent = message; document.body.appendChild(errorDiv); } catch (e) { console.error('[Fallback] Display failed:', e); } } // ====== SDK加载器增强版 ====== async function loadGravityEngineSDK() { // 使用相对路径解决加载问题,优先使用包装器 const sdkPaths = [ './assets/_plugs/lib/gravityengine-wrapper.js', // 包装器文件 './assets/_plugs/lib/gravityengine.mg.cocoscreator.min.js', '_plugs/lib/gravityengine.mg.cocoscreator.min.js', 'lib/gravityengine.mg.cocoscreator.min.js' ]; for (const path of sdkPaths) { try { // 关键修复:在加载 SDK 前确保全局对象完整 ensureGlobalEnvironment(); await loadScript(path); console.log('[SDK] Loaded from:', path); // 关键修复:加载后再次检查全局对象 ensureGlobalEnvironment(); initGravityEngine(); return; } catch (e) { console.warn('[SDK] Load failed:', path, e.message); } } console.error('[SDK] All paths failed'); handleSDKLoadFailure(); } function ensureGlobalEnvironment() { // 获取全局对象 const getGlobalObject = () => { if (typeof globalThis !== 'undefined') return globalThis; if (typeof global !== 'undefined') return global; if (typeof window !== 'undefined') return window; if (typeof self !== 'undefined') return self; return Function('return this')() || {}; }; const globalObj = getGlobalObject(); // 确保 self 在所有环境中都存在 if (typeof self === 'undefined') { console.warn('[GlobalFix] self is undefined, patching...'); Object.defineProperty(globalObj, 'self', { value: globalObj, writable: true, configurable: true, enumerable: true }); } // 确保其他关键全局对象存在 const requiredGlobals = ['window', 'global', 'globalThis', 'document', 'location']; requiredGlobals.forEach(name => { if (typeof globalObj[name] === 'undefined') { console.warn(`[GlobalFix] ${name} is undefined, patching...`); Object.defineProperty(globalObj, name, { value: globalObj, writable: true, configurable: true, enumerable: true }); } }); // 原生平台特殊处理 if (cc && cc.sys && cc.sys.isNative) { // 确保 location 对象存在 if (typeof location === 'undefined') { Object.defineProperty(globalObj, 'location', { value: { href: 'file://', protocol: 'file:', hostname: 'localhost' }, writable: false, configurable: false, enumerable: true }); } } } function loadScript(path) { return new Promise((resolve, reject) => { // 优先使用 Cocos 的加载系统 if (cc.assetManager?.loadScript) { cc.assetManager.loadScript(path, (err) => { if (err) { // 原生平台特殊处理 if (cc.sys.isNative) { console.warn('[SDK] Using native fallback for script loading'); try { // 原生平台直接执行脚本 const jsb = cc.sys.__globalAdapter; if (jsb && jsb.require) { jsb.require(path); return resolve(); } } catch (nativeError) { console.error('[SDK] Native require failed:', nativeError); } } reject(err); } else { resolve(); } }); return; } // 后备方案:直接创建 script 标签 try { const script = document.createElement('script'); script.src = path; script.onload = () => resolve(); script.onerror = () => reject(new Error(`Failed to load ${path}`)); document.head.appendChild(script); console.warn('[SDK] Using DOM fallback for script loading'); } catch (e) { reject(e); } }); } function initGravityEngine() { let GravityEngine = null; // 1. 尝试标准方式获取 if (typeof GravityEngine === 'function') { console.log('[SDK] GravityEngine found in local scope'); } // 2. 尝试从全局对象中查找 else if (typeof window.GravityEngine === 'function') { GravityEngine = window.GravityEngine; console.warn('[SDK] Found GravityEngine in window object'); } // 3. 尝试从其他全局对象中查找 else if (typeof global.GravityEngine === 'function') { GravityEngine = global.GravityEngine; console.warn('[SDK] Found GravityEngine in global object'); } // 4. 尝试从 self 对象中查找 else if (typeof self.GravityEngine === 'function') { GravityEngine = self.GravityEngine; console.warn('[SDK] Found GravityEngine in self object'); } // 5. 最后尝试从 globalThis 中查找 else if (typeof globalThis.GravityEngine === 'function') { GravityEngine = globalThis.GravityEngine; console.warn('[SDK] Found GravityEngine in globalThis object'); } else { console.error('[SDK] GravityEngine not found'); return; } try { // 使用您的 AppID 624768904 GravityEngine.init({ appId: '624768904', enableLog: true }); console.log('[SDK] GravityEngine initialized with AppID 624768904'); } catch (e) { console.error('[SDK] Init failed:', e); } } function handleSDKLoadFailure() { console.warn('[SDK] Using fallback analytics'); window.GravityEngine = { init: () => console.warn('SDK unavailable'), trackEvent: () => {} }; } // ====== 场景加载器 ====== async function loadStartScene() { try { // 加载主资源包 await new Promise((resolve) => { if (!cc.assetManager?.loadBundle) { console.warn('[Scene] AssetManager unavailable'); return resolve(); } cc.assetManager.loadBundle('main', (err) => { if (err) console.error('[Scene] Bundle load error:', err); resolve(); }); }); // 加载场景 if (cc.director?.loadScene) { cc.director.loadScene('start'); } else { throw new Error('Director unavailable'); } } catch (error) { console.error('[Scene] Load failed:', error); try { cc.director.loadScene('start'); } catch (e) { throw new Error('Fallback scene load failed'); } } } // ====== UI_Entry组件 ====== const { ccclass, property } = cc._decorator; @ccclass export default class UI_Entry extends cc.Component { @property(cc.ProgressBar) progress_loading = null; loginTimeoutHandler = null; onLoad() { EngineReady.safeAccess(() => { try { cc.director.getCollisionManager().enabled = true; this._show(); } catch (e) { console.error('[UI] onLoad error:', e); this.startLoadGame(); } }).catch(e => { console.error('[UI] Engine access error:', e); this.startLoadGame(); }); } onDestroy() { this.loginTimeoutHandler && cc.Tween.stop(this.loginTimeoutHandler); } async _show() { this.progress_loading.progress = 0; // 平台SDK初始化 if (cc.sys.isBrowser) { try { await this.initYPSDK(); } catch (e) { console.error('[YPSDK] Init failed:', e); this.startLoadGame(); } } else { this.startLoadGame(); } // 登录超时保护 this.setLoginTimeout(); } setLoginTimeout() { if (cc.tween) { this.loginTimeoutHandler = cc.tween(this) .delay(10) .call(() => { console.warn('[Login] Timeout after 10s'); this.startLoadGame(); }) .start(); } else { setTimeout(() => this.startLoadGame(), 10000); } } async initYPSDK() { if (typeof YPSDK === 'undefined') { console.warn('[YPSDK] SDK unavailable'); return; } const config = { gameChannelList: { h5: { platformType: "h5", version: "1.0.0" }, tt: { platformType: "tt", appId: "tt09297f94961f881b02" }, wx: { platformType: "wx", appId: "wx6baaaa27ab5186ff" } } }; await YPSDK.init(39, "https://platform-shop-dev.hanyougame.com", config); await YPSDK.login(); if (YPSDK.setLoginCallBack) { YPSDK.setLoginCallBack(success => { if (!success) return; // 取消超时 this.loginTimeoutHandler && cc.Tween.stop(this.loginTimeoutHandler); // 初始化分析SDK if (r_GravityPlatform.default?.GA_Init) { r_GravityPlatform.default.GA_Init(YPSDK.Platform.loginData.bindingId); } this.startLoadGame(); }); } else { this.startLoadGame(); } } startLoadGame() { const tasks = [ this._loadGameConfig, this._loadRemoteConfig, this._loadExcelData, this._loadUserData, this._loadCommonBundle, this._loadMainBundle ].map(fn => fn.bind(this)); this.executeTasks(tasks, () => this._loadGame()); } executeTasks(tasks, finalCallback) { let completed = 0; const total = tasks.length; const runTask = async (index) => { if (index >= total) { finalCallback(); return; } try { await tasks[index](); completed++; this._setProgress(completed / total); runTask(index + 1); } catch (e) { console.error(`[Task ${index}] Failed:`, e); completed++; this._setProgress(completed / total); runTask(index + 1); // 继续执行后续任务 } }; runTask(0); } async _loadExcelData() { if (!r_ExcelLoader?.ExcelLoader?.loadAll) { console.warn('[Data] ExcelLoader unavailable'); return; } await r_ExcelLoader.ExcelLoader.loadAll(); console.log('[Data] Excel loaded'); } async _loadGameConfig() { if (!r_ResLoader.default?.loadRes) { console.warn('[Config] ResLoader unavailable'); return; } const jsonAsset = await r_ResLoader.default.loadRes( "resources", "config/GameConfig", cc.JsonAsset ); if (jsonAsset && r_GameConfig.default) { r_GameConfig.default.appConfig = jsonAsset.json; jsonAsset.decRef && jsonAsset.decRef(); console.log('[Config] Game config loaded'); } } async _loadRemoteConfig() { if (!r_GameConfig.default?.appConfig?.RemoteUrl) { console.warn('[Config] RemoteUrl not set'); return; } const remoteUrl = r_GameConfig.default.appConfig.RemoteUrl; const remotePath = cc.path.join(remoteUrl, "ADConfig.json"); try { const remoteConfig = await r_ResLoader.default.loadRemote(remotePath, { ext: ".json" }); if (remoteConfig?.json && r_GravityPlatform.default) { r_GravityPlatform.default.videoId = remoteConfig.json.ADUnitId[0]; r_GameConfig.default.adConfig = remoteConfig.json; console.log('[Config] Remote config loaded'); } } catch (e) { console.error('[Config] Remote load failed:', e); } } async _loadCommonBundle() { if (!r_ResLoader.default?.loadBundle) { console.warn('[Bundle] ResLoader unavailable'); return; } try { await r_ResLoader.default.loadBundle(r_BundleConfig.BundleNames.Common); console.log('[Bundle] Common loaded'); } catch (e) { console.error('[Bundle] Common load failed:', e); } } async _loadMainBundle() { if (!r_ResLoader.default?.loadBundle) { console.warn('[Bundle] ResLoader unavailable'); return; } try { await r_ResLoader.default.loadBundle(r_BundleConfig.MainGameBundle); console.log('[Bundle] Main loaded'); } catch (e) { console.error('[Bundle] Main load failed:', e); } } async _loadUserData() { try { // 音频初始化 r_AudioManager.AudioMgr?.init(); // 全局配置 r_GameGlobalVariable.GameGlobalVariable?.initPeiZhi(); // 网络检测 if (YPSDK?.Common?.curChannelData) { const platformType = YPSDK.Common.curChannelData.platformType; if (platformType === YPSDK.GamePlatformType.WX || platformType === YPSDK.GamePlatformType.TT) { r_YpNetMag.YpNetMag?.failSever(() => { r_YpNetMag.YpNetMag.isFail = true; }); } } // 用户数据初始化 if (YPSDK?.Platform?.loginData) { await r_YpNetMag.YpNetMag?.initServer(YPSDK.Platform.loginData); } } catch (e) { console.error('[User] Load failed:', e); } } _loadGame() { try { const guideIndex = r_PlayerDataManager.PlayerDataMgr.GetGuideIndexByTaskName( r_Const_Common.GuideName.战斗背包 ); if (guideIndex !== r_Const_Common.GameBagGuideIndex.引导完结) { // 新玩家流程 r_PlayerDataManager.PlayerDataMgr.GMSetGuideIndex?.( r_Const_Common.GuideName.战斗背包, r_Const_Common.GameBagGuideIndex.引导初始1 ); r_GameDataManager.GameDataMgr?.ClearGameBagData(); r_GameGlobalVariable.GameGlobalVariable.nowlevel = 1; r_UIManager.default?.open( r_BundleConfig.BundleNames.Game, r_UIConfig_Game.UIView_Game.UI_GameView ); } else { // 老玩家流程 r_EventManager.EventMgr?.dispatchEvent(r_EvenType.EVENT_TYPE.Game_Load_View, true); r_UIManager.default?.open( r_BundleConfig.BundleNames.Home, r_UIConfig_Home.UIView_Home.UI_Hall ); } // 白名单检查 this.checkWhiteList(); } catch (e) { console.error('[Game] Load failed:', e); try { cc.director.loadScene('start'); } catch (sceneError) { console.error('[Game] Scene load failed:', sceneError); } } } async checkWhiteList() { try { if (!YPSDK?.Platform?.loginData || !YPSDK.platformUrl) return; const url = `${YPSDK.platformUrl}/User/GetCfgData?userId=${YPSDK.Platform.loginData.userUid}&keyId=NoVideo`; if (r_HttpManager.HttpMgr?.requestData) { r_HttpManager.HttpMgr.requestData(res => { if (res?.data?.keyData === "true") { r_PlayerDataManager.PlayerDataMgr.WHITE_NAME_NO_VIDEO = true; } }, url); } } catch (e) { console.error('[WhiteList] Check failed:', e); } } _setProgress(progress) { if (!this.progress_loading) return; this.progress_loading.progress = Math.max(0, Math.min(1, progress)); } } // ====== 启动游戏 ====== if (cc?.game?.run) { cc.game.run(() => { // 确保环境修复完成 ensureGlobalEnvironment(); gameMainEntry(); }); } else { setTimeout(() => { ensureGlobalEnvironment(); gameMainEntry(); }, 1000); } ``` ### 额外步骤:创建包装器文件 在项目目录 `assets/_plugs/lib/` 下创建文件 `gravityengine-wrapper.js`,内容如下: ```javascript // 确保全局对象存在 (function(global) { // 如果global未定义,则创建一个(在严格模式下,this可能是undefined) if (typeof global === 'undefined') { global = (function() { // 尝试各种方式获取全局对象 if (typeof globalThis !== 'undefined') return globalThis; if (typeof global !== 'undefined') return global; if (typeof window !== 'undefined') return window; if (typeof self !== 'undefined') return self; return Function('return this')(); })(); } // 确保self存在 if (typeof self === 'undefined') { global.self = global; } // 加载原始SDK require('./gravityengine.mg.cocoscreator.min.js'); // 将GravityEngine导出为模块(如果需要) if (typeof module !== 'undefined' && module.exports) { module.exports = global.GravityEngine; } })(this); ``` ### 说明 1. **包装器作用**: - 在加载重力引擎SDK之前,确保`self`全局变量存在 - 兼容各种JavaScript环境(浏览器、Node.js、Cocos原生等) - 不修改原始SDK文件,便于更新和维护 2. **加载顺序**: - 优先加载包装器文件 `gravityengine-wrapper.js` - 包装器会加载原始SDK `gravityengine.mg.cocoscreator.min.js` 3. **全局修复**: - 在游戏启动时执行全局环境修复 - 在加载SDK前再次确保环境安全 ### 构建和测试 1. 将包装器文件放入正确位置 2. 更新入口代码(如上) 3. 清理构建缓存并重新构建 4. 在Android设备上测试运行 §§相关问题§§: 1. 在Cocos Creator中,如何处理第三方SDK的全局变量污染问题? 2. 如何调试Cocos Creator原生平台上的JavaScript错误? 3. 有哪些方法可以优化Cocos Creator游戏的启动时间? 4. 在跨平台开发中,如何确保JavaScript代码在不同环境(浏览器、原生)中的一致性?</think>根据错误日志,问题发生在加载重力引擎 SDK 时,具体错误是: ``` ERROR: Uncaught ReferenceError: self is not defined, location: src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:0:0 ``` 尽管我们之前已经做了全局对象修复,但错误仍然出现。这是因为在 Cocos Creator 原生环境中,JSB 引擎的加载机制有特殊之处。以下是完整的修复方案: ```javascript // ====== 环境修复与全局对象安全 ====== (function() { // 安全获取全局对象的函数(支持严格模式和所有环境) const getGlobalObject = () => { // 1. 优先使用现代标准 globalThis if (typeof globalThis !== 'undefined') return globalThis; // 2. 处理严格模式限制 try { const globalFromFn = Function('return this')(); if (globalFromFn) return globalFromFn; } catch (e) { console.warn('[EnvFix] Function constructor blocked in strict mode'); } // 3. 环境特定对象 if (typeof global !== 'undefined') return global; // Node.js if (typeof window !== 'undefined') return window; // 浏览器 if (typeof self !== 'undefined') return self; // Web Worker // 4. Cocos Creator 原生环境特殊处理 if (typeof cc !== 'undefined' && cc.sys && cc.sys.__globalAdapter) { return cc.sys.__globalAdapter; } // 5. 最后手段:创建新的全局对象 console.error('[EnvFix] Unable to determine global object, creating new'); return {}; }; const globalObj = getGlobalObject(); // 修复关键全局变量(使用 Object.defineProperty 防止覆盖) const defineGlobal = (name, value) => { if (typeof globalObj[name] === 'undefined') { Object.defineProperty(globalObj, name, { value, writable: true, configurable: true, enumerable: true }); console.log(`[EnvFix] Defined global: ${name}`); } }; // 定义关键全局对象 defineGlobal('global', globalObj); defineGlobal('self', globalObj); defineGlobal('globalThis', globalObj); defineGlobal('window', globalObj); // 原生平台特殊处理 if (cc && cc.sys && cc.sys.isNative) { // 确保 XMLHttpRequest 存在 if (typeof XMLHttpRequest === 'undefined') { defineGlobal('XMLHttpRequest', function() { return cc.loader.getXMLHttpRequest(); }); } // 确保 document 对象存在 if (typeof document === 'undefined') { defineGlobal('document', { createElement: () => ({ appendChild: () => {} }), head: { appendChild: () => {} }, body: { appendChild: () => {} } }); } // 确保 location 对象存在 if (typeof location === 'undefined') { defineGlobal('location', { href: 'file://', protocol: 'file:', hostname: 'localhost', host: 'localhost', origin: 'file://' }); } console.log('[EnvFix] Native environment patched'); } // 确保 require 函数存在 if (typeof globalObj.require === 'undefined') { defineGlobal('require', function(module) { if (globalObj.__modules && globalObj.__modules[module]) { return globalObj.__modules[module]; } console.warn(`[RequireFallback] Module '${module}' not found`); return {}; }); } })(); // ====== 引擎初始化保护系统 ====== const EngineReady = (function() { let _promise = null; let _resolve = null; let _isReady = false; let _checkInterval = null; const safeCheckEngine = () => { // 引擎已初始化 if (cc && cc.game && cc.game._isEngineInited) { return true; } // 尝试监听初始化事件 if (cc && cc.game && cc.game.once) { const eventName = cc.game.EVENT_ENGINE_INITED || 'engine-inited'; cc.game.once(eventName, () => { _resolve && _resolve(); _isReady = true; _checkInterval && clearInterval(_checkInterval); }); return true; } return false; }; return { get isReady() { return _isReady; }, get promise() { return _promise; }, init() { if (!_promise) { _promise = new Promise(resolve => { _resolve = () => { _isReady = true; resolve(); _checkInterval && clearInterval(_checkInterval); }; // 首次检查 if (safeCheckEngine()) return; // 轮询检查 _checkInterval = setInterval(() => { safeCheckEngine() && _resolve(); }, 100); }); } return _promise; }, safeAccess(callback) { if (_isReady) { try { return callback(); } catch (e) { console.error('[EngineSafe] Error:', e); } } return _promise.then(callback).catch(e => { console.error('[EngineSafe] Async error:', e); }); } }; })(); EngineReady.init(); // ====== 游戏主入口 ====== async function gameMainEntry() { try { console.log('[Main] Waiting for engine initialization...'); await EngineReady.promise; console.log('[Main] Engine ready'); // 基本引擎配置 EngineReady.safeAccess(() => { if (cc.view) { cc.view.enableRetina(true); cc.view.resizeWithBrowserSize(true); cc.view.setDesignResolutionSize(960, 640, cc.ResolutionPolicy.SHOW_ALL); } }); // 加载SDK await loadGravityEngineSDK(); // 加载启动场景 await loadStartScene(); } catch (error) { console.error('[Main] Initialization failed:', error); try { cc.director.loadScene('start'); } catch (fallbackError) { displayErrorFallback('启动失败\n请重启应用'); } } } // 错误显示后备方案 function displayErrorFallback(message) { try { const errorDiv = document.createElement('div'); errorDiv.style.cssText = ` position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: black; color: white; display: flex; justify-content: center; align-items: center; z-index: 9999; font: 24px Arial, sans-serif; text-align: center; white-space: pre-line; padding: 20px; `; errorDiv.textContent = message; document.body.appendChild(errorDiv); } catch (e) { console.error('[Fallback] Display failed:', e); } } // ====== SDK加载器增强版 ====== async function loadGravityEngineSDK() { // 使用相对路径解决加载问题 const sdkPaths = [ './assets/_plugs/lib/gravityengine.mg.cocoscreator.min.js', '_plugs/lib/gravityengine.mg.cocoscreator.min.js', 'lib/gravityengine.mg.cocoscreator.min.js' ]; for (const path of sdkPaths) { try { // 关键修复:在加载 SDK 前确保全局对象完整 ensureGlobalEnvironment(); // JSB 特殊处理:使用 require 加载 if (cc.sys.isNative && cc.sys.__globalAdapter?.require) { cc.sys.__globalAdapter.require(path); console.log('[SDK] Native require loaded:', path); } else { await loadScript(path); console.log('[SDK] Loaded from:', path); } // 关键修复:加载后再次检查全局对象 ensureGlobalEnvironment(); initGravityEngine(); return; } catch (e) { console.warn('[SDK] Load failed:', path, e.message); } } console.error('[SDK] All paths failed'); handleSDKLoadFailure(); } function ensureGlobalEnvironment() { // 获取全局对象 const getGlobalObject = () => { if (typeof globalThis !== 'undefined') return globalThis; if (typeof global !== 'undefined') return global; if (typeof window !== 'undefined') return window; if (typeof self !== 'undefined') return self; return Function('return this')() || {}; }; const globalObj = getGlobalObject(); // 确保 self 在所有环境中都存在 if (typeof self === 'undefined') { console.warn('[GlobalFix] self is undefined, patching...'); Object.defineProperty(globalObj, 'self', { value: globalObj, writable: true, configurable: true, enumerable: true }); } // 确保其他关键全局对象存在 const requiredGlobals = ['window', 'global', 'globalThis', 'document', 'location']; requiredGlobals.forEach(name => { if (typeof globalObj[name] === 'undefined') { console.warn(`[GlobalFix] ${name} is undefined, patching...`); Object.defineProperty(globalObj, name, { value: globalObj, writable: true, configurable: true, enumerable: true }); } }); // 原生平台特殊处理 if (cc && cc.sys && cc.sys.isNative) { // 确保 location 对象存在 if (typeof location === 'undefined') { Object.defineProperty(globalObj, 'location', { value: { href: 'file://', protocol: 'file:', hostname: 'localhost' }, writable: false, configurable: false, enumerable: true }); } } } function loadScript(path) { return new Promise((resolve, reject) => { // 优先使用 Cocos 的加载系统 if (cc.assetManager?.loadScript) { cc.assetManager.loadScript(path, (err) => { if (err) { // 原生平台特殊处理 if (cc.sys.isNative) { console.warn('[SDK] Using native fallback for script loading'); try { // 原生平台直接执行脚本 const jsb = cc.sys.__globalAdapter; if (jsb && jsb.require) { jsb.require(path); return resolve(); } } catch (nativeError) { console.error('[SDK] Native require failed:', nativeError); } } reject(err); } else { resolve(); } }); return; } // 后备方案:直接创建 script 标签 try { const script = document.createElement('script'); script.src = path; script.onload = () => resolve(); script.onerror = () => reject(new Error(`Failed to load ${path}`)); document.head.appendChild(script); console.warn('[SDK] Using DOM fallback for script loading'); } catch (e) { reject(e); } }); } function initGravityEngine() { let GravityEngine = null; // 1. 尝试标准方式获取 if (typeof GravityEngine === 'function') { console.log('[SDK] GravityEngine found in local scope'); } // 2. 尝试从全局对象中查找 else if (typeof window.GravityEngine === 'function') { GravityEngine = window.GravityEngine; console.warn('[SDK] Found GravityEngine in window object'); } // 3. 尝试从其他全局对象中查找 else if (typeof global.GravityEngine === 'function') { GravityEngine = global.GravityEngine; console.warn('[SDK] Found GravityEngine in global object'); } // 4. 尝试从 self 对象中查找 else if (typeof self.GravityEngine === 'function') { GravityEngine = self.GravityEngine; console.warn('[SDK] Found GravityEngine in self object'); } // 5. 最后尝试从 globalThis 中查找 else if (typeof globalThis.GravityEngine === 'function') { GravityEngine = globalThis.GravityEngine; console.warn('[SDK] Found GravityEngine in globalThis object'); } else { console.error('[SDK] GravityEngine not found'); return; } try { // 使用您的 AppID 624768904 GravityEngine.init({ appId: '624768904', enableLog: true }); console.log('[SDK] GravityEngine initialized with AppID 624768904'); } catch (e) { console.error('[SDK] Init failed:', e); } } function handleSDKLoadFailure() { console.warn('[SDK] Using fallback analytics'); window.GravityEngine = { init: () => console.warn('SDK unavailable'), trackEvent: () => {} }; } // ====== 场景加载器 ====== async function loadStartScene() { try { // 加载主资源包 await new Promise((resolve) => { if (!cc.assetManager?.loadBundle) { console.warn('[Scene] AssetManager unavailable'); return resolve(); } cc.assetManager.loadBundle('main', (err) => { if (err) console.error('[Scene] Bundle load error:', err); resolve(); }); }); // 加载场景 if (cc.director?.loadScene) { cc.director.loadScene('start'); } else { throw new Error('Director unavailable'); } } catch (error) { console.error('[Scene] Load failed:', error); try { cc.director.loadScene('start'); } catch (e) { throw new Error('Fallback scene load failed'); } } } // ====== UI_Entry组件 ====== const { ccclass, property } = cc._decorator; @ccclass export default class UI_Entry extends cc.Component { @property(cc.ProgressBar) progress_loading = null; loginTimeoutHandler = null; onLoad() { EngineReady.safeAccess(() => { try { cc.director.getCollisionManager().enabled = true; this._show(); } catch (e) { console.error('[UI] onLoad error:', e); this.startLoadGame(); } }).catch(e => { console.error('[UI] Engine access error:', e); this.startLoadGame(); }); } onDestroy() { this.loginTimeoutHandler && cc.Tween.stop(this.loginTimeoutHandler); } async _show() { this.progress_loading.progress = 0; // 平台SDK初始化 if (cc.sys.isBrowser) { try { await this.initYPSDK(); } catch (e) { console.error('[YPSDK] Init failed:', e); this.startLoadGame(); } } else { this.startLoadGame(); } // 登录超时保护 this.setLoginTimeout(); } setLoginTimeout() { if (cc.tween) { this.loginTimeoutHandler = cc.tween(this) .delay(10) .call(() => { console.warn('[Login] Timeout after 10s'); this.startLoadGame(); }) .start(); } else { setTimeout(() => this.startLoadGame(), 10000); } } async initYPSDK() { if (typeof YPSDK === 'undefined') { console.warn('[YPSDK] SDK unavailable'); return; } const config = { gameChannelList: { h5: { platformType: "h5", version: "1.0.0" }, tt: { platformType: "tt", appId: "tt09297f94961f881b02" }, wx: { platformType: "wx", appId: "wx6baaaa27ab5186ff" } } }; await YPSDK.init(39, "https://platform-shop-dev.hanyougame.com", config); await YPSDK.login(); if (YPSDK.setLoginCallBack) { YPSDK.setLoginCallBack(success => { if (!success) return; // 取消超时 this.loginTimeoutHandler && cc.Tween.stop(this.loginTimeoutHandler); // 初始化分析SDK if (r_GravityPlatform.default?.GA_Init) { r_GravityPlatform.default.GA_Init(YPSDK.Platform.loginData.bindingId); } this.startLoadGame(); }); } else { this.startLoadGame(); } } startLoadGame() { const tasks = [ this._loadGameConfig, this._loadRemoteConfig, this._loadExcelData, this._loadUserData, this._loadCommonBundle, this._loadMainBundle ].map(fn => fn.bind(this)); this.executeTasks(tasks, () => this._loadGame()); } executeTasks(tasks, finalCallback) { let completed = 0; const total = tasks.length; const runTask = async (index) => { if (index >= total) { finalCallback(); return; } try { await tasks[index](); completed++; this._setProgress(completed / total); runTask(index + 1); } catch (e) { console.error(`[Task ${index}] Failed:`, e); completed++; this._setProgress(completed / total); runTask(index + 1); // 继续执行后续任务 } }; runTask(0); } async _loadExcelData() { if (!r_ExcelLoader?.ExcelLoader?.loadAll) { console.warn('[Data] ExcelLoader unavailable'); return; } await r_ExcelLoader.ExcelLoader.loadAll(); console.log('[Data] Excel loaded'); } async _loadGameConfig() { if (!r_ResLoader.default?.loadRes) { console.warn('[Config] ResLoader unavailable'); return; } const jsonAsset = await r_ResLoader.default.loadRes( "resources", "config/GameConfig", cc.JsonAsset ); if (jsonAsset && r_GameConfig.default) { r_GameConfig.default.appConfig = jsonAsset.json; jsonAsset.decRef && jsonAsset.decRef(); console.log('[Config] Game config loaded'); } } async _loadRemoteConfig() { if (!r_GameConfig.default?.appConfig?.RemoteUrl) { console.warn('[Config] RemoteUrl not set'); return; } const remoteUrl = r_GameConfig.default.appConfig.RemoteUrl; const remotePath = cc.path.join(remoteUrl, "ADConfig.json"); try { const remoteConfig = await r_ResLoader.default.loadRemote(remotePath, { ext: ".json" }); if (remoteConfig?.json && r_GravityPlatform.default) { r_GravityPlatform.default.videoId = remoteConfig.json.ADUnitId[0]; r_GameConfig.default.adConfig = remoteConfig.json; console.log('[Config] Remote config loaded'); } } catch (e) { console.error('[Config] Remote load failed:', e); } } async _loadCommonBundle() { if (!r_ResLoader.default?.loadBundle) { console.warn('[Bundle] ResLoader unavailable'); return; } try { await r_ResLoader.default.loadBundle(r_BundleConfig.BundleNames.Common); console.log('[Bundle] Common loaded'); } catch (e) { console.error('[Bundle] Common load failed:', e); } } async _loadMainBundle() { if (!r_ResLoader.default?.loadBundle) { console.warn('[Bundle] ResLoader unavailable'); return; } try { await r_ResLoader.default.loadBundle(r_BundleConfig.MainGameBundle); console.log('[Bundle] Main loaded'); } catch (e) { console.error('[Bundle] Main load failed:', e); } } async _loadUserData() { try { // 音频初始化 r_AudioManager.AudioMgr?.init(); // 全局配置 r_GameGlobalVariable.GameGlobalVariable?.initPeiZhi(); // 网络检测 if (YPSDK?.Common?.curChannelData) { const platformType = YPSDK.Common.curChannelData.platformType; if (platformType === YPSDK.GamePlatformType.WX || platformType === YPSDK.GamePlatformType.TT) { r_YpNetMag.YpNetMag?.failSever(() => { r_YpNetMag.YpNetMag.isFail = true; }); } } // 用户数据初始化 if (YPSDK?.Platform?.loginData) { await r_YpNetMag.YpNetMag?.initServer(YPSDK.Platform.loginData); } } catch (e) { console.error('[User] Load failed:', e); } } _loadGame() { try { const guideIndex = r_PlayerDataManager.PlayerDataMgr.GetGuideIndexByTaskName( r_Const_Common.GuideName.战斗背包 ); if (guideIndex !== r_Const_Common.GameBagGuideIndex.引导完结) { // 新玩家流程 r_PlayerDataManager.PlayerDataMgr.GMSetGuideIndex?.( r_Const_Common.GuideName.战斗背包, r_Const_Common.GameBagGuideIndex.引导初始1 ); r_GameDataManager.GameDataMgr?.ClearGameBagData(); r_GameGlobalVariable.GameGlobalVariable.nowlevel = 1; r_UIManager.default?.open( r_BundleConfig.BundleNames.Game, r_UIConfig_Game.UIView_Game.UI_GameView ); } else { // 老玩家流程 r_EventManager.EventMgr?.dispatchEvent(r_EvenType.EVENT_TYPE.Game_Load_View, true); r_UIManager.default?.open( r_BundleConfig.BundleNames.Home, r_UIConfig_Home.UIView_Home.UI_Hall ); } // 白名单检查 this.checkWhiteList(); } catch (e) { console.error('[Game] Load failed:', e); try { cc.director.loadScene('start'); } catch (sceneError) { console.error('[Game] Scene load failed:', sceneError); } } } async checkWhiteList() { try { if (!YPSDK?.Platform?.loginData || !YPSDK.platformUrl) return; const url = `${YPSDK.platformUrl}/User/GetCfgData?userId=${YPSDK.Platform.loginData.userUid}&keyId=NoVideo`; if (r_HttpManager.HttpMgr?.requestData) { r_HttpManager.HttpMgr.requestData(res => { if (res?.data?.keyData === "true") { r_PlayerDataManager.PlayerDataMgr.WHITE_NAME_NO_VIDEO = true; } }, url); } } catch (e) { console.error('[WhiteList] Check failed:', e); } } _setProgress(progress) { if (!this.progress_loading) return; this.progress_loading.progress = Math.max(0, Math.min(1, progress)); } } // ====== 启动游戏 ====== if (cc?.game?.run) { cc.game.run(() => { // 确保环境修复完成 ensureGlobalEnvironment(); gameMainEntry(); }); } else { setTimeout(() => { ensureGlobalEnvironment(); gameMainEntry(); }, 1000); } ``` ### 关键修复点 1. **JSB 引擎特殊处理**: ```javascript // JSB 特殊处理:使用 require 加载 if (cc.sys.isNative && cc.sys.__globalAdapter?.require) { cc.sys.__globalAdapter.require(path); console.log('[SDK] Native require loaded:', path); } else { await loadScript(path); console.log('[SDK] Loaded from:', path); } ``` 在 Cocos Creator 原生环境中,必须使用 `cc.sys.__globalAdapter.require` 来加载脚本,而不是标准的 `cc.assetManager.loadScript`。 2. **增强的全局对象修复**: ```javascript // 确保 self 在所有环境中都存在 if (typeof self === 'undefined') { console.warn('[GlobalFix] self is undefined, patching...'); Object.defineProperty(globalObj, 'self', { value: globalObj, writable: true, configurable: true, enumerable: true }); } ``` 在 SDK 加载前强制定义 `self` 对象,确保 SDK 内部不会出现引用错误。 3. **启动流程优化**: ```javascript cc.game.run(() => { // 确保环境修复完成 ensureGlobalEnvironment(); gameMainEntry(); }); ``` 在游戏启动时立即执行环境修复,确保所有全局对象在引擎初始化前就已定义。 ### 额外修复步骤 1. **修改重力引擎 SDK 文件**(可选但推荐): 在 `gravityengine.mg.cocoscreator.min.js` 文件开头添加: ```javascript // 在重力引擎 SDK 文件开头添加 (function(global) { if (typeof self === 'undefined') { global.self = global; } })((function() { if (typeof globalThis !== 'undefined') return globalThis; if (typeof global !== 'undefined') return global; if (typeof window !== 'undefined') return window; return Function('return this')() || {}; })()); ``` 2. **清理构建缓存**: ```bash # Windows rmdir /s /q build rmdir /s /q temp rmdir /s /q library # macOS/Linux rm -rf build/ temp/ library/ ``` 3. **构建设置**: 在 Cocos Creator 构建面板中: - 确保 "MD5 Cache" 选项已启用 - 在 "Native" 选项卡中,勾选 "Debug" 以获取更多日志 - 设置 "Script Debugging" 为 "Both" ### 错误分析 错误日志显示: ``` ERROR: Uncaught ReferenceError: self is not defined, location: src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:0:0 ``` 原因分析: 1. 在 Cocos Creator 原生环境中,`self` 对象默认不存在 2. 重力引擎 SDK 内部使用了 `self` 对象 3. 之前的修复代码执行时机可能太晚,在 SDK 加载时环境尚未准备好 4. JSB 引擎的脚本加载机制与浏览器环境不同 ### 测试验证 1. 在 Android 设备上安装应用 2. 检查日志中是否出现以下关键消息: ``` [SDK] Native require loaded: ./assets/_plugs/lib/gravityengine.mg.cocoscreator.min.js [SDK] GravityEngine initialized with AppID 624768904 ``` 3. 确认不再出现 `self is not defined` 错误
阅读全文

相关推荐

--------- beginning of system --------- beginning of main 2025-07-15 15:26:27.829 3124-3153 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x000082da 2025-07-15 15:26:27.829 3124-3153 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x000082e5 2025-07-15 15:26:27.835 3124-3153 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x00008c29 2025-07-15 15:26:27.835 3124-3153 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x000087fe 2025-07-15 15:26:27.858 3124-3153 EGL_emulation org.cocos2d.demo E tid 3153: eglSurfaceAttrib(1493): error 0x3009 (EGL_BAD_MATCH) 2025-07-15 15:26:29.679 3124-3151 jswrapper org.cocos2d.demo E ScriptEngine::onGetStringFromFile stream not found, possible missing file. 2025-07-15 15:26:29.679 3124-3151 jswrapper org.cocos2d.demo E ScriptEngine::runScript script stream, buffer is empty! 2025-07-15 15:26:29.679 3124-3151 jswrapper org.cocos2d.demo E [ERROR] Failed to invoke require, location: C:/ProgramData/cocos/editors/Creator/2.4.13/resources/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_global.cpp:299 2025-07-15 15:26:29.718 3124-3151 jswrapper org.cocos2d.demo E ScriptEngine::evalString catch exception: 2025-07-15 15:26:29.737 3124-3151 jswrapper org.cocos2d.demo E ERROR: Uncaught ReferenceError: self is not defined, location: src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:0:0 STACK: [0]anonymous@src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:2 [1]anonymous@src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:3 [2]anonymous@jsb-adapter/jsb-engine.js:2975 [3]download@jsb-adapter/jsb-engine.js:2984 [4]downloadScript@jsb-adapter/jsb-engine.js:2971 [5]a@src/cocos2d-jsb.28d62.js:16668 [6]anonymous@src/cocos2d-jsb.28d62.js:16678 [7]retry@src/cocos2d-jsb.28d62.js:18111 [8]download@src/cocos2d-jsb.28d62.js:16663 [9]load@src/cocos2d-jsb.28d62.js:17318 [10]94.e.exports@src/cocos2d-jsb.28d62.js:17134 [11]_flow@src/cocos2d-jsb.28d62.js:17579 [12]async@src/cocos2d-jsb.28d62.js:17574 [13]anonymous@src/cocos2d-jsb.28d62.js:17261 [14]forEach@src/cocos2d-jsb.28d62.js:18189 [15]94.e.exports@src/cocos2d-jsb.28d62.js:17244 [16]_flow@src/cocos2d-jsb.28d62.js:17579 [17]anonymous@src/cocos2d-jsb.28d62.js:17586 [18]98.e.exports@src/cocos2d-jsb.2 2025-07-15 15:26:29.738 3124-3151 jswrapper org.cocos2d.demo E ScriptEngine::evalString script src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js, failed! 2025-07-15 15:26:29.738 3124-3151 jswrapper org.cocos2d.demo E [ERROR] Failed to invoke require, location: C:/ProgramData/cocos/editors/Creator/2.4.13/resources/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_global.cpp:299 2025-07-15 15:26:42.981 1715-2033 bt_btif com.android.bluetooth E register_notification_rsp: Avrcp device is not connected, handle: 0x0 2025-07-15 15:26:42.981 1715-2033 bt_btif com.android.bluetooth E register_notification_rsp: Avrcp device is not connected, handle: 0x0 2025-07-15 15:26:42.989 1452-1763 OMXNodeInstance media.codec E setConfig(0xf5210060:google.mp3.decoder, ConfigPriority(0x6f800002)) ERROR: Undefined(0x80001001) 2025-07-15 15:26:42.990 1452-1763 OMXNodeInstance media.codec E getConfig(0xf5210060:google.mp3.decoder, ConfigAndroidVendorExtension(0x6f100004)) ERROR: Undefined(0x80001001) self问题解决了吗

--------- beginning of system 2025-07-14 19:01:46.868 1569-2215 ActivityManager system_server I Force stopping org.cocos2d.demo appid=10051 user=0: from pid 5432 --------- beginning of main 2025-07-14 19:01:46.869 2159-2159 ContextImpl com.android.coreservice W Calling a method in the system process without a qualified user: android.app.ContextImpl.startService:1531 android.content.ContextWrapper.startService:664 android.content.ContextWrapper.startService:664 com.android.coreservice.CoreBroadcastReceiver.onReceive:54 android.app.ActivityThread.handleReceiver:3424 2025-07-14 19:01:43.961 1569-1576 chatty system_server I uid=1000(system) FinalizerDaemon expire 46 lines 2025-07-14 19:01:43.961 1569-1576 System system_server W A resource failed to call close. 2025-07-14 19:01:46.870 1904-1904 CarrierSvcBindHelper com.android.phone D No carrier app for: 0 2025-07-14 19:01:46.935 1569-3446 ActivityManager system_server I Force stopping org.cocos2d.demo appid=10051 user=0: from pid 5445 2025-07-14 19:01:46.936 1904-1904 CarrierSvcBindHelper com.android.phone D No carrier app for: 0 2025-07-14 19:01:46.937 2159-2159 ContextImpl com.android.coreservice W Calling a method in the system process without a qualified user: android.app.ContextImpl.startService:1531 android.content.ContextWrapper.startService:664 android.content.ContextWrapper.startService:664 com.android.coreservice.CoreBroadcastReceiver.onReceive:54 android.app.ActivityThread.handleReceiver:3424 2025-07-14 19:01:46.959 1569-3446 ActivityManager system_server I START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=org.cocos2d.demo/org.cocos2dx.javascript.AppActivity} from uid 2000 2025-07-14 19:01:46.974 2159-2159 ContextImpl com.android.coreservice W Calling a method in the system process without a qualified user: android.app.ContextImpl.startService:1531 android.content.ContextWrapper.startService:664 android.content.ContextWrapper.startService:664 com.android.coreservice.CoreBroadcastReceiver.onReceive:45 android.app.ActivityThread.handleReceiver:3424 2025-07-14 19:01:46.979 1423-1423 [email protected] [email protected] I type=1400 audit(0.0:1117): avc: denied { ioctl } for path="/dev/fastpipe" dev="tmpfs" ino=7232 ioctlcmd=6867 scontext=u:r:hal_graphics_allocator_default:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1 2025-07-14 19:01:46.998 5451-5451 nativebridge pid-5451 D PreInitializeNativeBridge name=zygote64 instruction_set=arm64 2025-07-14 19:01:46.999 1569-1586 ActivityManager system_server I Start proc 5451:org.cocos2d.demo/u0a51 for activity org.cocos2d.demo/org.cocos2dx.javascript.AppActivity 2025-07-14 19:01:47.014 5451-5451 nativebridge pid-5451 W Failed to bind-mount /data/local/cfg-nnayn/ as /proc/cpuinfo: Not a directory 2025-07-14 19:01:47.017 5451-5451 Zygote pid-5451 I seccomp disabled by setenforce 0 2025-07-14 19:01:47.018 5451-5451 rg.cocos2d.dem pid-5451 I Late-enabling -Xcheck:jni 2025-07-14 19:01:47.036 5451-5451 libnb pid-5451 V enter native_bridge2_initialize /data/user/0/org.cocos2d.demo/code_cache arm64 2025-07-14 19:01:47.036 5451-5451 houdini pid-5451 D [5451] Initialize library(version: 9.0.7a_z.38597 RELEASE)... successfully. ---------------------------- PROCESS STARTED (5451) for package org.cocos2d.demo ---------------------------- 2025-07-14 19:01:47.037 5451-5451 libnb pid-5451 V enter native_bridge2_isCompatibleWith 2 2025-07-14 19:01:47.139 2159-2159 ContextImpl com.android.coreservice W Calling a method in the system process without a qualified user: android.app.ContextImpl.startService:1531 android.content.ContextWrapper.startService:664 android.content.ContextWrapper.startService:664 com.android.coreservice.CoreBroadcastReceiver.onReceive:54 android.app.ActivityThread.handleReceiver:3424 2025-07-14 19:01:47.037 5451-5451 chatty org.cocos2d.demo I uid=10051(org.cocos2d.demo) identical 63 lines 2025-07-14 19:01:47.037 5451-5451 libnb org.cocos2d.demo V enter native_bridge2_isCompatibleWith 2 2025-07-14 19:01:47.157 5451-5451 libnb org.cocos2d.demo V enter native_bridge2_isCompatibleWith 3 2025-07-14 19:01:47.157 5451-5451 libnb org.cocos2d.demo V enter native_bridge3_isPathSupported /data/app/org.cocos2d.demo-DSE6AeZBhpmsfM8p5sz99g==/lib/arm64:/data/app/org.cocos2d.demo-DSE6AeZBhpmsfM8p5sz99g==/base.apk!/lib/arm64-v8a 2025-07-14 19:01:47.157 5451-5451 libnb org.cocos2d.demo V enter native_bridge2_isCompatibleWith 3 2025-07-14 19:01:47.157 5451-5451 libnb org.cocos2d.demo V enter native_bridge3_initAnonymousNamespace libandroid.so:libaaudio.so:libc.so:libcamera2ndk.so:libdl.so:libEGL.so:libGLESv1_CM.so:libGLESv2.so:libGLESv3.so:libicui18n.so:libicuuc.so:libjnigraphics.so:liblog.so:libmediandk.so:libm.so:libnativewindow.so:libneuralnetworks.so:libOpenMAXAL.so:libOpenSLES.so:libRS.so:libstdc++.so:libsync.so:libvulkan.so:libwebviewchromium_plat_support.so:libz.so, /data/app/org.cocos2d.demo-DSE6AeZBhpmsfM8p5sz99g==/lib/arm64:/data/app/org.cocos2d.demo-DSE6AeZBhpmsfM8p5sz99g==/base.apk!/lib/arm64-v8a 2025-07-14 19:01:47.157 5451-5451 libnb org.cocos2d.demo V enter native_bridge2_isCompatibleWith 3 2025-07-14 19:01:47.157 5451-5451 libnb org.cocos2d.demo V enter native_bridge3_isPathSupported /data/app/org.cocos2d.demo-DSE6AeZBhpmsfM8p5sz99g==/lib/arm64:/data/app/org.cocos2d.demo-DSE6AeZBhpmsfM8p5sz99g==/base.apk!/lib/arm64-v8a 2025-07-14 19:01:47.157 5451-5451 libnb org.cocos2d.demo V enter native_bridge2_isCompatibleWith 3 2025-07-14 19:01:47.157 5451-5451 libnb org.cocos2d.demo V enter native_bridge3_createNamespace classloader-namespace, (null), /data/app/org.cocos2d.demo-DSE6AeZBhpmsfM8p5sz99g==/lib/arm64:/data/app/org.cocos2d.demo-DSE6AeZBhpmsfM8p5sz99g==/base.apk!/lib/arm64-v8a, /data:/mnt/expand:/data/user/0/org.cocos2d.demo 2025-07-14 19:01:47.157 5451-5451 libnb org.cocos2d.demo V enter native_bridge2_isCompatibleWith 4 2025-07-14 19:01:47.157 5451-5451 libnb org.cocos2d.demo V enter native_bridge2_isCompatibleWith 3 2025-07-14 19:01:47.157 5451-5451 libnb org.cocos2d.demo V enter native_bridge3_linkNamespaces libandroid.so:libaaudio.so:libc.so:libcamera2ndk.so:libdl.so:libEGL.so:libGLESv1_CM.so:libGLESv2.so:libGLESv3.so:libicui18n.so:libicuuc.so:libjnigraphics.so:liblog.so:libmediandk.so:libm.so:libnativewindow.so:libneuralnetworks.so:libOpenMAXAL.so:libOpenSLES.so:libRS.so:libstdc++.so:libsync.so:libvulkan.so:libwebviewchromium_plat_support.so:libz.so 2025-07-14 19:01:47.164 1569-1576 System system_server W A resource failed to call close. 2025-07-14 19:01:47.164 1569-1576 chatty system_server I uid=1000(system) FinalizerDaemon identical 19 lines 2025-07-14 19:01:47.164 1569-1576 System system_server W A resource failed to call close. 2025-07-14 19:01:47.198 1721-2100 ziparchive com.android.systemui W Unable to open '/data/app/org.cocos2d.demo-qLW_1oeK0d6GzjNEfloC_Q==/base.apk': No such file or directory 2025-07-14 19:01:47.198 1721-2100 ndroid.systemu com.android.systemui E Failed to open APK '/data/app/org.cocos2d.demo-qLW_1oeK0d6GzjNEfloC_Q==/base.apk' I/O error 2025-07-14 19:01:47.198 1721-2100 ResourcesManager com.android.systemui E failed to add asset path /data/app/org.cocos2d.demo-qLW_1oeK0d6GzjNEfloC_Q==/base.apk 2025-07-14 19:01:47.198 1721-2100 PackageManager com.android.systemui W Failure retrieving resources for org.cocos2d.demo 2025-07-14 19:01:47.198 1721-2100 ziparchive com.android.systemui W Unable to open '/data/app/org.cocos2d.demo-qLW_1oeK0d6GzjNEfloC_Q==/base.apk': No such file or directory 2025-07-14 19:01:47.198 1721-2100 ndroid.systemu com.android.systemui E Failed to open APK '/data/app/org.cocos2d.demo-qLW_1oeK0d6GzjNEfloC_Q==/base.apk' I/O error 2025-07-14 19:01:47.198 1721-2100 ResourcesManager com.android.systemui E failed to add asset path /data/app/org.cocos2d.demo-qLW_1oeK0d6GzjNEfloC_Q==/base.apk 2025-07-14 19:01:47.198 1721-2100 PackageManager com.android.systemui W Failure retrieving resources for org.cocos2d.demo 2025-07-14 19:01:47.198 1721-2100 ziparchive com.android.systemui W Unable to open '/data/app/org.cocos2d.demo-qLW_1oeK0d6GzjNEfloC_Q==/base.apk': No such file or directory 2025-07-14 19:01:47.198 1721-2100 ndroid.systemu com.android.systemui E Failed to open APK '/data/app/org.cocos2d.demo-qLW_1oeK0d6GzjNEfloC_Q==/base.apk' I/O error 2025-07-14 19:01:47.198 1721-2100 ResourcesManager com.android.systemui E failed to add asset path /data/app/org.cocos2d.demo-qLW_1oeK0d6GzjNEfloC_Q==/base.apk 2025-07-14 19:01:47.198 1721-2100 PackageManager com.android.systemui W Failure retrieving resources for org.cocos2d.demo 2025-07-14 19:01:47.198 1721-2100 ziparchive com.android.systemui W Unable to open '/data/app/org.cocos2d.demo-qLW_1oeK0d6GzjNEfloC_Q==/base.apk': No such file or directory 2025-07-14 19:01:47.198 1721-2100 ndroid.systemu com.android.systemui E Failed to open APK '/data/app/org.cocos2d.demo-qLW_1oeK0d6GzjNEfloC_Q==/base.apk' I/O error 2025-07-14 19:01:47.198 1721-2100 ResourcesManager com.android.systemui E failed to add asset path /data/app/org.cocos2d.demo-qLW_1oeK0d6GzjNEfloC_Q==/base.apk 2025-07-14 19:01:47.198 1721-2100 PackageManager com.android.systemui W Failure retrieving resources for org.cocos2d.demo 2025-07-14 19:01:47.198 1721-2100 ziparchive com.android.systemui W Unable to open '/data/app/org.cocos2d.demo-qLW_1oeK0d6GzjNEfloC_Q==/base.apk': No such file or directory 2025-07-14 19:01:47.198 1721-2100 ndroid.systemu com.android.systemui E Failed to open APK '/data/app/org.cocos2d.demo-qLW_1oeK0d6GzjNEfloC_Q==/base.apk' I/O error 2025-07-14 19:01:47.198 1721-2100 ResourcesManager com.android.systemui E failed to add asset path /data/app/org.cocos2d.demo-qLW_1oeK0d6GzjNEfloC_Q==/base.apk 2025-07-14 19:01:47.198 1721-2100 PackageManager com.android.systemui W Failure retrieving resources for org.cocos2d.demo 2025-07-14 19:01:47.224 5451-5451 Cocos2dxActivity org.cocos2d.demo D Cocos2dxActivity onCreate: org.cocos2dx.javascript.AppActivity@f1c691f, savedInstanceState: null 2025-07-14 19:01:47.260 5451-5451 libnb org.cocos2d.demo V enter native_bridge2_isCompatibleWith 3 2025-07-14 19:01:47.260 5451-5451 libnb org.cocos2d.demo V enter native_bridge3_loadLibraryExt /data/app/org.cocos2d.demo-DSE6AeZBhpmsfM8p5sz99g==/lib/arm64/libcocos2djs.so, 2, 0x3 2025-07-14 19:01:47.512 5451-5451 libnb org.cocos2d.demo V native_bridge3_loadLibraryExt: 0x763877d4eac0 2025-07-14 19:01:47.513 5451-5451 libnb org.cocos2d.demo V enter native_bridge2_getTrampoline JNI_OnLoad, trampoline_addr 0x76388e6af000 2025-07-14 19:01:47.513 5451-5451 JniHelper org.cocos2d.demo D JniHelper::setJavaVM(0x76388ede6928), pthread_self() = 129987584391496 2025-07-14 19:01:47.513 5451-5451 main org.cocos2d.demo D cocos_jni_env_init 2025-07-14 19:01:47.513 5451-5451 Cocos2dxHelper org.cocos2d.demo D isSupportLowLatency:true 2025-07-14 19:01:47.515 5451-5451 Cocos2dxHelper org.cocos2d.demo D sampleRate: 48000, framesPerBuffer: 1024 2025-07-14 19:01:47.515 5451-5451 libnb org.cocos2d.demo V enter native_bridge2_getTrampoline Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetAudioDeviceInfo, trampoline_addr 0x76388e6af020 2025-07-14 19:01:47.515 5451-5451 JniImp org.cocos2d.demo D nativeSetAudioDeviceInfo: sampleRate: 48000, bufferSizeInFrames: 1024 2025-07-14 19:01:47.516 5451-5451 libnb org.cocos2d.demo V enter native_bridge2_getTrampoline Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetApkPath, trampoline_addr 0x76388e6af040 2025-07-14 19:01:47.517 5451-5451 libnb org.cocos2d.demo V enter native_bridge2_getTrampoline Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetContext, trampoline_addr 0x76388e6af060 2025-07-14 19:01:47.520 5451-5451 libnb org.cocos2d.demo V enter native_bridge2_getTrampoline Java_org_cocos2dx_lib_Cocos2dxActivity_getGLContextAttrs, trampoline_addr 0x76388e6af080 2025-07-14 19:01:47.521 5451-5451 OpenGLRenderer org.cocos2d.demo D Skia GL Pipeline 2025-07-14 19:01:47.522 5451-5451 SDKWrapper org.cocos2d.demo W project.json 中不存在 serviceClassPath 字段 2025-07-14 19:01:47.523 5451-5451 Cocos2dxActivity org.cocos2d.demo D model=ASUS_AI2401_A 2025-07-14 19:01:47.523 5451-5451 Cocos2dxActivity org.cocos2d.demo D product=ASUS_AI2401_A 2025-07-14 19:01:47.523 5451-5451 Cocos2dxActivity org.cocos2d.demo D isEmulator=false 2025-07-14 19:01:47.546 5451-5451 Cocos2dxActivity org.cocos2d.demo D onResume() 2025-07-14 19:01:47.599 5451-5451 libnb org.cocos2d.demo V enter native_bridge2_getTrampoline Java_org_cocos2dx_lib_Cocos2dxGLSurfaceView_nativeOnSizeChanged, trampoline_addr 0x76388e6af0a0 2025-07-14 19:01:47.599 5451-5480 <no-tag> org.cocos2d.demo I fastpipe: Connect success 2025-07-14 19:01:47.601 5451-5480 <no-tag> org.cocos2d.demo I fastpipe: Connect success 2025-07-14 19:01:47.601 5451-5480 HostConnection org.cocos2d.demo D HostRPC::connect sucess: app=org.cocos2d.demo, pid=5451, tid=5480, this=0x7638888262c0 2025-07-14 19:01:47.602 5451-5480 HostConnection org.cocos2d.demo D queryAndSetGLESMaxVersion select gles-version: 3.1 hostGLVersion:46 process:org.cocos2d.demo 2025-07-14 19:01:47.604 5451-5480 ConfigStore org.cocos2d.demo I android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0 2025-07-14 19:01:47.604 5451-5480 ConfigStore org.cocos2d.demo I android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0 2025-07-14 19:01:47.604 5451-5480 OpenGLRenderer org.cocos2d.demo I Initialized EGL, version 1.4 2025-07-14 19:01:47.604 5451-5480 OpenGLRenderer org.cocos2d.demo D Swap behavior 1 2025-07-14 19:01:47.605 5451-5478 <no-tag> org.cocos2d.demo I fastpipe: Connect success 2025-07-14 19:01:47.605 5451-5478 HostConnection org.cocos2d.demo D HostRPC::connect sucess: app=org.cocos2d.demo, pid=5451, tid=5478, this=0x76387a5f7b00 2025-07-14 19:01:47.610 5451-5480 EGL_emulation org.cocos2d.demo D eglCreateContext: 0x76389273ba80: maj 3 min 1 rcv 4 2025-07-14 19:01:47.610 5451-5478 HostConnection org.cocos2d.demo D queryAndSetGLESMaxVersion select gles-version: 3.1 hostGLVersion:46 process:org.cocos2d.demo 2025-07-14 19:01:47.617 5451-5478 EGL_emulation org.cocos2d.demo D eglCreateContext: 0x76389273bf00: maj 3 min 1 rcv 4 2025-07-14 19:01:47.638 5451-5478 vndksupport org.cocos2d.demo D Loading /vendor/lib64/hw/[email protected] from current namespace instead of sphal namespace. 2025-07-14 19:01:47.639 5451-5480 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x000082da 2025-07-14 19:01:47.639 5451-5480 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x000082e5 2025-07-14 19:01:47.640 5451-5478 vndksupport org.cocos2d.demo D Loading /vendor/lib64/hw/gralloc.default.so from current namespace instead of sphal namespace. 2025-07-14 19:01:47.642 5451-5480 HostConnection org.cocos2d.demo D ExtendedRCEncoderContext GL_VERSION return OpenGL ES 3.1 v1 2025-07-14 19:01:47.644 5451-5480 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x00008c29 2025-07-14 19:01:47.645 5451-5480 eglCodecCommon org.cocos2d.demo E glUtilsParamSize: unknow param 0x000087fe 2025-07-14 19:01:47.666 5451-5478 libnb org.cocos2d.demo V enter native_bridge2_getTrampoline Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit, trampoline_addr 0x76388e6af0c0 2025-07-14 19:01:47.666 5451-5478 main org.cocos2d.demo D cocos_android_app_init 2025-07-14 19:01:47.667 5451-5478 HostConnection org.cocos2d.demo D ExtendedRCEncoderContext GL_VERSION return OpenGL ES 3.1 v1 2025-07-14 19:01:47.671 5451-5480 EGL_emulation org.cocos2d.demo E tid 5480: eglSurfaceAttrib(1493): error 0x3009 (EGL_BAD_MATCH) 2025-07-14 19:01:47.671 5451-5480 OpenGLRenderer org.cocos2d.demo W Failed to set EGL_SWAP_BEHAVIOR on surface 0x76387a0f6180, error=EGL_BAD_MATCH 2025-07-14 19:01:47.672 5451-5478 JniImp org.cocos2d.demo D nativeInit: 1440, 2560, 2025-07-14 19:01:47.686 5451-5478 jswrapper org.cocos2d.demo D Initializing V8, version: 8.0.426.16 2025-07-14 19:01:47.709 5451-5451 Cocos2dxActivity org.cocos2d.demo D onWindowFocusChanged() hasFocus=true 2025-07-14 19:01:47.548 2159-2159 ContextImpl com.android.coreservice W Calling a method in the system process without a qualified user: android.app.ContextImpl.startService:1531 android.content.ContextWrapper.startService:664 android.content.ContextWrapper.startService:664 com.android.coreservice.CoreBroadcastReceiver.onReceive:54 android.app.ActivityThread.handleReceiver:3424 2025-07-14 19:01:47.712 2159-2159 ContextImpl com.android.coreservice W Calling a method in the system process without a qualified user: android.app.ContextImpl.startService:1531 android.content.ContextWrapper.startService:664 android.content.ContextWrapper.startService:664 com.android.coreservice.CoreBroadcastReceiver.onReceive:70 android.app.ActivityThread.handleReceiver:3424 2025-07-14 19:01:47.747 1569-1576 System system_server W A resource failed to call close. 2025-07-14 19:01:47.747 1569-1576 chatty system_server I uid=1000(system) FinalizerDaemon identical 25 lines 2025-07-14 19:01:47.747 1569-1576 System system_server W A resource failed to call close. 2025-07-14 19:01:47.775 5451-5478 jswrapper org.cocos2d.demo D libuv version: 1.13.1 2025-07-14 19:01:47.780 5451-5488 jswrapper org.cocos2d.demo D Debugger listening..., visit [ devtools://devtools/bundled/js_app.html?v8only=true&ws=0.0.0.0:6086/00010002-0003-4004-8005-000600070008 ] in chrome browser to debug! 2025-07-14 19:01:47.780 5451-5488 jswrapper org.cocos2d.demo D For help see https://nodejs.org/en/docs/inspector 2025-07-14 19:01:48.368 5451-5478 jswrapper org.cocos2d.demo D JS: Enable batch GL commands optimization! 2025-07-14 19:01:49.262 5451-5478 NetworkSecurityConfig org.cocos2d.demo D No Network Security Config specified, using platform default 2025-07-14 19:01:49.264 5451-5478 rg.cocos2d.dem org.cocos2d.demo W Accessing hidden method Ldalvik/system/CloseGuard;->get()Ldalvik/system/CloseGuard; (light greylist, reflection) 2025-07-14 19:01:49.264 5451-5478 rg.cocos2d.dem org.cocos2d.demo W Accessing hidden method Ldalvik/system/CloseGuard;->open(Ljava/lang/String;)V (light greylist, reflection) 2025-07-14 19:01:49.264 5451-5478 rg.cocos2d.dem org.cocos2d.demo W Accessing hidden method Ldalvik/system/CloseGuard;->warnIfOpen()V (light greylist, reflection) 2025-07-14 19:01:49.269 5451-5478 cocos2d-x org.cocos2d.demo D find in flash memory dirPath(/data/user/0/org.cocos2d.demo/files/temp) 2025-07-14 19:01:49.322 5451-5478 jswrapper org.cocos2d.demo E ScriptEngine::onGetStringFromFile stream not found, possible missing file. 2025-07-14 19:01:49.322 5451-5478 jswrapper org.cocos2d.demo E ScriptEngine::runScript script stream, buffer is empty! 2025-07-14 19:01:49.322 5451-5478 jswrapper org.cocos2d.demo E [ERROR] Failed to invoke require, location: C:/ProgramData/cocos/editors/Creator/2.4.13/resources/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_global.cpp:299 2025-07-14 19:01:49.362 5451-5478 jswrapper org.cocos2d.demo E ScriptEngine::evalString catch exception: 2025-07-14 19:01:49.382 5451-5478 jswrapper org.cocos2d.demo E ERROR: Uncaught ReferenceError: self is not defined, location: src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:0:0 STACK: [0]anonymous@src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:2 [1]anonymous@src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:3 [2]anonymous@jsb-adapter/jsb-engine.js:2975 [3]download@jsb-adapter/jsb-engine.js:2984 [4]downloadScript@jsb-adapter/jsb-engine.js:2971 [5]a@src/cocos2d-jsb.28d62.js:16668 [6]anonymous@src/cocos2d-jsb.28d62.js:16678 [7]retry@src/cocos2d-jsb.28d62.js:18111 [8]download@src/cocos2d-jsb.28d62.js:16663 [9]load@src/cocos2d-jsb.28d62.js:17318 [10]94.e.exports@src/cocos2d-jsb.28d62.js:17134 [11]_flow@src/cocos2d-jsb.28d62.js:17579 [12]async@src/cocos2d-jsb.28d62.js:17574 [13]anonymous@src/cocos2d-jsb.28d62.js:17261 [14]forEach@src/cocos2d-jsb.28d62.js:18189 [15]94.e.exports@src/cocos2d-jsb.28d62.js:17244 [16]_flow@src/cocos2d-jsb.28d62.js:17579 [17]anonymous@src/cocos2d-jsb.28d62.js:17586 [18]98.e.exports@src/cocos2d-jsb.2 2025-07-14 19:01:49.382 5451-5478 debug info org.cocos2d.demo D Uncaught Exception: - location : (see stack) - msg : Uncaught ReferenceError: self is not defined - detail : [0]anonymous@src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:2 [1]anonymous@src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:3 [2]anonymous@jsb-adapter/jsb-engine.js:2975 [3]download@jsb-adapter/jsb-engine.js:2984 [4]downloadScript@jsb-adapter/jsb-engine.js:2971 [5]a@src/cocos2d-jsb.28d62.js:16668 [6]anonymous@src/cocos2d-jsb.28d62.js:16678 [7]retry@src/cocos2d-jsb.28d62.js:18111 [8]download@src/cocos2d-jsb.28d62.js:16663 [9]load@src/cocos2d-jsb.28d62.js:17318 [10]94.e.exports@src/cocos2d-jsb.28d62.js:17134 [11]_flow@src/cocos2d-jsb.28d62.js:17579 [12]async@src/cocos2d-jsb.28d62.js:17574 [13]anonymous@src/cocos2d-jsb.28d62.js:17261 [14]forEach@src/cocos2d-jsb.28d62.js:18189 [15]94.e.exports@src/cocos2d-jsb.28d62.js:17244 [16]_flow@src/cocos2d-jsb.28d62.js:17579 [17]anonymous@src/cocos2d-jsb.28d62.js:17586 [18]98.e.exports@src/cocos2d-jsb.28d62.js:17642 [19] 2025-07-14 19:01:49.383 5451-5478 jswrapper org.cocos2d.demo D JS: [ERROR]: (see stack) Uncaught ReferenceError: self is not defined [0]anonymous@src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:2 [1]anonymous@src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js:3 [2]anonymous@jsb-adapter/jsb-engine.js:2975 [3]download@jsb-adapter/jsb-engine.js:2984 [4]downloadScript@jsb-adapter/jsb-engine.js:2971 [5]a@src/cocos2d-jsb.28d62.js:16668 [6]anonymous@src/cocos2d-jsb.28d62.js:16678 [7]retry@src/cocos2d-jsb.28d62.js:18111 [8]download@src/cocos2d-jsb.28d62.js:16663 [9]load@src/cocos2d-jsb.28d62.js:17318 [10]94.e.exports@src/cocos2d-jsb.28d62.js:17134 [11]_flow@src/cocos2d-jsb.28d62.js:17579 [12]async@src/cocos2d-jsb.28d62.js:17574 [13]anonymous@src/cocos2d-jsb.28d62.js:17261 [14]forEach@src/cocos2d-jsb.28d62.js:18189 [15]94.e.exports@src/cocos2d-jsb.28d62.js:17244 [16]_flow@src/cocos2d-jsb.28d62.js:17579 [17]anonymous@src/cocos2d-jsb.28d62.js:17586 [18]98.e.exports@src/cocos2d-jsb.28d62.js:17642 [19]_flow@src/cocos2d-jsb.28d62.js:17579 2025-07-14 19:01:49.384 5451-5478 jswrapper org.cocos2d.demo E ScriptEngine::evalString script src/assets/_plugs/lib/gravityengine.mg.cocoscreator.min.dbb97.js, failed! 2025-07-14 19:01:49.384 5451-5478 jswrapper org.cocos2d.demo E [ERROR] Failed to invoke require, location: C:/ProgramData/cocos/editors/Creator/2.4.13/resources/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_global.cpp:299 2025-07-14 19:01:49.428 5451-5478 libnb org.cocos2d.demo V enter native_bridge2_getTrampoline Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnSurfaceChanged, trampoline_addr 0x76388e6af0e0 2025-07-14 19:01:49.429 5451-5478 libnb org.cocos2d.demo V enter native_bridge2_getTrampoline Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeRender, trampoline_addr 0x76388e6af100 2025-07-14 19:01:49.652 5451-5478 libnb org.cocos2d.demo V enter native_bridge2_getTrampoline Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnResume, trampoline_addr 0x76388e6af120 2025-07-14 19:01:49.667 5451-5478 renderer org.cocos2d.demo D (626): Device caps: maxVextexTextures: 32, maxFragUniforms: 1024, maxTextureUints: 32, maxVertexAttributes: 16, maxDrawBuffers: 1, maxColorAttatchments: 1 2025-07-14 19:01:49.856 1569-1583 system_server system_server W Failed to determine oat file name for dex location /data/app/org.cocos2d.demo-DSE6AeZBhpmsfM8p5sz99g==/base.apk: Dalvik cache directory does not exist 2025-07-14 19:01:49.856 1569-1583 ActivityManager system_server I Displayed org.cocos2d.demo/org.cocos2dx.javascript.AppActivity: +2s896ms 2025-07-14 19:01:49.865 1436-1436 surfaceflinger surfaceflinger I type=1400 audit(0.0:1139): avc: denied { read write } for path="/dev/fastpipe" dev="tmpfs" ino=7232 scontext=u:r:hal_graphics_composer_default:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1 2025-07-14 19:01:49.904 1436-1524 SurfaceFlinger surfaceflinger W Attempting to set client state on removed layer: Splash Screen org.cocos2d.demo#0 2025-07-14 19:01:49.904 1436-1524 SurfaceFlinger surfaceflinger W Attempting to destroy on removed layer: Splash Screen org.cocos2d.demo#0 2025-07-14 19:01:49.937 5451-5478 jswrapper org.cocos2d.demo D JS: Cocos Creator v2.4.13 2025-07-14 19:01:50.037 5451-5478 jswrapper org.cocos2d.demo D JS: 平板 宽度=750 高度=1333.3333333333335 2025-07-14 19:01:50.041 5451-5478 jswrapper org.cocos2d.demo D JS: 平板 宽度 适配后 宽度=750.375 高度=1334 2025-07-14 19:01:50.249 5451-5478 jswrapper org.cocos2d.demo D JS: 【YPSDK】 设置 登录回调 成功 2025-07-14 19:01:50.250 5451-5478 jswrapper org.cocos2d.demo D JS: [game-logger] UIManager open view: UI_Entry 2025-07-14 19:01:50.428 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:01:51.176 5451-5478 chatty org.cocos2d.demo I uid=10051(org.cocos2d.demo) GLThread 168 identical 11 lines 2025-07-14 19:01:51.246 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:01:51.245 1433-1433 ldinit ldinit I type=1400 audit(0.0:1140): avc: denied { read } for name="partitions" dev="proc" ino=4026532050 scontext=u:r:ldinit:s0 tcontext=u:object_r:proc:s0 tclass=file permissive=1 2025-07-14 19:01:51.245 1433-1433 ldinit ldinit I type=1400 audit(0.0:1140): avc: denied { open } for path="/proc/partitions" dev="proc" ino=4026532050 scontext=u:r:ldinit:s0 tcontext=u:object_r:proc:s0 tclass=file permissive=1 2025-07-14 19:01:51.330 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:01:59.903 5451-5478 chatty org.cocos2d.demo I uid=10051(org.cocos2d.demo) GLThread 168 identical 95 lines 2025-07-14 19:01:59.976 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:00.001 1569-1583 memtrack system_server E Couldn't load memtrack module 2025-07-14 19:02:00.001 1569-1583 android.os.Debug system_server W failed to get memory consumption info: -1 2025-07-14 19:02:00.048 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:00.149 5451-5478 chatty org.cocos2d.demo I uid=10051(org.cocos2d.demo) GLThread 168 identical 1 line 2025-07-14 19:02:00.216 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:00.256 5451-5478 jswrapper org.cocos2d.demo D JS: [ERROR]: 10s后,仍然未登录成功,直接进入游戏 2025-07-14 19:02:00.266 5451-5478 jswrapper org.cocos2d.demo D JS: Load game config success: [object Object] 2025-07-14 19:02:00.267 5451-5478 jswrapper org.cocos2d.demo D JS: 游戏本地配置加载成功 6 2025-07-14 19:02:00.281 5451-5478 jswrapper org.cocos2d.demo D JS: Load remote config success: [object Object] 2025-07-14 19:02:00.282 5451-5478 jswrapper org.cocos2d.demo D JS: 远程配置加载成功 13 2025-07-14 19:02:00.300 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:00.368 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:00.436 5451-5494 rg.cocos2d.dem org.cocos2d.demo W Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([B)V (light greylist, reflection) 2025-07-14 19:02:00.436 5451-5497 rg.cocos2d.dem org.cocos2d.demo W Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([B)V (light greylist, reflection) 2025-07-14 19:02:00.436 5451-5493 rg.cocos2d.dem org.cocos2d.demo W Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([B)V (light greylist, reflection) 2025-07-14 19:02:00.436 5451-5502 rg.cocos2d.dem org.cocos2d.demo W Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([B)V (light greylist, reflection) 2025-07-14 19:02:00.442 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:00.486 5451-5493 rg.cocos2d.dem org.cocos2d.demo W Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getAlpnSelectedProtocol()[B (light greylist, reflection) 2025-07-14 19:02:00.512 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:00.578 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:00.582 5451-5478 libnb org.cocos2d.demo V enter native_bridge2_getTrampoline Java_org_cocos2dx_lib_Cocos2dxDownloader_nativeOnProgress, trampoline_addr 0x76388e6af140 2025-07-14 19:02:00.583 5451-5478 libnb org.cocos2d.demo V enter native_bridge2_getTrampoline Java_org_cocos2dx_lib_Cocos2dxDownloader_nativeOnFinish, trampoline_addr 0x76388e6af160 2025-07-14 19:02:00.675 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:00.824 5451-5478 chatty org.cocos2d.demo I uid=10051(org.cocos2d.demo) GLThread 168 identical 2 lines 2025-07-14 19:02:00.908 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:01.080 5451-5478 jswrapper org.cocos2d.demo D JS: [game-logger] load excel done 20 2025-07-14 19:02:01.083 5451-5478 jswrapper org.cocos2d.demo D JS: 游戏数据表加载成功 799 2025-07-14 19:02:01.085 5451-5478 jswrapper org.cocos2d.demo D JS: [ERROR]: 初始化数据 2025-07-14 19:02:01.092 5451-5478 jswrapper org.cocos2d.demo D JS: [ERROR]: [game-logger] load user data error: [object Object] 2025-07-14 19:02:01.121 5451-5478 jswrapper org.cocos2d.demo D JS: Loaded main bundle [object Object] 2025-07-14 19:02:01.122 5451-5478 jswrapper org.cocos2d.demo D JS: Common分包下载 28 2025-07-14 19:02:01.144 5451-5478 jswrapper org.cocos2d.demo D JS: Loaded main bundle [object Object] 2025-07-14 19:02:01.145 5451-5478 jswrapper org.cocos2d.demo D JS: Home分包下载 22 2025-07-14 19:02:01.162 5451-5478 debug info org.cocos2d.demo D Uncaught Exception: - location : - msg : unhandledRejectedPromise - detail : TypeError: Cannot read property 'userUid' of null stacktrace: [0]406.window.__awaiter@src/cocos2d-jsb.28d62.js:71530 [1]t.onInitWhiteName@assets/main/index.0a7c4.jsc:16936 [2]t._loadGame@assets/main/index.0a7c4.jsc:16756 [3]anonymous@assets/main/index.0a7c4.jsc:16771 2025-07-14 19:02:01.162 5451-5478 jswrapper org.cocos2d.demo D JS: [ERROR]: unhandledRejectedPromise TypeError: Cannot read property 'userUid' of null stacktrace: [0]406.window.__awaiter@src/cocos2d-jsb.28d62.js:71530 [1]t.onInitWhiteName@assets/main/index.0a7c4.jsc:16936 [2]t._loadGame@assets/main/index.0a7c4.jsc:16756 [3]anonymous@assets/main/index.0a7c4.jsc:16771 2025-07-14 19:02:01.188 5451-5478 jswrapper org.cocos2d.demo D JS: [game-logger] auto release all resources: ["UI_Entry"] 2025-07-14 19:02:01.323 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:01.479 5451-5478 jswrapper org.cocos2d.demo D JS: 登陆时间 1752490921479 2025-07-14 19:02:01.482 5451-5478 jswrapper org.cocos2d.demo D JS: [game-logger] 发送埋点 _uma.custom.gameProgress 章节1_0波 2025-07-14 19:02:01.484 5451-5478 jswrapper org.cocos2d.demo D JS: [game-logger] UIManager open view: UI_GameView 2025-07-14 19:02:01.535 5451-5478 AudioPlayerProvider org.cocos2d.demo I deviceSampleRate: 48000, bufferSizeInFrames: 192 2025-07-14 19:02:01.535 5451-5478 AudioPlayerProvider org.cocos2d.demo D Android API level: 28 2025-07-14 19:02:01.535 5451-5478 AudioMixerController org.cocos2d.demo V In the constructor of AudioMixerController! 2025-07-14 19:02:01.535 5451-5478 <no-tag> org.cocos2d.demo D PlayerBase::PlayerBase() 2025-07-14 19:02:01.535 5451-5478 <no-tag> org.cocos2d.demo D TrackPlayerBase::TrackPlayerBase() 2025-07-14 19:02:01.536 5451-5478 libOpenSLES org.cocos2d.demo I Emulating old channel mask behavior (ignoring positional mask 0x3, using default mask 0x3 based on channel count of 2) 2025-07-14 19:02:01.536 1434-5232 AudioFlinger audioserver W createTrack_l(): mismatch between requested flags (00000104) and output flags (00000002) 2025-07-14 19:02:01.536 1434-5232 AudioFlinger audioserver D Client defaulted notificationFrames to 960 for frameCount 2052 2025-07-14 19:02:01.537 5451-5478 AudioTrack org.cocos2d.demo W AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount 0 -> 2052 2025-07-14 19:02:01.538 1707-2033 bt_btif com.android.bluetooth E register_notification_rsp: Avrcp device is not connected, handle: 0x0 2025-07-14 19:02:01.538 1707-2033 chatty com.android.bluetooth I uid=1002(bluetooth) BluetoothAvrcpH identical 4 lines 2025-07-14 19:02:01.538 1707-2033 bt_btif com.android.bluetooth E register_notification_rsp: Avrcp device is not connected, handle: 0x0 2025-07-14 19:02:01.535 1413-1413 writer [email protected] I type=1400 audit(0.0:1143): avc: denied { ioctl } for path="/dev/fastpipe" dev="tmpfs" ino=7232 ioctlcmd=6869 scontext=u:r:hal_audio_default:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1 2025-07-14 19:02:01.538 1413-2919 audio_hw_hal [email protected] D raw_start_output_stream, stream=0xf5f1b000, sampleRate=48000, channel=2, bps=16, bufSize=4096 2025-07-14 19:02:01.539 5451-5478 AudioEngineImpl org.cocos2d.demo V play2d, _audioPlayers.size=0 2025-07-14 19:02:01.539 5451-5478 AudioPlayerProvider org.cocos2d.demo V (@assets/assets/game/native/c1/c1e23d2f-b7dc-44d4-91a4-8774e9abf939.261eb.mp3) file size: 179648 2025-07-14 19:02:01.540 5451-5478 UrlAudioPlayer org.cocos2d.demo V Current UrlAudioPlayer instance count: 1 2025-07-14 19:02:01.540 5451-5478 UrlAudioPlayer org.cocos2d.demo V UrlAudioPlayer::prepare: @assets/assets/game/native/c1/c1e23d2f-b7dc-44d4-91a4-8774e9abf939.261eb.mp3, SL_DATALOCATOR_ANDROIDFD, 98, 6980012, 179648 2025-07-14 19:02:01.540 5451-5478 <no-tag> org.cocos2d.demo D PlayerBase::PlayerBase() 2025-07-14 19:02:01.540 5451-5478 <no-tag> org.cocos2d.demo D TrackPlayerBase::TrackPlayerBase() 2025-07-14 19:02:01.541 1452-2087 NuPlayerDriver mediaserver D NuPlayerDriver(0xf4419800) created, clientPid(5451) 2025-07-14 19:02:01.542 1452-5511 GenericSource mediaserver D FileSource remote 2025-07-14 19:02:01.535 1413-1413 writer [email protected] W type=1300 audit(0.0:1143): arch=40000003 syscall=54 per=8 success=yes exit=0 a0=6 a1=80046869 a2=f5f0f020 a3=f5f0f020 items=0 ppid=1 auid=4294967295 uid=1041 gid=1005 euid=1041 suid=1041 fsuid=1041 egid=1005 sgid=1005 fsgid=1005 tty=(none) ses=4294967295 exe="/system/vendor/bin/hw/[email protected]" subj=u:r:hal_audio_default:s0 key=(null) 2025-07-14 19:02:01.544 1452-5510 NuPlayerDriver mediaserver D notifyListener_l(0xf4419800), (1, 0, 0, -1), loop setting(0, 0) 2025-07-14 19:02:01.535 1362-1362 auditd pid-1362 W type=1327 audit(0.0:1143): proctitle="/vendor/bin/hw/[email protected]" 2025-07-14 19:02:01.545 1452-2087 NuPlayerDriver mediaserver D start(0xf4419800), state is 4, eos is 0 2025-07-14 19:02:01.545 1452-5510 GenericSource mediaserver I start 2025-07-14 19:02:01.547 1452-5514 OMXClient mediaserver I IOmx service obtained 2025-07-14 19:02:01.547 1458-1458 OMXMaster media.codec I makeComponentInstance(OMX.google.mp3.decoder) in [email protected] process 2025-07-14 19:02:01.548 1458-1458 OMXNodeInstance media.codec E setConfig(0xf4f2c120:google.mp3.decoder, ConfigPriority(0x6f800002)) ERROR: Undefined(0x80001001) 2025-07-14 19:02:01.548 1452-5514 ACodec mediaserver I codec does not support config priority (err -2147483648) 2025-07-14 19:02:01.548 1458-1458 OMXNodeInstance media.codec E getConfig(0xf4f2c120:google.mp3.decoder, ConfigAndroidVendorExtension(0x6f100004)) ERROR: Undefined(0x80001001) 2025-07-14 19:02:01.549 1452-5514 MediaCodec mediaserver I MediaCodec will operate in async mode 2025-07-14 19:02:01.549 1410-1410 AshmemAllocator [email protected] W ashmem_create_region(8192) returning hidl_memory(0x76391702c100, 8192) 2025-07-14 19:02:01.550 1410-1410 chatty [email protected] I uid=1000(system) [email protected] identical 2 lines 2025-07-14 19:02:01.550 1410-1410 AshmemAllocator [email protected] W ashmem_create_region(8192) returning hidl_memory(0x76391702c100, 8192) 2025-07-14 19:02:01.551 1410-1410 AshmemAllocator [email protected] W ashmem_create_region(9216) returning hidl_memory(0x76391702c100, 9216) 2025-07-14 19:02:01.551 1410-1410 chatty [email protected] I uid=1000(system) [email protected] identical 2 lines 2025-07-14 19:02:01.552 1410-1410 AshmemAllocator [email protected] W ashmem_create_region(9216) returning hidl_memory(0x76391702c100, 9216) 2025-07-14 19:02:01.553 1434-5232 AudioFlinger audioserver W createTrack_l(): mismatch between requested flags (00000008) and output flags (00000002) 2025-07-14 19:02:01.553 1434-5232 AudioFlinger audioserver D Client defaulted notificationFrames to 3760 for frameCount 11280 2025-07-14 19:02:01.554 1452-5510 NuPlayerDriver mediaserver D notifyListener_l(0xf4419800), (6, 0, 0, -1), loop setting(0, 1) 2025-07-14 19:02:01.597 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:01.617 5451-5478 jswrapper org.cocos2d.demo D JS: 背景底图时间差 133 2025-07-14 19:02:01.675 1434-1539 AudioFlinger audioserver D mixer(0xf3483640) throttle end: throttle time(10) 2025-07-14 19:02:01.774 1434-1539 AudioFlinger audioserver D mixer(0xf3483640) throttle end: throttle time(10) 2025-07-14 19:02:01.817 1452-5510 NuPlayerDriver mediaserver D notifyListener_l(0xf4419800), (211, 0, 0, 20), loop setting(0, 1) 2025-07-14 19:02:02.016 5451-5478 jswrapper org.cocos2d.demo D JS: [game-logger] 格子保底数量: 1 2025-07-14 19:02:02.018 5451-5478 jswrapper org.cocos2d.demo D JS: [game-logger] 触发格子保底: 0 2025-07-14 19:02:02.020 5451-5478 chatty org.cocos2d.demo I uid=10051(org.cocos2d.demo) GLThread 168 identical 1 line 2025-07-14 19:02:02.021 5451-5478 jswrapper org.cocos2d.demo D JS: [game-logger] 触发格子保底: 0 2025-07-14 19:02:02.075 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:02.075 1452-5510 NuPlayerDriver mediaserver D notifyListener_l(0xf4419800), (211, 0, 0, 20), loop setting(0, 1) 2025-07-14 19:02:02.203 5451-5478 AudioEngineImpl org.cocos2d.demo V play2d, _audioPlayers.size=1 2025-07-14 19:02:02.203 5451-5478 AudioPlayerProvider org.cocos2d.demo V (@assets/assets/game/native/92/921f296e-e66d-4abd-89b5-5278346f0cd6.d3c80.mp3) file size: 3305 2025-07-14 19:02:02.204 5451-5478 AudioPlayerProvider org.cocos2d.demo V FileInfo (0x763874c2e030), Waiting preload (@assets/assets/game/native/92/921f296e-e66d-4abd-89b5-5278346f0cd6.d3c80.mp3) to finish ... 2025-07-14 19:02:02.204 5451-5506 AudioPlayerProvider org.cocos2d.demo V AudioPlayerProvider::preloadEffect: (@assets/assets/game/native/92/921f296e-e66d-4abd-89b5-5278346f0cd6.d3c80.mp3) 2025-07-14 19:02:02.204 5451-5506 AudioDecoderProvider org.cocos2d.demo V url:@assets/assets/game/native/92/921f296e-e66d-4abd-89b5-5278346f0cd6.d3c80.mp3, extension:.mp3 2025-07-14 19:02:02.204 5451-5506 AudioDecoderMp3 org.cocos2d.demo V Create AudioDecoderMp3 2025-07-14 19:02:02.205 5451-5506 mp3reader org.cocos2d.demo V skipped ID3 tag, new starting offset is 172 (0x00000000000000ac) 2025-07-14 19:02:02.205 5451-5506 mp3reader org.cocos2d.demo V subsequent header is fff38064 2025-07-14 19:02:02.205 5451-5506 mp3reader org.cocos2d.demo V found subsequent frame #2 at 380 2025-07-14 19:02:02.205 5451-5506 mp3reader org.cocos2d.demo V subsequent header is fff38264 2025-07-14 19:02:02.205 5451-5506 mp3reader org.cocos2d.demo V found subsequent frame #3 at 588 2025-07-14 19:02:02.205 5451-5506 mp3reader org.cocos2d.demo V subsequent header is fff38264 2025-07-14 19:02:02.205 5451-5506 mp3reader org.cocos2d.demo V found subsequent frame #4 at 797 2025-07-14 19:02:02.245 5451-5506 AudioDecoderMp3 org.cocos2d.demo I Original audio info: numChannels: 2, sampleRate: 22050, bitPerSample: 16, containerSize: 16, channelMask: 3, endianness: 2, numFrames: 8640, duration: 0.391837, total size: 34560 2025-07-14 19:02:02.245 5451-5506 AudioDecoder org.cocos2d.demo D Decoding (@assets/assets/game/native/92/921f296e-e66d-4abd-89b5-5278346f0cd6.d3c80.mp3) to pcm data wasted 40.580002ms 2025-07-14 19:02:02.245 5451-5506 AudioDecoder org.cocos2d.demo V Resample: 22050 --> 48000 2025-07-14 19:02:02.245 5451-5506 AudioResampler org.cocos2d.demo V resampler load 0 -> 6 MHz due to delta +6 MHz from quality 2 2025-07-14 19:02:02.245 5451-5506 AudioResampler org.cocos2d.demo V Create cubic Resampler 2025-07-14 19:02:02.245 5451-5506 AudioDecoder org.cocos2d.demo V resample() 18808 output frames 2025-07-14 19:02:02.247 5451-5506 AudioDecoder org.cocos2d.demo V outFrames: 18808 2025-07-14 19:02:02.247 5451-5506 AudioDecoder org.cocos2d.demo V resample() complete 2025-07-14 19:02:02.247 5451-5506 AudioDecoder org.cocos2d.demo V reset() complete 2025-07-14 19:02:02.247 5451-5506 AudioResampler org.cocos2d.demo V resampler load 6 -> 0 MHz due to delta -6 MHz from quality 2 2025-07-14 19:02:02.252 5451-5506 AudioDecoder org.cocos2d.demo V pcm buffer size: 75232 2025-07-14 19:02:02.254 5451-5506 AudioDecoder org.cocos2d.demo D Resampling (@assets/assets/game/native/92/921f296e-e66d-4abd-89b5-5278346f0cd6.d3c80.mp3) wasted 8.943000ms 2025-07-14 19:02:02.254 5451-5506 AudioDecoder org.cocos2d.demo I Audio channel count is 2, no need to interleave 2025-07-14 19:02:02.254 5451-5506 AudioDecoder org.cocos2d.demo D Interleave (@assets/assets/game/native/92/921f296e-e66d-4abd-89b5-5278346f0cd6.d3c80.mp3) wasted 0.104000ms 2025-07-14 19:02:02.254 5451-5506 AudioPlayerProvider org.cocos2d.demo V decode succeed 2025-07-14 19:02:02.254 5451-5506 AudioPlayerProvider org.cocos2d.demo V preload (@assets/assets/game/native/92/921f296e-e66d-4abd-89b5-5278346f0cd6.d3c80.mp3) callback count: 1 2025-07-14 19:02:02.254 5451-5506 AudioPlayerProvider org.cocos2d.demo V FileInfo (0x763874c2e030), Set isSucceed flag: 1, path: @assets/assets/game/native/92/921f296e-e66d-4abd-89b5-5278346f0cd6.d3c80.mp3 2025-07-14 19:02:02.254 5451-5478 AudioPlayerProvider org.cocos2d.demo V FileInfo (0x763874c2e030), Waitup preload (@assets/assets/game/native/92/921f296e-e66d-4abd-89b5-5278346f0cd6.d3c80.mp3) ... 2025-07-14 19:02:02.254 5451-5506 AudioDecoder org.cocos2d.demo V ~AudioDecoder() 0x7638889762f0 2025-07-14 19:02:02.255 5451-5478 PcmAudioPlayer org.cocos2d.demo V PcmAudioPlayer constructor: 0x76387a63e020 2025-07-14 19:02:02.255 5451-5478 AssetFd org.cocos2d.demo V ~AssetFd: 11 2025-07-14 19:02:02.255 5451-5478 PcmAudioPlayer org.cocos2d.demo V PcmAudioPlayer (0x76387a63e020) play, url: @assets/assets/game/native/92/921f296e-e66d-4abd-89b5-5278346f0cd6.d3c80.mp3 2025-07-14 19:02:02.301 5451-5478 jswrapper org.cocos2d.demo D JS: [game-logger] 1334 2025-07-14 19:02:02.332 1452-5510 NuPlayerDriver mediaserver D notifyListener_l(0xf4419800), (211, 0, 0, 20), loop setting(0, 1) 2025-07-14 19:02:02.409 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:02.590 1452-5510 NuPlayerDriver mediaserver D notifyListener_l(0xf4419800), (211, 0, 0, 20), loop setting(0, 1) 2025-07-14 19:02:02.617 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:02.636 5451-5478 chatty org.cocos2d.demo I uid=10051(org.cocos2d.demo) GLThread 168 identical 1 line 2025-07-14 19:02:02.660 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:02.677 5451-5507 AudioMixerController org.cocos2d.demo V Play over ... 2025-07-14 19:02:02.677 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:02.677 5451-5507 AudioMixerController org.cocos2d.demo V Doesn't have enough tracks: 1, 1 2025-07-14 19:02:02.680 5451-5478 AudioEngineImpl org.cocos2d.demo V Removing player id=1, state:5 2025-07-14 19:02:02.680 5451-5478 PcmAudioPlayer org.cocos2d.demo V In the destructor of PcmAudioPlayer (0x76387a63e020) 2025-07-14 19:02:02.680 5451-5478 Track org.cocos2d.demo V ~Track(): 0x7638705f4880 2025-07-14 19:02:02.690 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:02.774 5451-5478 chatty org.cocos2d.demo I uid=10051(org.cocos2d.demo) GLThread 168 identical 7 lines 2025-07-14 19:02:02.787 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:02.789 1411-1411 healthd healthd I type=1400 audit(0.0:1144): avc: denied { read } for name="present" dev="sysfs" ino=6625 scontext=u:r:healthd:s0 tcontext=u:object_r:sysfs:s0 tclass=file permissive=1 2025-07-14 19:02:02.789 1411-1411 healthd healthd I type=1400 audit(0.0:1144): avc: denied { open } for path="/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/PNP0C0A:00/power_supply/BAT0/present" dev="sysfs" ino=6625 scontext=u:r:healthd:s0 tcontext=u:object_r:sysfs:s0 tclass=file permissive=1 2025-07-14 19:02:02.789 1411-1411 healthd healthd W type=1300 audit(0.0:1144): arch=c000003e syscall=257 success=yes exit=9 a0=ffffff9c a1=763917028360 a2=a0000 a3=0 items=0 ppid=1 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 exe="/system/bin/healthd" subj=u:r:healthd:s0 key=(null) 2025-07-14 19:02:02.797 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:02.823 5451-5478 chatty org.cocos2d.demo I uid=10051(org.cocos2d.demo) GLThread 168 identical 2 lines 2025-07-14 19:02:02.834 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 2025-07-14 19:02:02.848 1452-5510 NuPlayerDriver mediaserver D notifyListener_l(0xf4419800), (211, 0, 0, 20), loop setting(0, 1) 2025-07-14 19:02:02.848 5451-5478 HostConnection org.cocos2d.demo D glGetError exceeded. 解决问题了吗

PS E:\workspace\Android\MyApplication> adb logcat -s SRReader:V BluetoothUtils:V *:S adb server version (41) doesn't match this client (36); killing... * daemon started successfully * --------- beginning of main 03-20 20:12:29.868 6234 6474 D BluetoothUtils: Bluetooth device F88 doesn't have exclusive manager 03-20 20:12:29.869 6234 6474 D BluetoothUtils: Bluetooth device Auto Bluetooth doesn't have exclusive manager 03-20 20:12:29.870 6234 6474 D BluetoothUtils: Bluetooth device S9 doesn't have exclusive manager 03-20 20:12:29.871 6234 6474 D BluetoothUtils: Bluetooth device sanag Z50S Pro Max doesn't have exclusive manager 03-20 20:12:29.872 6234 6474 D BluetoothUtils: Bluetooth device SYNC doesn't have exclusive manager 03-20 20:12:29.892 6234 6474 D BluetoothUtils: Bluetooth device F88 doesn't have exclusive manager 03-20 20:12:29.893 6234 6474 D BluetoothUtils: Bluetooth device Auto Bluetooth doesn't have exclusive manager 03-20 20:12:29.894 6234 6474 D BluetoothUtils: Bluetooth device S9 doesn't have exclusive manager 03-20 20:12:29.895 6234 6474 D BluetoothUtils: Bluetooth device sanag Z50S Pro Max doesn't have exclusive manager 03-20 20:12:29.896 6234 6474 D BluetoothUtils: Bluetooth device SYNC doesn't have exclusive manager 03-20 20:12:55.831 24306 24990 E BluetoothUtils: isDeepDozeMode? false 03-20 20:12:58.809 24306 24990 E BluetoothUtils: isDeepDozeMode? false 03-20 20:13:19.330 24306 24990 E BluetoothUtils: isDeepDozeMode? false 03-20 20:13:33.980 24306 24990 E BluetoothUtils: isDeepDozeMode? false 03-20 20:13:44.525 24306 24642 D BluetoothUtils: isSupportBluetoothRestrict = 1 03-20 20:13:45.031 17621 17621 I SRReader: JNI_OnLoad 03-20 20:13:51.865 17621 17621 I SRReader: CardPowerOn 03-20 20:13:51.865 17621 17621 I SRReader: sendData:55 AA 02 00 11 00 11 03-20 20:14:34.029 24306 24990 E BluetoothUtils: isDeepDozeMode? false 03-20 20:14:52.287 24306 24990 E BluetoothUtils: isDeepDozeMode? false 03-20 20:14:52.619 24306 24990 E BluetoothUtils: isDeepDozeMode? false 03-20 20:14:52.630 24306 24990 E BluetoothUtils: isDeepDozeMode? false 03-20 20:14:52.798 24306 24990 E BluetoothUtils: isDeepDozeMode? false

plugins { id 'com.android.application' } apply from: 'jacoco-report.gradle' def cfg = rootProject.ext.configuration android { compileSdk cfg.targetSdk defaultConfig { applicationId cfg.applicationId minSdk cfg.minSdk targetSdk cfg.targetSdk versionCode cfg.versionCode versionName cfg.versionName } signingConfigs { release { storeFile file("$rootDir/platform.jks") storePassword = "123456" keyPassword = "123456" keyAlias = "ktplatfrom" } debug { storeFile file("$rootDir/platform.jks") storePassword = "123456" keyPassword = "123456" keyAlias = "ktplatfrom" } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } debugCoverage { minifyEnabled false testCoverageEnabled false } } // buildTypes { // release { // minifyEnabled false // signingConfig signingConfigs.release // } // debug { // minifyEnabled false // signingConfig signingConfigs.debug // debuggable true // testCoverageEnabled false // } // } applicationVariants.all { variant -> variant.outputs.all { output -> def newName = "ktLauncher.apk" outputFileName = newName } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } dataBinding { enabled = true } buildFeatures { aidl true } //儿童模式 flavorDimensions "default" productFlavors { _NORMAL_MODE { buildConfigField("int", "user_model", "0") } _CHILD_MODE { buildConfigField("int", "user_model", '1') } } testOptions { unitTests { includeAndroidResources = true returnDefaultValues = true } } } gradle.projectsEvaluated { tasks.withType(JavaCompile) { Set<File> fileSet = options.bootstrapClasspath.getFiles() List<File> newFileList = new ArrayList<>(); //将framework.jar插入到最前面 newFileList.add(new File("libs/framework.jar")) //最后将原始的数据插入 newFileList.addAll(fileSet) options.bootstrapClasspath = files( newFileList.toArray() ) } } dependencies { // api fileTree(include: ['*.jar'], dir: 'libs') implementation rootProject.ext.dependencies["appcompat"] implementation rootProject.ext.dependencies["material"] implementation rootProject.ext.dependencies["constraintlayout"] implementation rootProject.ext.dependencies["lifecycle-extensions"] implementation rootProject.ext.dependencies["gson"] implementation project(':base') compileOnly files('libs/framework.jar') implementation 'com.github.bumptech.glide:glide:4.12.0' implementation 'com.android.support:design:28.0.0' implementation "androidx.constraintlayout:constraintlayout:2.1.3" annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' // test testImplementation 'org.powermock:powermock-module-junit4:2.0.7' testImplementation 'org.powermock:powermock-module-junit4-rule:1.7.4' testImplementation 'org.powermock:powermock-api-mockito2:2.0.7' testImplementation 'org.mockito:mockito-core:3.3.3' testImplementation 'android.arch.core:core-testing:1.1.1' testImplementation 'org.mockito:mockito-inline:3.11.2' } -----build.gradle----------- apply plugin: 'jacoco' //gradlew clean & gradlew createOfflineTestCoverageReport & gradlew jacocoTestReport tasks.withType(Test) { jacoco.includeNoLocationClasses = true jacoco.excludes = ['jdk.internal.*'] } configurations { jacocoAnt jacocoRuntime } jacoco { toolVersion = "0.8.5" } def offline_instrumented_outputDir = "$buildDir.path/intermediates/classes-instrumented/debugCoverage" tasks.withType(Test) { jacoco.includeNoLocationClasses = true jacoco.excludes = ['jdk.internal.*'] } def coverageSourceDirs = [ 'src/main/java' ] task jacocoTestReport(type: JacocoReport, dependsOn: "test") { group = "Reporting" description = "Generate Jacoco coverage reports" classDirectories.from = fileTree( dir: './build/intermediates/javac/debugCoverage/classes/', excludes: [ '**/R.class', '**/R$*.class', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*', '**/BuildConfig.*', '**/**Bean.class', '**/inputmethod/*', '**/config/*.*', '**/flex/*.*', '**/AssetsUtils.class' ] ) getSourceDirectories().setFrom(files(coverageSourceDirs)) getExecutionData().setFrom(files('./build/jacoco/testDebugUnitTest.exec')) } jacocoTestReport { reports { xml.enabled true html.enabled true html.destination file("build/test-results/jacocoHtml") } } /* This task is used to create offline instrumentation of classes for on-the-fly instrumentation coverage tool like Jacoco. See jacoco classId * and Offline Instrumentation from the jacoco site for more info. * * In this case, some classes mocked using PowerMock were reported as 0% coverage on jacoco & Sonarqube. The issue between PowerMock and jacoco * is well documented, and a possible solution is offline Instrumentation (not so well documented for gradle). * * In a nutshell, this task: * - Pre-instruments the original *.class files * - Puts the instrumented classes path at the beginning of the task's classpath (for report purposes) * - Runs test & generates a new exec file based on the pre-instrumented classes -- as opposed to on-the-fly instrumented class files generated by jacoco. * * It is currently not implemented to run prior to any other existing tasks (like test, jacocoTestReport, etc...), therefore, it should be called * explicitly if Offline Instrumentation report is needed. * * Usage: gradle clean & gradle createOfflineInstrTestCoverageReport & gradle jacocoTestReport * - gradle clean //To prevent influence from any previous task execution * - gradle createOfflineInstrTestCoverageReport //To generate *.exec file from offline instrumented class * - gradle jacocoTestReport //To generate html report from newly created *.exec task */ task createOfflineTestCoverageReport(dependsOn: ['instrument', 'testDebugCoverageUnitTest']) { group = "reporting" doLast { ant.taskdef(name: 'report', classname: 'org.jacoco.ant.ReportTask', classpath: configur3+ations.jacocoAnt.asPath) ant.report() { executiondata { ant.file(file: "$buildDir.path/jacoco/testDebugCoverageUnitTest.exec") } structure(name: 'Example') { classfiles { fileset(dir: "$project.buildDir/intermediates/javac/debugCoverage") } sourcefiles { fileset(dir: 'src/main/java') } } //Uncomment if we want the task to generate jacoco html reports. However, the current script does not exclude files. //An alternative is to used jacocoTestReport after this task finishes //html(destdir: "$buildDir.path/reports/jacocoHtml") } } } createOfflineTestCoverageReport.dependsOn(clean) /* * Part of the Offline Instrumentation process is to add the jacoco runtime to the class path along with the path of the instrumented files. */ gradle.taskGraph.whenReady { graph -> if (graph.hasTask(instrument)) { tasks.withType(Test) { doFirst { systemProperty 'jacoco-agent.destfile', buildDir.path + '/jacoco/testDebugCoverageUnitTest.exec' classpath = files(offline_instrumented_outputDir) + classpath + configurations.jacocoRuntime } } } } /* * Instruments the classes per se */ task instrument(dependsOn:'compileDebugUnitTestSources') { doLast { println 'Instrumenting classes' ant.taskdef(name: 'instrument', classname: 'org.jacoco.ant.InstrumentTask', classpath: configurations.jacocoAnt.asPath) ant.instrument(destdir: offline_instrumented_outputDir) { fileset(dir: "$buildDir.path/intermediates/javac/debugCoverage") } } } -----jacoco-report.gradle--------------- jacoco-report.gradle 在同一个项目中的base模块可以正常生成jacoco单元测试覆盖率报告,但是在app模块无法生成,build文件夹中,都没有jacoco和 test-results文件夹。上述的jacoco-report.gradle和build.gradle是app模块的内容 请问应该如何解决app模块无法显示jacoco报告的问题i

7-3 Score Processing 分数 10 作者 翁恺 单位 浙江大学 Write a program to process students score data. The input of your program has lines of text, in one of the two formats: Student's name and student id, as <student id>, <name>, and Score for one student of one course, as <student id>, <course name>, <marks>. Example of the two formats are: 3190101234, Zhang San 3190101111, Linear Algebra, 89.5 Comma is used as the seperator of each field, and will never be in any of the fields. Notice that there are more than one word for name of the person and name of the course. To make your code easier, the score can be treated as double. The number of the students and the number of the courses are not known at the beginning. The number of lines are not known at the beginning either. The lines of different format appear in no order. One student may not get enrolled in every course. Your program should read every line in and print out a table of summary in .csv format. The first line of the output is the table head, consists fields like this: student id, name, <course name 1>, <course name 2>, ..., average where the course names are all the courses read, in alphabet order. There should be one space after each comma. Then each line of the output is data for one student, in the ascended order of their student id, with score of each course, like: 3190101234, Zhang San, 85.0, , 89.5, , , 87.3 For the course that hasn't been enrolled, leave a blank before the comma, and should not get included in the average. The average has one decimal place. There should be one space after each comma. And the last line of the output is a summary line for average score of every course, like: , , 76.2, 87.4, , , 76.8 All the number output, including the averages have one decimal place. Input Format As described in the text above. Output Format As described in the text above. The standard output is generated by a program compiled by gcc, that the round of the first decimal place is in the "gcc way". Sample Input 3180111435, Operating System, 34.5 3180111430, Linear Algebra, 80 3180111435, Jessie Zhao 3180111430, Zhiwen Yang 3180111430, Computer Architecture, 46.5 3180111434, Linear Algebra, 61.5 3180111434, Anna Teng Sample Output student id, name, Computer Architecture, Linear Algebra, Operating System, average 3180111430, Zhiwen Yang, 46.5, 80.0, , 63.2 3180111434, Anna Teng, , 61.5, , 61.5 3180111435, Jessie Zhao, , , 34.5, 34.5 , , 46.5, 70.8, 34.

/* This is a library written for the BNO080 SparkFun sells these at its website: www.sparkfun.com Do you like this library? Help support SparkFun. Buy a board! https://www.sparkfun.com/products/14586 Written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017 The BNO080 IMU is a powerful triple axis gyro/accel/magnetometer coupled with an ARM processor to maintain and complete all the complex calculations for various VR, inertial, step counting, and movement operations. This library handles the initialization of the BNO080 and is able to query the sensor for different readings. https://github.com/sparkfun/SparkFun_BNO080_Arduino_Library Development environment specifics: Arduino IDE 1.8.3 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "SparkFun_BNO080_Arduino_Library.h" //Attempt communication with the device //Return true if we got a 'Polo' back from Marco boolean BNO080::begin(uint8_t deviceAddress, TwoWire &wirePort) { _deviceAddress = deviceAddress; //If provided, store the I2C address from user _i2cPort = &wirePort; //Grab which port the user wants us to use //We expect caller to begin their I2C port, with the speed of their choice external to the library //But if they forget, we start the hardware here. _i2cPort->begin(); //Begin by resetting the IMU softReset(); //Check communication with device shtpData[0] = SHTP_REPORT_PRODUCT_ID_REQUEST; //Request the product ID and reset info shtpData[1] = 0; //Reserved //Transmit packet on channel 2, 2 bytes sendPacket(CHANNEL_CONTROL, 2); //Now we wait for response if (receivePacket() == true) { if (shtpData[0] == SHTP_REPORT_PRODUCT_ID_RESPONSE) { return(true); } } return(false); //Something went wrong } //Calling this function with nothing sets the debug port to Serial //You can also call it with other streams like Serial1, SerialUSB, etc. void BNO080::enableDebugging(Stream &debugPort) { _debugPort = &debugPort; _printDebug = true; } //Updates the latest variables if possible //Returns false if new readings are not available bool BNO080::dataAvailable(void) { if (receivePacket() == true) { //Check to see if this packet is a sensor reporting its data to us if (shtpHeader[2] == CHANNEL_REPORTS && shtpData[0] == SHTP_REPORT_BASE_TIMESTAMP) { parseInputReport(); //This will update the rawAccelX, etc variables depending on which feature report is found return(true); } } return(false); } //This function pulls the data from the input report //The input reports vary in length so this function stores the various 16-bit values as globals //Unit responds with packet that contains the following: //shtpHeader[0:3]: First, a 4 byte header //shtpData[0:4]: Then a 5 byte timestamp of microsecond clicks since reading was taken //shtpData[5 + 0]: Then a feature report ID (0x01 for Accel, 0x05 for Rotation Vector) //shtpData[5 + 1]: Sequence number (See 6.5.18.2) //shtpData[5 + 2]: Status //shtpData[3]: Delay //shtpData[4:5]: i/accel x/gyro x/etc //shtpData[6:7]: j/accel y/gyro y/etc //shtpData[8:9]: k/accel z/gyro z/etc //shtpData[10:11]: real/gyro temp/etc //shtpData[12:13]: Accuracy estimate void BNO080::parseInputReport(void) { //Calculate the number of data bytes in this packet int16_t dataLength = ((uint16_t)shtpHeader[1] << 8 | shtpHeader[0]); dataLength &= ~(1 << 15); //Clear the MSbit. This bit indicates if this package is a continuation of the last. //Ignore it for now. TODO catch this as an error and exit dataLength -= 4; //Remove the header bytes from the data count uint8_t status = shtpData[5 + 2] & 0x03; //Get status bits uint16_t data1 = (uint16_t)shtpData[5 + 5] << 8 | shtpData[5 + 4]; uint16_t data2 = (uint16_t)shtpData[5 + 7] << 8 | shtpData[5 + 6]; uint16_t data3 = (uint16_t)shtpData[5 + 9] << 8 | shtpData[5 + 8]; uint16_t data4 = 0; uint16_t data5 = 0; if(dataLength - 5 > 9) { data4= (uint16_t)shtpData[5 + 11] << 8 | shtpData[5 + 10]; } if(dataLength - 5 > 11) { data5 = (uint16_t)shtpData[5 + 13] << 8 | shtpData[5 + 12]; } //Store these generic values to their proper global variable if(shtpData[5] == SENSOR_REPORTID_ACCELEROMETER) { accelAccuracy = status; rawAccelX = data1; rawAccelY = data2; rawAccelZ = data3; } else if(shtpData[5] == SENSOR_REPORTID_LINEAR_ACCELERATION) { accelLinAccuracy = status; rawLinAccelX = data1; rawLinAccelY = data2; rawLinAccelZ = data3; } else if(shtpData[5] == SENSOR_REPORTID_GYROSCOPE) { gyroAccuracy = status; rawGyroX = data1; rawGyroY = data2; rawGyroZ = data3; } else if(shtpData[5] == SENSOR_REPORTID_MAGNETIC_FIELD) { magAccuracy = status; rawMagX = data1; rawMagY = data2; rawMagZ = data3; } else if(shtpData[5] == SENSOR_REPORTID_ROTATION_VECTOR || shtpData[5] == SENSOR_REPORTID_GAME_ROTATION_VECTOR) { quatAccuracy = status; rawQuatI = data1; rawQuatJ = data2; rawQuatK = data3; rawQuatReal = data4; rawQuatRadianAccuracy = data5; //Only available on rotation vector, not game rot vector } else if(shtpData[5] == SENSOR_REPORTID_STEP_COUNTER) { stepCount = data3; //Bytes 8/9 } else if(shtpData[5] == SENSOR_REPORTID_STABILITY_CLASSIFIER) { stabilityClassifier = shtpData[5 + 4]; //Byte 4 only } else if(shtpData[5] == SENSOR_REPORTID_PERSONAL_ACTIVITY_CLASSIFIER) { activityClassifier = shtpData[5 + 5]; //Most likely state //Load activity classification confidences into the array for(uint8_t x = 0 ; x < 9 ; x++) //Hardcoded to max of 9. TODO - bring in array size _activityConfidences[x] = shtpData[5 + 6 + x]; //5 bytes of timestamp, byte 6 is first confidence byte } else { //This sensor report ID is unhandled. //See reference manual to add additional feature reports as needed } //TODO additional feature reports may be strung together. Parse them all. } //Return the rotation vector quaternion I float BNO080::getQuatI() { float quat = qToFloat(rawQuatI, rotationVector_Q1); return(quat); } //Return the rotation vector quaternion J float BNO080::getQuatJ() { float quat = qToFloat(rawQuatJ, rotationVector_Q1); return(quat); } //Return the rotation vector quaternion K float BNO080::getQuatK() { float quat = qToFloat(rawQuatK, rotationVector_Q1); return(quat); } //Return the rotation vector quaternion Real float BNO080::getQuatReal() { float quat = qToFloat(rawQuatReal, rotationVector_Q1); return(quat); } //Return the rotation vector accuracy float BNO080::getQuatRadianAccuracy() { float quat = qToFloat(rawQuatRadianAccuracy, rotationVector_Q1); return(quat); } //Return the acceleration component uint8_t BNO080::getQuatAccuracy() { return(quatAccuracy); } //Return the acceleration component float BNO080::getAccelX() { float accel = qToFloat(rawAccelX, accelerometer_Q1); return(accel); } //Return the acceleration component float BNO080::getAccelY() { float accel = qToFloat(rawAccelY, accelerometer_Q1); return(accel); } //Return the acceleration component float BNO080::getAccelZ() { float accel = qToFloat(rawAccelZ, accelerometer_Q1); return(accel); } //Return the acceleration component uint8_t BNO080::getAccelAccuracy() { return(accelAccuracy); } // linear acceleration, i.e. minus gravity //Return the acceleration component float BNO080::getLinAccelX() { float accel = qToFloat(rawLinAccelX, linear_accelerometer_Q1); return(accel); } //Return the acceleration component float BNO080::getLinAccelY() { float accel = qToFloat(rawLinAccelY, linear_accelerometer_Q1); return(accel); } //Return the acceleration component float BNO080::getLinAccelZ() { float accel = qToFloat(rawLinAccelZ, linear_accelerometer_Q1); return(accel); } //Return the acceleration component uint8_t BNO080::getLinAccelAccuracy() { return(accelLinAccuracy); } //Return the gyro component float BNO080::getGyroX() { float gyro = qToFloat(rawGyroX, gyro_Q1); return(gyro); } //Return the gyro component float BNO080::getGyroY() { float gyro = qToFloat(rawGyroY, gyro_Q1); return(gyro); } //Return the gyro component float BNO080::getGyroZ() { float gyro = qToFloat(rawGyroZ, gyro_Q1); return(gyro); } //Return the gyro component uint8_t BNO080::getGyroAccuracy() { return(gyroAccuracy); } //Return the magnetometer component float BNO080::getMagX() { float mag = qToFloat(rawMagX, magnetometer_Q1); return(mag); } //Return the magnetometer component float BNO080::getMagY() { float mag = qToFloat(rawMagY, magnetometer_Q1); return(mag); } //Return the magnetometer component float BNO080::getMagZ() { float mag = qToFloat(rawMagZ, magnetometer_Q1); return(mag); } //Return the mag component uint8_t BNO080::getMagAccuracy() { return(magAccuracy); } //Return the step count uint16_t BNO080::getStepCount() { return(stepCount); } //Return the stability classifier uint8_t BNO080::getStabilityClassifier() { return(stabilityClassifier); } //Return the activity classifier uint8_t BNO080::getActivityClassifier() { return(activityClassifier); } //Given a record ID, read the Q1 value from the metaData record in the FRS (ya, it's complicated) //Q1 is used for all sensor data calculations int16_t BNO080::getQ1(uint16_t recordID) { //Q1 is always the lower 16 bits of word 7 uint16_t q = readFRSword(recordID, 7) & 0xFFFF; //Get word 7, lower 16 bits return(q); } //Given a record ID, read the Q2 value from the metaData record in the FRS //Q2 is used in sensor bias int16_t BNO080::getQ2(uint16_t recordID) { //Q2 is always the upper 16 bits of word 7 uint16_t q = readFRSword(recordID, 7) >> 16; //Get word 7, upper 16 bits return(q); } //Given a record ID, read the Q3 value from the metaData record in the FRS //Q3 is used in sensor change sensitivity int16_t BNO080::getQ3(uint16_t recordID) { //Q3 is always the upper 16 bits of word 8 uint16_t q = readFRSword(recordID, 8) >> 16; //Get word 8, upper 16 bits return(q); } //Given a record ID, read the resolution value from the metaData record in the FRS for a given sensor float BNO080::getResolution(uint16_t recordID) { //The resolution Q value are 'the same as those used in the sensor's input report' //This should be Q1. int16_t Q = getQ1(recordID); //Resolution is always word 2 uint32_t value = readFRSword(recordID, 2); //Get word 2 float resolution = qToFloat(value, Q); return(resolution); } //Given a record ID, read the range value from the metaData record in the FRS for a given sensor float BNO080::getRange(uint16_t recordID) { //The resolution Q value are 'the same as those used in the sensor's input report' //This should be Q1. int16_t Q = getQ1(recordID); //Range is always word 1 uint32_t value = readFRSword(recordID, 1); //Get word 1 float range = qToFloat(value, Q); return(range); } //Given a record ID and a word number, look up the word data //Helpful for pulling out a Q value, range, etc. //Use readFRSdata for pulling out multi-word objects for a sensor (Vendor data for example) uint32_t BNO080::readFRSword(uint16_t recordID, uint8_t wordNumber) { if(readFRSdata(recordID, wordNumber, 1) == true) //Get word number, just one word in length from FRS return(metaData[0]); //Return this one word return(0); //Error } //Ask the sensor for data from the Flash Record System //See 6.3.6 page 40, FRS Read Request void BNO080::frsReadRequest(uint16_t recordID, uint16_t readOffset, uint16_t blockSize) { shtpData[0] = SHTP_REPORT_FRS_READ_REQUEST; //FRS Read Request shtpData[1] = 0; //Reserved shtpData[2] = (readOffset >> 0) & 0xFF; //Read Offset LSB shtpData[3] = (readOffset >> 8) & 0xFF; //Read Offset MSB shtpData[4] = (recordID >> 0) & 0xFF; //FRS Type LSB shtpData[5] = (recordID >> 8) & 0xFF; //FRS Type MSB shtpData[6] = (blockSize >> 0) & 0xFF; //Block size LSB shtpData[7] = (blockSize >> 8) & 0xFF; //Block size MSB //Transmit packet on channel 2, 8 bytes sendPacket(CHANNEL_CONTROL, 8); } //Given a sensor or record ID, and a given start/stop bytes, read the data from the Flash Record System (FRS) for this sensor //Returns true if metaData array is loaded successfully //Returns false if failure bool BNO080::readFRSdata(uint16_t recordID, uint8_t startLocation, uint8_t wordsToRead) { uint8_t spot = 0; //First we send a Flash Record System (FRS) request frsReadRequest(recordID, startLocation, wordsToRead); //From startLocation of record, read a # of words //Read bytes until FRS reports that the read is complete while (1) { //Now we wait for response while (1) { uint8_t counter = 0; while(receivePacket() == false) { if(counter++ > 100) return(false); //Give up delay(1); } //We have the packet, inspect it for the right contents //See page 40. Report ID should be 0xF3 and the FRS types should match the thing we requested if (shtpData[0] == SHTP_REPORT_FRS_READ_RESPONSE) if ( ( (uint16_t)shtpData[13] << 8 | shtpData[12]) == recordID) break; //This packet is one we are looking for } uint8_t dataLength = shtpData[1] >> 4; uint8_t frsStatus = shtpData[1] & 0x0F; uint32_t data0 = (uint32_t)shtpData[7] << 24 | (uint32_t)shtpData[6] << 16 | (uint32_t)shtpData[5] << 8 | (uint32_t)shtpData[4]; uint32_t data1 = (uint32_t)shtpData[11] << 24 | (uint32_t)shtpData[10] << 16 | (uint32_t)shtpData[9] << 8 | (uint32_t)shtpData[8]; //Record these words to the metaData array if (dataLength > 0) { metaData[spot++] = data0; } if (dataLength > 1) { metaData[spot++] = data1; } if (spot >= MAX_METADATA_SIZE) { if(_printDebug == true) _debugPort->println(F("metaData array over run. Returning.")); return(true); //We have run out of space in our array. Bail. } if (frsStatus == 3 || frsStatus == 6 || frsStatus == 7) { return(true); //FRS status is read completed! We're done! } } } //Send command to reset IC //Read all advertisement packets from sensor //The sensor has been seen to reset twice if we attempt too much too quickly. //This seems to work reliably. void BNO080::softReset(void) { shtpData[0] = 1; //Reset //Attempt to start communication with sensor sendPacket(CHANNEL_EXECUTABLE, 1); //Transmit packet on channel 1, 1 byte //Read all incoming data and flush it delay(50); while (receivePacket() == true) ; delay(50); while (receivePacket() == true) ; } //Get the reason for the last reset //1 = POR, 2 = Internal reset, 3 = Watchdog, 4 = External reset, 5 = Other uint8_t BNO080::resetReason() { shtpData[0] = SHTP_REPORT_PRODUCT_ID_REQUEST; //Request the product ID and reset info shtpData[1] = 0; //Reserved //Transmit packet on channel 2, 2 bytes sendPacket(CHANNEL_CONTROL, 2); //Now we wait for response if (receivePacket() == true) { if (shtpData[0] == SHTP_REPORT_PRODUCT_ID_RESPONSE) { return(shtpData[1]); } } return(0); } //Given a register value and a Q point, convert to float //See https://en.wikipedia.org/wiki/Q_(number_format) float BNO080::qToFloat(int16_t fixedPointValue, uint8_t qPoint) { float qFloat = fixedPointValue; qFloat *= pow(2, qPoint * -1); return (qFloat); } //Sends the packet to enable the rotation vector void BNO080::enableRotationVector(uint16_t timeBetweenReports) { setFeatureCommand(SENSOR_REPORTID_ROTATION_VECTOR, timeBetweenReports); } //Sends the packet to enable the rotation vector void BNO080::enableGameRotationVector(uint16_t timeBetweenReports) { setFeatureCommand(SENSOR_REPORTID_GAME_ROTATION_VECTOR, timeBetweenReports); } //Sends the packet to enable the accelerometer void BNO080::enableAccelerometer(uint16_t timeBetweenReports) { setFeatureCommand(SENSOR_REPORTID_ACCELEROMETER, timeBetweenReports); } //Sends the packet to enable the accelerometer void BNO080::enableLinearAccelerometer(uint16_t timeBetweenReports) { setFeatureCommand(SENSOR_REPORTID_LINEAR_ACCELERATION, timeBetweenReports); } //Sends the packet to enable the gyro void BNO080::enableGyro(uint16_t timeBetweenReports) { setFeatureCommand(SENSOR_REPORTID_GYROSCOPE, timeBetweenReports); } //Sends the packet to enable the magnetometer void BNO080::enableMagnetometer(uint16_t timeBetweenReports) { setFeatureCommand(SENSOR_REPORTID_MAGNETIC_FIELD, timeBetweenReports); } //Sends the packet to enable the step counter void BNO080::enableStepCounter(uint16_t timeBetweenReports) { setFeatureCommand(SENSOR_REPORTID_STEP_COUNTER, timeBetweenReports); } //Sends the packet to enable the Stability Classifier void BNO080::enableStabilityClassifier(uint16_t timeBetweenReports) { setFeatureCommand(SENSOR_REPORTID_STABILITY_CLASSIFIER, timeBetweenReports); } //Sends the packet to enable the various activity classifiers void BNO080::enableActivityClassifier(uint16_t timeBetweenReports, uint32_t activitiesToEnable, uint8_t (&activityConfidences)[9]) { _activityConfidences = activityConfidences; //Store pointer to array setFeatureCommand(SENSOR_REPORTID_PERSONAL_ACTIVITY_CLASSIFIER, timeBetweenReports, activitiesToEnable); } //Sends the commands to begin calibration of the accelerometer void BNO080::calibrateAccelerometer() { sendCalibrateCommand(CALIBRATE_ACCEL); } //Sends the commands to begin calibration of the gyro void BNO080::calibrateGyro() { sendCalibrateCommand(CALIBRATE_GYRO); } //Sends the commands to begin calibration of the magnetometer void BNO080::calibrateMagnetometer() { sendCalibrateCommand(CALIBRATE_MAG); } //Sends the commands to begin calibration of the planar accelerometer void BNO080::calibratePlanarAccelerometer() { sendCalibrateCommand(CALIBRATE_PLANAR_ACCEL); } //See 2.2 of the Calibration Procedure document 1000-4044 void BNO080::calibrateAll() { sendCalibrateCommand(CALIBRATE_ACCEL_GYRO_MAG); } void BNO080::endCalibration() { sendCalibrateCommand(CALIBRATE_STOP); //Disables all calibrations } //Given a sensor's report ID, this tells the BNO080 to begin reporting the values void BNO080::setFeatureCommand(uint8_t reportID, uint16_t timeBetweenReports) { setFeatureCommand(reportID, timeBetweenReports, 0); //No specific config } //Given a sensor's report ID, this tells the BNO080 to begin reporting the values //Also sets the specific config word. Useful for personal activity classifier void BNO080::setFeatureCommand(uint8_t reportID, uint16_t timeBetweenReports, uint32_t specificConfig) { long microsBetweenReports = (long)timeBetweenReports * 1000L; shtpData[0] = SHTP_REPORT_SET_FEATURE_COMMAND; //Set feature command. Reference page 55 shtpData[1] = reportID; //Feature Report ID. 0x01 = Accelerometer, 0x05 = Rotation vector shtpData[2] = 0; //Feature flags shtpData[3] = 0; //Change sensitivity (LSB) shtpData[4] = 0; //Change sensitivity (MSB) shtpData[5] = (microsBetweenReports >> 0) & 0xFF; //Report interval (LSB) in microseconds. 0x7A120 = 500ms shtpData[6] = (microsBetweenReports >> 8) & 0xFF; //Report interval shtpData[7] = (microsBetweenReports >> 16) & 0xFF; //Report interval shtpData[8] = (microsBetweenReports >> 24) & 0xFF; //Report interval (MSB) shtpData[9] = 0; //Batch Interval (LSB) shtpData[10] = 0; //Batch Interval shtpData[11] = 0; //Batch Interval shtpData[12] = 0; //Batch Interval (MSB) shtpData[13] = (specificConfig >> 0) & 0xFF; //Sensor-specific config (LSB) shtpData[14] = (specificConfig >> 8) & 0xFF; //Sensor-specific config shtpData[15] = (specificConfig >> 16) & 0xFF; //Sensor-specific config shtpData[16] = (specificConfig >> 24) & 0xFF; //Sensor-specific config (MSB) //Transmit packet on channel 2, 17 bytes sendPacket(CHANNEL_CONTROL, 17); } //Tell the sensor to do a command //See 6.3.8 page 41, Command request //The caller is expected to set P0 through P8 prior to calling void BNO080::sendCommand(uint8_t command) { shtpData[0] = SHTP_REPORT_COMMAND_REQUEST; //Command Request shtpData[1] = commandSequenceNumber++; //Increments automatically each function call shtpData[2] = command; //Command //Caller must set these /*shtpData[3] = 0; //P0 shtpData[4] = 0; //P1 shtpData[5] = 0; //P2 shtpData[6] = 0; shtpData[7] = 0; shtpData[8] = 0; shtpData[9] = 0; shtpData[10] = 0; shtpData[11] = 0;*/ //Transmit packet on channel 2, 12 bytes sendPacket(CHANNEL_CONTROL, 12); } //This tells the BNO080 to begin calibrating //See page 50 of reference manual and the 1000-4044 calibration doc void BNO080::sendCalibrateCommand(uint8_t thingToCalibrate) { /*shtpData[3] = 0; //P0 - Accel Cal Enable shtpData[4] = 0; //P1 - Gyro Cal Enable shtpData[5] = 0; //P2 - Mag Cal Enable shtpData[6] = 0; //P3 - Subcommand 0x00 shtpData[7] = 0; //P4 - Planar Accel Cal Enable shtpData[8] = 0; //P5 - Reserved shtpData[9] = 0; //P6 - Reserved shtpData[10] = 0; //P7 - Reserved shtpData[11] = 0; //P8 - Reserved*/ for(uint8_t x = 3 ; x < 12 ; x++) //Clear this section of the shtpData array shtpData[x] = 0; if(thingToCalibrate == CALIBRATE_ACCEL) shtpData[3] = 1; else if(thingToCalibrate == CALIBRATE_GYRO) shtpData[4] = 1; else if(thingToCalibrate == CALIBRATE_MAG) shtpData[5] = 1; else if(thingToCalibrate == CALIBRATE_PLANAR_ACCEL) shtpData[7] = 1; else if(thingToCalibrate == CALIBRATE_ACCEL_GYRO_MAG) { shtpData[3] = 1; shtpData[4] = 1; shtpData[5] = 1; } else if(thingToCalibrate == CALIBRATE_STOP) ; //Do nothing, bytes are set to zero //Using this shtpData packet, send a command sendCommand(COMMAND_ME_CALIBRATE); } //This tells the BNO080 to save the Dynamic Calibration Data (DCD) to flash //See page 49 of reference manual and the 1000-4044 calibration doc void BNO080::saveCalibration() { /*shtpData[3] = 0; //P0 - Reserved shtpData[4] = 0; //P1 - Reserved shtpData[5] = 0; //P2 - Reserved shtpData[6] = 0; //P3 - Reserved shtpData[7] = 0; //P4 - Reserved shtpData[8] = 0; //P5 - Reserved shtpData[9] = 0; //P6 - Reserved shtpData[10] = 0; //P7 - Reserved shtpData[11] = 0; //P8 - Reserved*/ for(uint8_t x = 3 ; x < 12 ; x++) //Clear this section of the shtpData array shtpData[x] = 0; //Using this shtpData packet, send a command sendCommand(COMMAND_DCD); //Save DCD command } //Wait a certain time for incoming I2C bytes before giving up //Returns false if failed boolean BNO080::waitForI2C() { for (uint8_t counter = 0 ; counter < 100 ; counter++) //Don't got more than 255 { if (_i2cPort->available() > 0) return (true); delay(1); } if(_printDebug == true) _debugPort->println(F("I2C timeout")); return (false); } //Check to see if there is any new data available //Read the contents of the incoming packet into the shtpData array boolean BNO080::receivePacket(void) { _i2cPort->requestFrom((uint8_t)_deviceAddress, (uint8_t)4); //Ask for four bytes to find out how much data we need to read if (waitForI2C() == false) return (false); //Error //Get the first four bytes, aka the packet header uint8_t packetLSB = _i2cPort->read(); uint8_t packetMSB = _i2cPort->read(); uint8_t channelNumber = _i2cPort->read(); uint8_t sequenceNumber = _i2cPort->read(); //Not sure if we need to store this or not //Store the header info. shtpHeader[0] = packetLSB; shtpHeader[1] = packetMSB; shtpHeader[2] = channelNumber; shtpHeader[3] = sequenceNumber; //Calculate the number of data bytes in this packet int16_t dataLength = ((uint16_t)packetMSB << 8 | packetLSB); dataLength &= ~(1 << 15); //Clear the MSbit. //This bit indicates if this package is a continuation of the last. Ignore it for now. //TODO catch this as an error and exit if (dataLength == 0) { //Packet is empty return (false); //All done } dataLength -= 4; //Remove the header bytes from the data count getData(dataLength); return (true); //We're done! } //Sends multiple requests to sensor until all data bytes are received from sensor //The shtpData buffer has max capacity of MAX_PACKET_SIZE. Any bytes over this amount will be lost. //Arduino I2C read limit is 32 bytes. Header is 4 bytes, so max data we can read per interation is 28 bytes boolean BNO080::getData(uint16_t bytesRemaining) { uint16_t dataSpot = 0; //Start at the beginning of shtpData array //Setup a series of chunked 32 byte reads while (bytesRemaining > 0) { uint16_t numberOfBytesToRead = bytesRemaining; if (numberOfBytesToRead > (I2C_BUFFER_LENGTH-4)) numberOfBytesToRead = (I2C_BUFFER_LENGTH-4); _i2cPort->requestFrom((uint8_t)_deviceAddress, (uint8_t)(numberOfBytesToRead + 4)); if (waitForI2C() == false) return (0); //Error //The first four bytes are header bytes and are throw away _i2cPort->read(); _i2cPort->read(); _i2cPort->read(); _i2cPort->read(); for (uint8_t x = 0 ; x < numberOfBytesToRead ; x++) { uint8_t incoming = _i2cPort->read(); if (dataSpot < MAX_PACKET_SIZE) { shtpData[dataSpot++] = incoming; //Store data into the shtpData array } else { //Do nothing with the data } } bytesRemaining -= numberOfBytesToRead; } return (true); //Done! } //Given the data packet, send the header then the data //Returns false if sensor does not ACK //TODO - Arduino has a max 32 byte send. Break sending into multi packets if needed. boolean BNO080::sendPacket(uint8_t channelNumber, uint8_t dataLength) { uint8_t packetLength = dataLength + 4; //Add four bytes for the header //if(packetLength > I2C_BUFFER_LENGTH) return(false); //You are trying to send too much. Break into smaller packets. _i2cPort->beginTransmission(_deviceAddress); //Send the 4 byte packet header _i2cPort->write(packetLength & 0xFF); //Packet length LSB _i2cPort->write(packetLength >> 8); //Packet length MSB _i2cPort->write(channelNumber); //Channel number _i2cPort->write(sequenceNumber[channelNumber]++); //Send the sequence number, increments with each packet sent, different counter for each channel //Send the user's data packet for (uint8_t i = 0 ; i < dataLength ; i++) { _i2cPort->write(shtpData[i]); } if (_i2cPort->endTransmission() != 0) { return (false); } return (true); } //Pretty prints the contents of the current shtp header and data packets void BNO080::printPacket(void) { if(_printDebug == true) { uint16_t packetLength = (uint16_t)shtpHeader[1] << 8 | shtpHeader[0]; //Print the four byte header _debugPort->print(F("Header:")); for(uint8_t x = 0 ; x < 4 ; x++) { _debugPort->print(F(" ")); if(shtpHeader[x] < 0x10) _debugPort->print(F("0")); _debugPort->print(shtpHeader[x], HEX); } uint8_t printLength = packetLength - 4; if(printLength > 40) printLength = 40; //Artificial limit. We don't want the phone book. _debugPort->print(F(" Body:")); for(uint8_t x = 0 ; x < printLength ; x++) { _debugPort->print(F(" ")); if(shtpData[x] < 0x10) _debugPort->print(F("0")); _debugPort->print(shtpData[x], HEX); } if (packetLength & 1 << 15) { _debugPort->println(F(" [Continued packet] ")); packetLength &= ~(1 << 15); } _debugPort->print(F(" Length:")); _debugPort->print (packetLength); _debugPort->print(F(" Channel:")); if (shtpHeader[2] == 0) _debugPort->print(F("Command")); else if (shtpHeader[2] == 1) _debugPort->print(F("Executable")); else if (shtpHeader[2] == 2) _debugPort->print(F("Control")); else if (shtpHeader[2] == 3) _debugPort->print(F("Sensor-report")); else if (shtpHeader[2] == 4) _debugPort->print(F("Wake-report")); else if (shtpHeader[2] == 5) _debugPort->print(F("Gyro-vector")); else _debugPort->print(shtpHeader[2]); _debugPort->println(); } } /* This is a library written for the BNO080 SparkFun sells these at its website: www.sparkfun.com Do you like this library? Help support SparkFun. Buy a board! https://www.sparkfun.com/products/14586 Written by Nathan Seidle @ SparkFun Electronics, December 28th, 2017 The BNO080 IMU is a powerful triple axis gyro/accel/magnetometer coupled with an ARM processor to maintain and complete all the complex calculations for various VR, inertial, step counting, and movement operations. This library handles the initialization of the BNO080 and is able to query the sensor for different readings. https://github.com/sparkfun/SparkFun_BNO080_Arduino_Library Development environment specifics: Arduino IDE 1.8.3 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #pragma once #if (ARDUINO >= 100) #include "Arduino.h" #else #include "WProgram.h" #endif #include <Wire.h> //The default I2C address for the BNO080 on the SparkX breakout is 0x4B. 0x4A is also possible. #define BNO080_DEFAULT_ADDRESS 0x4B //Platform specific configurations //Define the size of the I2C buffer based on the platform the user has //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) //I2C_BUFFER_LENGTH is defined in Wire.H #define I2C_BUFFER_LENGTH BUFFER_LENGTH #elif defined(__SAMD21G18A__) //SAMD21 uses RingBuffer.h #define I2C_BUFFER_LENGTH SERIAL_BUFFER_SIZE #elif __MK20DX256__ //Teensy #elif ARDUINO_ARCH_ESP32 //ESP32 based platforms #else //The catch-all default is 32 #define I2C_BUFFER_LENGTH 32 #endif //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //Registers const byte CHANNEL_COMMAND = 0; const byte CHANNEL_EXECUTABLE = 1; const byte CHANNEL_CONTROL = 2; const byte CHANNEL_REPORTS = 3; const byte CHANNEL_WAKE_REPORTS = 4; const byte CHANNEL_GYRO = 5; //All the ways we can configure or talk to the BNO080, figure 34, page 36 reference manual //These are used for low level communication with the sensor, on channel 2 #define SHTP_REPORT_COMMAND_RESPONSE 0xF1 #define SHTP_REPORT_COMMAND_REQUEST 0xF2 #define SHTP_REPORT_FRS_READ_RESPONSE 0xF3 #define SHTP_REPORT_FRS_READ_REQUEST 0xF4 #define SHTP_REPORT_PRODUCT_ID_RESPONSE 0xF8 #define SHTP_REPORT_PRODUCT_ID_REQUEST 0xF9 #define SHTP_REPORT_BASE_TIMESTAMP 0xFB #define SHTP_REPORT_SET_FEATURE_COMMAND 0xFD //All the different sensors and features we can get reports from //These are used when enabling a given sensor #define SENSOR_REPORTID_ACCELEROMETER 0x01 #define SENSOR_REPORTID_GYROSCOPE 0x02 #define SENSOR_REPORTID_MAGNETIC_FIELD 0x03 #define SENSOR_REPORTID_LINEAR_ACCELERATION 0x04 #define SENSOR_REPORTID_ROTATION_VECTOR 0x05 #define SENSOR_REPORTID_GRAVITY 0x06 #define SENSOR_REPORTID_GAME_ROTATION_VECTOR 0x08 #define SENSOR_REPORTID_GEOMAGNETIC_ROTATION_VECTOR 0x09 #define SENSOR_REPORTID_TAP_DETECTOR 0x10 #define SENSOR_REPORTID_STEP_COUNTER 0x11 #define SENSOR_REPORTID_STABILITY_CLASSIFIER 0x13 #define SENSOR_REPORTID_PERSONAL_ACTIVITY_CLASSIFIER 0x1E //Record IDs from figure 29, page 29 reference manual //These are used to read the metadata for each sensor type #define FRS_RECORDID_ACCELEROMETER 0xE302 #define FRS_RECORDID_GYROSCOPE_CALIBRATED 0xE306 #define FRS_RECORDID_MAGNETIC_FIELD_CALIBRATED 0xE309 #define FRS_RECORDID_ROTATION_VECTOR 0xE30B //Command IDs from section 6.4, page 42 //These are used to calibrate, initialize, set orientation, tare etc the sensor #define COMMAND_ERRORS 1 #define COMMAND_COUNTER 2 #define COMMAND_TARE 3 #define COMMAND_INITIALIZE 4 #define COMMAND_DCD 6 #define COMMAND_ME_CALIBRATE 7 #define COMMAND_DCD_PERIOD_SAVE 9 #define COMMAND_OSCILLATOR 10 #define COMMAND_CLEAR_DCD 11 #define CALIBRATE_ACCEL 0 #define CALIBRATE_GYRO 1 #define CALIBRATE_MAG 2 #define CALIBRATE_PLANAR_ACCEL 3 #define CALIBRATE_ACCEL_GYRO_MAG 4 #define CALIBRATE_STOP 5 #define MAX_PACKET_SIZE 128 //Packets can be up to 32k but we don't have that much RAM. #define MAX_METADATA_SIZE 9 //This is in words. There can be many but we mostly only care about the first 9 (Qs, range, etc) class BNO080 { public: boolean begin(uint8_t deviceAddress = BNO080_DEFAULT_ADDRESS, TwoWire &wirePort = Wire); //By default use the default I2C addres, and use Wire port void enableDebugging(Stream &debugPort = Serial); //Turn on debug printing. If user doesn't specify then Serial will be used. void softReset(); //Try to reset the IMU via software uint8_t resetReason(); //Query the IMU for the reason it last reset float qToFloat(int16_t fixedPointValue, uint8_t qPoint); //Given a Q value, converts fixed point floating to regular floating point number boolean waitForI2C(); //Delay based polling for I2C traffic boolean receivePacket(void); boolean getData(uint16_t bytesRemaining); //Given a number of bytes, send the requests in I2C_BUFFER_LENGTH chunks boolean sendPacket(uint8_t channelNumber, uint8_t dataLength); void printPacket(void); //Prints the current shtp header and data packets void enableRotationVector(uint16_t timeBetweenReports); void enableGameRotationVector(uint16_t timeBetweenReports); void enableAccelerometer(uint16_t timeBetweenReports); void enableLinearAccelerometer(uint16_t timeBetweenReports); void enableGyro(uint16_t timeBetweenReports); void enableMagnetometer(uint16_t timeBetweenReports); void enableStepCounter(uint16_t timeBetweenReports); void enableStabilityClassifier(uint16_t timeBetweenReports); void enableActivityClassifier(uint16_t timeBetweenReports, uint32_t activitiesToEnable, uint8_t (&activityConfidences)[9]); bool dataAvailable(void); void parseInputReport(void); float getQuatI(); float getQuatJ(); float getQuatK(); float getQuatReal(); float getQuatRadianAccuracy(); uint8_t getQuatAccuracy(); float getAccelX(); float getAccelY(); float getAccelZ(); uint8_t getAccelAccuracy(); float getLinAccelX(); float getLinAccelY(); float getLinAccelZ(); uint8_t getLinAccelAccuracy(); float getGyroX(); float getGyroY(); float getGyroZ(); uint8_t getGyroAccuracy(); float getMagX(); float getMagY(); float getMagZ(); uint8_t getMagAccuracy(); void calibrateAccelerometer(); void calibrateGyro(); void calibrateMagnetometer(); void calibratePlanarAccelerometer(); void calibrateAll(); void endCalibration(); void saveCalibration(); uint16_t getStepCount(); uint8_t getStabilityClassifier(); uint8_t getActivityClassifier(); void setFeatureCommand(uint8_t reportID, uint16_t timeBetweenReports); void setFeatureCommand(uint8_t reportID, uint16_t timeBetweenReports, uint32_t specificConfig); void sendCommand(uint8_t command); void sendCalibrateCommand(uint8_t thingToCalibrate); //Metadata functions int16_t getQ1(uint16_t recordID); int16_t getQ2(uint16_t recordID); int16_t getQ3(uint16_t recordID); float getResolution(uint16_t recordID); float getRange(uint16_t recordID); uint32_t readFRSword(uint16_t recordID, uint8_t wordNumber); void frsReadRequest(uint16_t recordID, uint16_t readOffset, uint16_t blockSize); bool readFRSdata(uint16_t recordID, uint8_t startLocation, uint8_t wordsToRead); //Global Variables uint8_t shtpHeader[4]; //Each packet has a header of 4 bytes uint8_t shtpData[MAX_PACKET_SIZE]; uint8_t sequenceNumber[6] = {0, 0, 0, 0, 0, 0}; //There are 6 com channels. Each channel has its own seqnum uint8_t commandSequenceNumber = 0; //Commands have a seqNum as well. These are inside command packet, the header uses its own seqNum per channel uint32_t metaData[MAX_METADATA_SIZE]; //There is more than 10 words in a metadata record but we'll stop at Q point 3 private: //Variables TwoWire *_i2cPort; //The generic connection to user's chosen I2C hardware uint8_t _deviceAddress; //Keeps track of I2C address. setI2CAddress changes this. Stream *_debugPort; //The stream to send debug messages to if enabled. Usually Serial. boolean _printDebug = false; //Flag to print debugging variables //These are the raw sensor values pulled from the user requested Input Report uint16_t rawAccelX, rawAccelY, rawAccelZ, accelAccuracy; uint16_t rawLinAccelX, rawLinAccelY, rawLinAccelZ, accelLinAccuracy; uint16_t rawGyroX, rawGyroY, rawGyroZ, gyroAccuracy; uint16_t rawMagX, rawMagY, rawMagZ, magAccuracy; uint16_t rawQuatI, rawQuatJ, rawQuatK, rawQuatReal, rawQuatRadianAccuracy, quatAccuracy; uint16_t stepCount; uint8_t stabilityClassifier; uint8_t activityClassifier; uint8_t *_activityConfidences; //Array that store the confidences of the 9 possible activities //These Q values are defined in the datasheet but can also be obtained by querying the meta data records //See the read metadata example for more info int16_t rotationVector_Q1 = 14; int16_t accelerometer_Q1 = 8; int16_t linear_accelerometer_Q1 = 8; int16_t gyro_Q1 = 9; int16_t magnetometer_Q1 = 4; }; 请根据以上参考代码,写出我所需的STM32F411ceu6基于I2C控制BNO080的库函数

最新推荐

recommend-type

信捷PLC与台达伺服A2B2通讯实现高效拧螺丝动作:速度模式、扭力限制及锁紧信号IO输出

内容概要:本文详细介绍了如何利用信捷PLC与台达伺服A2/B2进行通讯,实现高效的拧螺丝动作。主要内容涵盖速度模式的配置、扭力限制的设置以及锁紧信号的IO输出。文中提供了具体的硬件接线方法,如伺服CN1接口与PLC输出端的连接细节,确保了系统的稳定性和可靠性。同时,还给出了详细的参数设置和PLC程序示例,帮助用户快速理解和应用。此外,文章特别强调了扭矩监控的重要性,并提供了一些实用的避坑指南,如伺服使能的正确接法、脉冲口抗干扰措施以及扭力限制值的调整技巧。 适合人群:从事自动化设备安装、调试的技术人员,尤其是对PLC和伺服系统有一定了解的工程师。 使用场景及目标:适用于需要实现自动化拧螺丝操作的企业或实验室,旨在提高生产效率和产品质量。通过学习本文,读者可以掌握信捷PLC与台达伺服的具体配置方法,从而顺利完成拧螺丝任务。 其他说明:本文不仅提供了理论指导,还附带了大量的实战经验和技巧,有助于读者在实际工作中避免常见错误,提升工作效率。
recommend-type

汽车安全领域中基于Simulink的ABS模型仿真与防抱死制动系统建模 仿真技术 详细版

内容概要:本文深入探讨了利用Simulink进行汽车防抱死制动系统(ABS)的建模与仿真的方法。主要内容涵盖Simulink环境下ABS模型的具体构建,包括速度传感器模块和制动压力控制模块的设计,以及详细的仿真分析。文中不仅展示了有无ABS系统在紧急制动情况下的性能差异,还提供了具体的Matlab代码片段,解释了ABS控制系统的工作原理及其重要性。通过对比实验,证明了ABS系统能够显著缩短刹车距离并提高行车安全性。 适合人群:汽车工程专业学生、从事汽车安全技术研发的工程师和技术爱好者。 使用场景及目标:帮助读者掌握ABS系统的基本原理和建模技巧,提升对汽车主动安全技术的理解,适用于教学培训、科研项目和个人学习等场景。 其他说明:文章附带了完整的Word文档说明和Simulink模型文件,便于读者进一步理解和实践。
recommend-type

V公司高效稳定的汽车零部件开发工具:全套OSEK NM协议栈源代码及配置功能,轻松完成集成,量产保证

内容概要:本文详细介绍了汽车零部件开发巨头V公司提供的OSEK NM协议栈源代码及其配置功能。OSEK NM是一种专为汽车网络管理设计的通信协议,由韩国汽车工业标准化组织制定。V公司提供的这套工具集不仅代码结构清晰、模块化程度高,而且具有高效稳定的特性,适用于汽车零部件的开发。文中具体解析了源代码的结构和各模块的功能,特别是网络管理模块的核心代码,展示了V公司在网络管理方面的精细控制。此外,文章还详细描述了集成步骤和性能优化方法,强调了V公司提供的技术支持和优化工具。最终,V公司的OSEK NM协议栈因其稳定性和量产保证,成为了汽车零部件开发的首选工具。 适合人群:从事汽车零部件开发的技术人员、嵌入式系统工程师、汽车电子工程师。 使用场景及目标:① 快速集成并使用OSEK NM协议栈进行汽车零部件开发;② 提升网络管理和数据传输的效率;③ 实现高效稳定的汽车网络管理系统。 其他说明:V公司提供的OSEK NM协议栈不仅简化了开发流程,还确保了产品的量产可行性,适用于现代汽车工业的发展需求。
recommend-type

嵌入式系统中串口转以太网通信的CC++实现及其应用

内容概要:本文档详细介绍了使用C语言和C++实现串口转以太网通信的技术细节。它不仅涵盖了多路网口和串口之间的双向数据转换,还支持UDP和TCP两种连接方式。文中特别强调了通过Qt5.10.1平台和QSerialPort类来构建这一通信机制的具体方法。此外,文档还提供了丰富的辅助工具如16进制数据发送窗口、接收窗口、自动连接功能以及配置文件管理等特性。为了便于开发者理解和使用,所有源代码均配有详细的注释和技术文档。 适合人群:对嵌入式系统开发感兴趣的工程师或者有一定编程经验的研发人员。 使用场景及目标:适用于需要将传统RS232/485等串行接口设备接入现代网络环境的情况,比如工业自动化控制系统、智能家居产品或其他物联网应用场景。通过学习本文档,读者能够掌握如何利用现有硬件资源搭建高效稳定的串口转以太网解决方案。 其他说明:该文档不仅限于理论讲解,还包括实际项目案例分享,帮助读者更好地理解整个系统的运作流程。同时提醒使用者确保源码放置于纯英文路径下以便正确编译运行。
recommend-type

几何测量中最小二乘法评估直线度、平面度及圆度的C#实现 - 最小二乘法

内容概要:本文详细介绍了最小二乘法在几何测量领域的应用,特别是针对直线度、平面度和圆度的评估方法。文中不仅解释了最小二乘法的基本原理及其在不同几何形状拟合中的具体步骤,还提供了完整的C#实现代码。对于每种几何形状,作者都列出了详细的计算流程,从数据点的初始化到最后的最佳拟合结果确定,确保读者能够理解和实现这一数学优化技术。 适合人群:从事几何测量工作的技术人员以及对最小二乘法感兴趣的开发者。 使用场景及目标:适用于需要精确评估几何形状特征的应用场合,如机械制造、质量检测等领域。通过学习本文,读者可以掌握如何使用最小二乘法进行直线度、平面度和圆度的计算,从而提高测量精度。 阅读建议:由于涉及到具体的数学推导和编程实现,建议读者具备一定的数学基础和C#编程经验,在阅读过程中结合实际案例进行练习,以便更好地理解最小二乘法的应用。
recommend-type

掌握XFireSpring整合技术:HELLOworld原代码使用教程

标题:“xfirespring整合使用原代码”中提到的“xfirespring”是指将XFire和Spring框架进行整合使用。XFire是一个基于SOAP的Web服务框架,而Spring是一个轻量级的Java/Java EE全功能栈的应用程序框架。在Web服务开发中,将XFire与Spring整合能够发挥两者的优势,例如Spring的依赖注入、事务管理等特性,与XFire的简洁的Web服务开发模型相结合。 描述:“xfirespring整合使用HELLOworld原代码”说明了在这个整合过程中实现了一个非常基本的Web服务示例,即“HELLOworld”。这通常意味着创建了一个能够返回"HELLO world"字符串作为响应的Web服务方法。这个简单的例子用来展示如何设置环境、编写服务类、定义Web服务接口以及部署和测试整合后的应用程序。 标签:“xfirespring”表明文档、代码示例或者讨论集中于XFire和Spring的整合技术。 文件列表中的“index.jsp”通常是一个Web应用程序的入口点,它可能用于提供一个用户界面,通过这个界面调用Web服务或者展示Web服务的调用结果。“WEB-INF”是Java Web应用中的一个特殊目录,它存放了应用服务器加载的Servlet类文件和相关的配置文件,例如web.xml。web.xml文件中定义了Web应用程序的配置信息,如Servlet映射、初始化参数、安全约束等。“META-INF”目录包含了元数据信息,这些信息通常由部署工具使用,用于描述应用的元数据,如manifest文件,它记录了归档文件中的包信息以及相关的依赖关系。 整合XFire和Spring框架,具体知识点可以分为以下几个部分: 1. XFire框架概述 XFire是一个开源的Web服务框架,它是基于SOAP协议的,提供了一种简化的方式来创建、部署和调用Web服务。XFire支持多种数据绑定,包括XML、JSON和Java数据对象等。开发人员可以使用注解或者基于XML的配置来定义服务接口和服务实现。 2. Spring框架概述 Spring是一个全面的企业应用开发框架,它提供了丰富的功能,包括但不限于依赖注入、面向切面编程(AOP)、数据访问/集成、消息传递、事务管理等。Spring的核心特性是依赖注入,通过依赖注入能够将应用程序的组件解耦合,从而提高应用程序的灵活性和可测试性。 3. XFire和Spring整合的目的 整合这两个框架的目的是为了利用各自的优势。XFire可以用来创建Web服务,而Spring可以管理这些Web服务的生命周期,提供企业级服务,如事务管理、安全性、数据访问等。整合后,开发者可以享受Spring的依赖注入、事务管理等企业级功能,同时利用XFire的简洁的Web服务开发模型。 4. XFire与Spring整合的基本步骤 整合的基本步骤可能包括添加必要的依赖到项目中,配置Spring的applicationContext.xml,以包括XFire特定的bean配置。比如,需要配置XFire的ServiceExporter和ServicePublisher beans,使得Spring可以管理XFire的Web服务。同时,需要定义服务接口以及服务实现类,并通过注解或者XML配置将其关联起来。 5. Web服务实现示例:“HELLOworld” 实现一个Web服务通常涉及到定义服务接口和服务实现类。服务接口定义了服务的方法,而服务实现类则提供了这些方法的具体实现。在XFire和Spring整合的上下文中,“HELLOworld”示例可能包含一个接口定义,比如`HelloWorldService`,和一个实现类`HelloWorldServiceImpl`,该类有一个`sayHello`方法返回"HELLO world"字符串。 6. 部署和测试 部署Web服务时,需要将应用程序打包成WAR文件,并部署到支持Servlet 2.3及以上版本的Web应用服务器上。部署后,可以通过客户端或浏览器测试Web服务的功能,例如通过访问XFire提供的服务描述页面(WSDL)来了解如何调用服务。 7. JSP与Web服务交互 如果在应用程序中使用了JSP页面,那么JSP可以用来作为用户与Web服务交互的界面。例如,JSP可以包含JavaScript代码来发送异步的AJAX请求到Web服务,并展示返回的结果给用户。在这个过程中,JSP页面可能使用XMLHttpRequest对象或者现代的Fetch API与Web服务进行通信。 8. 项目配置文件说明 项目配置文件如web.xml和applicationContext.xml分别在Web应用和服务配置中扮演关键角色。web.xml负责定义Web组件,比如Servlet、过滤器和监听器,而applicationContext.xml则负责定义Spring容器中的bean,包括数据源、事务管理器、业务逻辑组件和服务访问器等。 总之,通过上述整合使用原代码的知识点,可以深入理解XFire与Spring框架的结合使用,以及如何开发和部署基本的Web服务。这些技术知识有助于进行更高层次的Web服务开发,以及在复杂的IT环境中灵活运用各种框架和工具。
recommend-type

【Unity2018汉化大揭秘】:一步到位优化中文用户体验

# 摘要 本论文详细介绍了Unity2018汉化项目的实施过程,从理论准备到实践步骤,再到后期的测试与优化,最终分享了汉化经验和心得。首先,强调了汉化项目对于用户体验提升和产品国际化的重要性,并分析了汉化资源的分类、识别与管理方法。接着,详细阐述了汉化工具的选择、脚本编写、资源手动调整等实践步骤,以及汉化质量测试、体验优化和项目维护更新的重要性。论文最后通过案例研究,分析了汉化中的挑战和应对策略,并预测了汉化技术未来的发展方向。整个汉化过程不仅涉及技术层面的操作,还包含了深入的理论研究和实践心得分享,对提升汉化项目的效率和质量具有指导意义。 # 关键字 Unity汉化;用户体验;国际化;资源
recommend-type

iPhone

<think>我们注意到用户意图不明确,但提到了“照片提取”和“其他功能帮助”。因此,我们需要通过搜索来获取关于iPhone照片提取的常见方法以及其他可能的功能帮助。由于用户问题比较宽泛,我们将重点放在照片提取上,因为这是明确提到的关键词。同时,我们也会考虑一些其他常用功能的帮助。首先,针对照片提取,可能涉及从iPhone导出照片、从备份中提取照片、或者从损坏的设备中恢复照片等。我们将搜索这些方面的信息。其次,关于其他功能帮助,我们可以提供一些常见问题的快速指南,如电池优化、屏幕时间管理等。根据要求,我们需要将答案组织为多个方法或步骤,并在每个步骤间换行。同时,避免使用第一人称和步骤词汇。由于
recommend-type

驾校一点通软件:提升驾驶证考试通过率

标题“驾校一点通”指向的是一款专门为学员考取驾驶证提供帮助的软件,该软件强调其辅助性质,旨在为学员提供便捷的学习方式和复习资料。从描述中可以推断出,“驾校一点通”是一个与驾驶考试相关的应用软件,这类软件一般包含驾驶理论学习、模拟考试、交通法规解释等内容。 文件标题中的“2007”这个年份标签很可能意味着软件的最初发布时间或版本更新年份,这说明了软件具有一定的历史背景和可能经过了多次更新,以适应不断变化的驾驶考试要求。 压缩包子文件的文件名称列表中,有以下几个文件类型值得关注: 1. images.dat:这个文件名表明,这是一个包含图像数据的文件,很可能包含了用于软件界面展示的图片,如各种标志、道路场景等图形。在驾照学习软件中,这类图片通常用于帮助用户认识和记忆不同交通标志、信号灯以及驾驶过程中需要注意的各种道路情况。 2. library.dat:这个文件名暗示它是一个包含了大量信息的库文件,可能包含了法规、驾驶知识、考试题库等数据。这类文件是提供给用户学习驾驶理论知识和准备科目一理论考试的重要资源。 3. 驾校一点通小型汽车专用.exe:这是一个可执行文件,是软件的主要安装程序。根据标题推测,这款软件主要是针对小型汽车驾照考试的学员设计的。通常,小型汽车(C1类驾照)需要学习包括车辆构造、基础驾驶技能、安全行车常识、交通法规等内容。 4. 使用说明.html:这个文件是软件使用说明的文档,通常以网页格式存在,用户可以通过浏览器阅读。使用说明应该会详细介绍软件的安装流程、功能介绍、如何使用软件的各种模块以及如何通过软件来帮助自己更好地准备考试。 综合以上信息,我们可以挖掘出以下几个相关知识点: - 软件类型:辅助学习软件,专门针对驾驶考试设计。 - 应用领域:主要用于帮助驾考学员准备理论和实践考试。 - 文件类型:包括图片文件(images.dat)、库文件(library.dat)、可执行文件(.exe)和网页格式的说明文件(.html)。 - 功能内容:可能包含交通法规知识学习、交通标志识别、驾驶理论学习、模拟考试、考试题库练习等功能。 - 版本信息:软件很可能最早发布于2007年,后续可能有多个版本更新。 - 用户群体:主要面向小型汽车驾照考生,即C1类驾照学员。 - 使用方式:用户需要将.exe安装文件进行安装,然后根据.html格式的使用说明来熟悉软件操作,从而利用images.dat和library.dat中的资源来辅助学习。 以上知识点为从给定文件信息中提炼出来的重点,这些内容对于了解“驾校一点通”这款软件的功能、作用、使用方法以及它的发展历史都有重要的指导意义。
recommend-type

【DFLauncher自动化教程】:简化游戏启动流程,让游戏体验更流畅

# 摘要 DFLauncher是一个功能丰富的游戏启动和管理平台,本论文将介绍其安装、基础使用、高级设置、社区互动以及插件开发等方面。通过对配置文件的解析、界面定制、自动化功能的实现、高级配置选项、安全性和性能监控的详细讨论,本文阐述了DFLauncher如何帮助用户更高效地管理和优化游戏环境。此外,本文还探讨了DFLauncher社区的资源分享、教育教程和插件开发等内容,