# TSGame 跨平台项目说明文档 ## 项目概述 TSGame 是一个跨平台的棋牌游戏应用,支持Android、iOS、HarmonyOS等主流移动平台。主要实现了聚友棋牌、进贤聚友棋牌等多个地方特色棋牌游戏。项目采用WebView混合开发模式,通过统一的JS Bridge接口实现跨平台功能。 ### 支持平台 - **Android**: API 21+ (Android 5.0+) - **iOS**: iOS 11.0+ - **HarmonyOS**: API 8+ (HarmonyOS 3.0+) ### 基本信息 - **应用标识**: `com.jx.jyhd` (可根据平台调整) - **应用名称**: 进贤聚友棋牌(支持多种地方棋牌名称配置) - **当前版本**: 3.6.3 - **架构模式**: WebView + JS Bridge 混合开发 ## 跨平台技术架构 ### 整体架构设计 ``` ┌─────────────────────────────────────────────────────┐ │ H5游戏前端 │ │ (HTML5 + CSS3 + JavaScript) │ └─────────────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────────────┐ │ JS Bridge 通信层 │ │ (统一的跨平台API接口定义) │ └─────────────────────────────────────────────────────┘ │ ┌─────────────┬─────────────┬─────────────┬─────────────┐ │ Android │ iOS │ HarmonyOS │ 其他平台 │ │ Native │ Native │ Native │ Native │ └─────────────┴─────────────┴─────────────┴─────────────┘ ``` ### 核心设计原则 1. **统一接口**: 所有平台实现相同的JS Bridge API接口 2. **功能对等**: 确保各平台功能基本一致 3. **性能优化**: 针对不同平台特性进行优化 4. **用户体验**: 遵循各平台的设计规范 ## 项目功能特性 ### 核心功能模块 1. **多地方棋牌游戏支持** - 崇仁聚友棋牌 - 进贤聚友棋牌 - 广州聚友棋牌 - 慈溪聚友棋牌 - 东乡棋牌等多个地方特色游戏 2. **WebView游戏引擎** - Android: 腾讯X5 WebView内核 - iOS: WKWebView - HarmonyOS: Web组件 - 支持HTML5游戏运行 - 自定义JS桥接功能 3. **社交分享功能** - 微信好友/朋友圈分享 - QQ分享(Android) - 系统分享(iOS/HarmonyOS) - 抖音分享(Intent/URL Scheme方式) 4. **位置服务** - Android: 高德地图SDK - iOS: 高德地图SDK + CoreLocation - HarmonyOS: 华为地图服务 - GPS/网络定位支持 5. **语音功能** - 声网Agora音频SDK(全平台支持) - 实时语音通话 - 录音功能 6. **版本管理** - 应用自动更新 - 游戏资源热更新 - 配置文件动态加载 ## 跨平台项目目录结构 ### 通用项目结构 ``` tsgame_multiplatform/ ├── shared/ # 共享资源 │ ├── webview/ # H5游戏资源 │ │ ├── assets/ # 静态资源 │ │ ├── js/ # JavaScript文件 │ │ ├── css/ # 样式文件 │ │ └── index.html # 游戏入口页面 │ ├── bridge/ # JS Bridge接口定义 │ │ ├── bridge-api.js # 统一API接口 │ │ └── bridge-types.ts # TypeScript类型定义 │ └── config/ # 配置文件 │ ├── game-config.json # 游戏配置 │ └── platform-config.json # 平台配置 ├── android/ # Android平台实现 │ ├── app/ │ │ ├── src/main/java/ # Java/Kotlin源码 │ │ ├── src/main/assets/ # 资源文件 │ │ └── build.gradle # 构建配置 │ └── libs/ # 第三方库 ├── ios/ # iOS平台实现 │ ├── TSGame/ │ │ ├── Classes/ # OC/Swift源码 │ │ ├── Resources/ # 资源文件 │ │ └── Info.plist # 应用配置 │ └── Podfile # 依赖管理 ├── harmonyos/ # HarmonyOS平台实现 │ ├── entry/ │ │ ├── src/main/ets/ # ArkTS源码 │ │ ├── src/main/resources/ # 资源文件 │ │ └── build-profile.json5 # 构建配置 │ └── oh-package.json5 # 依赖管理 ├── docs/ # 项目文档 │ ├── platform-guides/ # 平台开发指南 │ ├── api-reference/ # API参考文档 │ └── deployment/ # 部署指南 └── tools/ # 开发工具 ├── build-scripts/ # 构建脚本 └── test-tools/ # 测试工具 ``` ### 平台特定代码包结构 #### Android (Java/Kotlin) ``` com.jx.jyhd/ ├── activity/ # 活动页面 │ ├── MainActivity # 主入口 │ ├── WebViewActivity # WebView容器 │ └── SplashActivity # 启动页 ├── bridge/ # JS Bridge实现 │ ├── BridgeWebView # WebView扩展 │ ├── BridgeHandler # 方法处理器 │ └── BridgeManager # 桥接管理器 ├── service/ # 业务服务 │ ├── AuthService # 认证服务 │ ├── ShareService # 分享服务 │ └── LocationService # 定位服务 └── utils/ # 工具类 ├── NetworkUtils # 网络工具 └── StorageUtils # 存储工具 ``` #### iOS (Objective-C/Swift) ``` TSGame/ ├── Controllers/ # 控制器 │ ├── TSMainViewController # 主控制器 │ ├── TSWebViewController # WebView控制器 │ └── TSSplashViewController # 启动页控制器 ├── Bridge/ # JS Bridge实现 │ ├── TSBridgeWebView # WebView扩展 │ ├── TSBridgeHandler # 方法处理器 │ └── TSBridgeManager # 桥接管理器 ├── Services/ # 业务服务 │ ├── TSAuthService # 认证服务 │ ├── TSShareService # 分享服务 │ └── TSLocationService # 定位服务 └── Utils/ # 工具类 ├── TSNetworkUtils # 网络工具 └── TSStorageUtils # 存储工具 ``` #### HarmonyOS (ArkTS) ``` src/main/ets/ ├── entryability/ # 应用入口 │ └── EntryAbility.ts # 主Ability ├── pages/ # 页面 │ ├── Index.ets # 主页面 │ ├── WebView.ets # WebView页面 │ └── Splash.ets # 启动页 ├── bridge/ # JS Bridge实现 │ ├── BridgeWebView.ets # WebView扩展 │ ├── BridgeHandler.ets # 方法处理器 │ └── BridgeManager.ets # 桥接管理器 ├── services/ # 业务服务 │ ├── AuthService.ets # 认证服务 │ ├── ShareService.ets # 分享服务 │ └── LocationService.ets # 定位服务 └── utils/ # 工具类 ├── NetworkUtils.ets # 网络工具 └── StorageUtils.ets # 存储工具 ``` ## 跨平台应用启动流程 ### 统一启动流程设计 ``` 应用启动 ↓ 平台初始化 (原生代码) ↓ 权限检查与申请 ↓ 配置文件加载 ↓ JS Bridge初始化 ↓ WebView组件加载 ↓ H5游戏资源加载 ↓ 游戏启动完成 ``` ### 平台特定启动流程 #### Android启动流程 1. **应用启动入口** ``` AndroidManifest.xml → SplashActivity → MainActivity → WebViewActivity ``` 2. **初始化阶段** (`SplashActivity.onCreate`) ```java 1. 权限检查和存储权限申请 2. 设置全屏显示和屏幕常亮 3. 初始化日志系统 4. 友盟统计初始化 5. 微信API初始化 6. 获取当前Activity信息 ``` #### iOS启动流程 1. **应用启动入口** ``` Info.plist → AppDelegate → TSMainViewController → TSWebViewController ``` 2. **初始化阶段** (`AppDelegate.didFinishLaunchingWithOptions`) ```objc 1. 权限检查和申请 2. 状态栏和导航栏配置 3. 日志系统初始化 4. 统计SDK初始化 5. 微信API初始化 6. 根视图控制器设置 ``` #### HarmonyOS启动流程 1. **应用启动入口** ``` module.json5 → EntryAbility → Index.ets → WebView.ets ``` 2. **初始化阶段** (`EntryAbility.onCreate`) ```typescript 1. 权限检查和申请 2. 窗口属性配置 3. 日志系统初始化 4. 分析服务初始化 5. 第三方SDK初始化 6. 主页面加载 ``` ### 配置加载流程(通用) ```javascript // 第一阶段:本地配置加载 1. 从本地存储读取游戏配置参数: - gamestart: 游戏启动目录 - gamedir: 游戏父目录 - gameconfig: 游戏配置URL - agent: 代理ID - channel: 渠道号 - market: 市场来源 // 第二阶段:版本检查 1. 检查是否首次安装 2. 从assets/bundle复制初始游戏资源 3. 检查本地版本与服务器版本 4. 决定是否需要更新游戏资源 // 第三阶段:资源更新 if (需要应用更新) { // 跳转到应用商店或下载APK/IPA } else if (需要游戏资源更新) { 下载游戏ZIP包 -> 解压到本地 -> 更新配置 } else { 直接启动游戏 } // 第四阶段:游戏启动 1. 初始化H5数据 (app_data.js) 2. 写入游戏配置参数到JS文件 3. 启动主游戏WebView页面 4. 完成启动流程 ``` ### 关键配置文件 #### version.json (版本配置) ```json { "version": 1, "gameid": "game001", "name": "游戏名称", "platform": "all" } ``` #### app_data.js (运行时配置) ```javascript var app_version = 1; var app_gameconfig = 'config_url'; var app_gamedir = 'game_directory'; var app_gamestart = 'start_file'; var app_agent = 'agent_id'; var app_channel = 'channel_id'; var app_market = 'market_id'; var app_platform = 'android|ios|harmonyos'; 下载游戏ZIP包 -> 解压到本地 -> 更新配置 } else { 直接启动游戏 } ``` #### 第六阶段:游戏启动 ```java 1. 初始化H5数据 (app_data.js) 2. 写入游戏配置参数到JS文件 3. 启动主游戏WebView页面 4. 完成启动流程 ``` ## WebView与原生交互API 项目使用自定义的JS桥接框架实现WebView与原生Android之间的双向通信。主要基于 `BridgeWebView` 实现。 ### API快速参考表 | 功能分类 | API名称 | 调用方向 | 主要用途 | |---------|---------|----------|----------| | **认证登录** | `accreditlogin` | JS→Native | 触发微信/QQ登录 | | | `sharelogin` | Native→JS | 登录结果回调 | | **社交分享** | `friendsSharetypeUrlToptitleDescript` | JS→Native | 微信/抖音分享 | | | `sharesuccess` | Native→JS | 分享结果回调 | | **设备信息** | `getphoneInfo` | JS→Native | 获取设备基本信息 | | | `getbattery` | JS→Native | 获取电池电量 | | | `getwifiLevel` | JS→Native | 获取WiFi信号强度 | | | `getnetwork` | JS→Native | 获取网络连接状态 | | | `getTime` | JS→Native | 获取系统时间 | | **多媒体** | `getphoto` | JS↔Native | 图片下载处理 | | | `opensaoma` | JS→Native | 二维码扫描 | | | `opencamera` | JS→Native | 拍照功能 | | **音频** | `prepareaudio` | JS→Native | 录音准备 | | | `mediaTypeAudio` | JS→Native | 音频播放 | | | `voicePlaying` | JS→Native | 语音动画 | | **音视频通话** | `createRoom` | JS→Native | 创建音视频房间 | | | `exitRoom` | JS→Native | 退出音视频房间 | | **定位服务** | `startlocation` | JS→Native | 开始定位 | | | `getlocationinfo` | JS→Native | 获取位置信息 | | | `locationinfo` | Native→JS | 定位结果回调 | | **系统交互** | `vibrator` | JS→Native | 手机震动 | | | `orientation` | JS→Native | 屏幕方向控制 | | | `finsh` | JS→Native | 退出应用 | | | `notification` | JS→Native | 系统通知 | | **摇一摇** | `startshake` | JS→Native | 开始摇一摇监听 | | | `stopshake` | JS→Native | 停止摇一摇 | | | `shake` | Native→JS | 摇一摇事件回调 | | **页面操作** | `OpenurlTitleData` | JS→Native | 打开新WebView页面 | | | `browser` | JS→Native | 系统浏览器打开链接 | | | `backgameData` | JS→Native | 返回并传递数据 | | **复制粘贴** | `gameCopytext` | JS→Native | 复制文本到剪贴板 | | | `gamepastetext` | JS→Native | 获取剪贴板内容 | | **电话状态** | `getphonestate` | JS→Native | 获取电话状态 | | | `phoneStateChanged` | Native→JS | 电话状态变化 | | **应用管理** | `getGameinstall` | JS→Native | 检查应用安装状态 | | | `getmarketname` | JS→Native | 获取市场来源 | | **前后台** | `appservice` | Native→JS | 前后台状态通知 | ### 核心组件 #### 1. 桥接框架核心类 - **`BridgeWebView`**: 继承自腾讯X5 WebView,实现JS桥接功能 - **`BridgeHandler`**: 处理JS调用原生的接口 - **`CallBackFunction`**: 原生向JS回调的接口 - **`Message`**: 消息传递的数据模型 #### 2. JS桥接原理 ```javascript // JS端调用原生方法 WebViewJavascriptBridge.callHandler('handlerName', data, function(response) { console.log('Response from native:', response); }); // JS端注册方法供原生调用 WebViewJavascriptBridge.registerHandler('jsHandlerName', function(data, responseCallback) { responseCallback('Response from JS'); }); ``` ```java // 原生端注册方法供JS调用 x5webview.registerHandler("handlerName", new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) { // 处理JS传来的数据 function.onCallBack("Response from native"); } }); // 原生端调用JS方法 x5webview.callHandler("jsHandlerName", data, new CallBackFunction() { @Override public void onCallBack(String data) { // 处理JS的回调数据 } }); ``` ### 完整API接口详细说明 #### 1. 用户认证与登录类 | API名称 | 调用方向 | 参数 | 返回值 | 说明 | |---------|----------|------|-------|------| | `accreditlogin` | JS→Native | 登录类型 | 无 | 触发授权登录(支持微信/QQ) | | `sharelogin` | Native→JS | 用户信息JSON | 无 | 登录成功后回传用户信息 | **JS调用示例:** ```javascript // 触发微信登录 WebViewJavascriptBridge.callHandler('accreditlogin', '2', function(response) { console.log('登录触发成功'); }); ``` **用户信息JSON格式:** ```json { "openid": "用户openid", "headimgurl": "头像URL", "nickname": "用户昵称", "sex": "性别(1男2女)", "city": "所在城市", "province": "所在省份", "unionid": "微信unionid" } ``` #### 2. 社交分享功能 | API名称 | 调用方向 | 参数 | 返回值 | 说明 | |---------|----------|------|-------|------| | `friendsSharetypeUrlToptitleDescript` | JS→Native | 分享参数JSON | 无 | 微信分享(好友/朋友圈/抖音) | | `sharesuccess` | Native→JS | 分享结果JSON | 无 | 分享结果回调 | **JS调用示例:** ```javascript // 微信好友分享 var shareData = { "type": "1", // 1-普通分享, 2-截图分享, 3-图片分享 "sharefriend": "1", // 1-好友, 2-朋友圈, 3-抖音 "webpageUrl": "https://example.com", "title": "分享标题", "description": "分享描述", "sharetype": "link" }; WebViewJavascriptBridge.callHandler('friendsSharetypeUrlToptitleDescript', JSON.stringify(shareData)); ``` **分享结果回调:** ```javascript // 注册分享结果监听 WebViewJavascriptBridge.registerHandler('sharesuccess', function(data) { var result = JSON.parse(data); if(result.success === 1) { console.log('分享成功'); } else { console.log('分享失败'); } }); ``` #### 3. 设备信息获取类 | API名称 | 调用方向 | 参数 | 返回值 | 说明 | |---------|----------|------|-------|------| | `getphoneInfo` | JS→Native | 无 | 设备信息JSON | 获取手机基本配置信息 | | `getbattery` | JS→Native | 无 | 电量百分比 | 获取当前电池电量 | | `getwifiLevel` | JS→Native | 无 | WiFi信息JSON | 获取WiFi信号强度和名称 | | `getnetwork` | JS→Native | 无 | 网络状态 | 获取网络连接类型 | | `getTime` | JS→Native | 无 | 时间戳 | 获取系统当前时间戳 | | `getcompareCode` | JS→Native | 无 | 版本对比结果 | 获取APK版本对比结果 | **JS调用示例:** ```javascript // 获取设备信息 WebViewJavascriptBridge.callHandler('getphoneInfo', '', function(response) { var deviceInfo = JSON.parse(response); console.log('设备型号:' + deviceInfo.model); console.log('系统版本:' + deviceInfo.version); }); // 获取网络状态 WebViewJavascriptBridge.callHandler('getnetwork', '', function(response) { // 返回值:1-无网络, 2-WiFi, 3-移动网络 console.log('网络状态:' + response); }); ``` #### 4. 多媒体功能类 | API名称 | 调用方向 | 参数 | 返回值 | 说明 | |---------|----------|------|-------|------| | `getphoto` | JS→Native | 图片URL数组JSON | 无 | 批量下载网络图片到本地 | | `opensaoma` | JS→Native | 无 | 扫码结果 | 打开相机扫描二维码 | | `opencamera` | JS→Native | 无 | 图片路径 | 打开相机拍照 | **图片下载示例:** ```javascript // 批量下载图片 var imageUrls = ["http://example.com/1.jpg", "http://example.com/2.jpg"]; WebViewJavascriptBridge.callHandler('getphoto', JSON.stringify(imageUrls)); // 监听下载完成回调 WebViewJavascriptBridge.registerHandler('getphoto', function(data) { var result = JSON.parse(data); console.log('图片下载完成:' + result.localPath); }); ``` #### 5. 音频功能类 | API名称 | 调用方向 | 参数 | 返回值 | 说明 | |---------|----------|------|-------|------| | `prepareaudio` | JS→Native | 无 | 无 | 开始录音准备 | | `mediaTypeAudio` | JS→Native | 音频参数JSON | 无 | 播放音频文件 | | `voicePlaying` | JS→Native | 语音动画参数 | 无 | 显示语音播放动画 | | `srcIsloop` | JS→Native | 循环播放参数 | 无 | 设置音频循环播放 | **音频播放示例:** ```javascript // 播放音频 var audioData = { "audiourl": "http://example.com/audio.mp3", "type": "1", // 1-普通播放, 2-历史记录播放 "user": "0" // 用户位置索引 }; WebViewJavascriptBridge.callHandler('mediaTypeAudio', JSON.stringify(audioData)); ``` #### 6. 实时音视频功能(声网Agora) | API名称 | 调用方向 | 参数 | 返回值 | 说明 | |---------|----------|------|-------|------| | `createRoom` | JS→Native | 房间信息JSON | 无 | 创建或加入语音/视频房间 | | `exitRoom` | JS→Native | 无 | 无 | 退出当前音视频房间 | | `getVideoinfo` | JS→Native | 无 | 视频窗口信息JSON | 获取视频悬浮窗位置信息 | | `DragViewvideoIsshow` | JS→Native | 显示类型 | 无 | 控制视频悬浮窗显示/隐藏 | **房间管理示例:** ```javascript // 创建音视频房间 var roomData = { "roomId": "12345", "userId": "user001", "token": "agora_token", "type": "video" // audio 或 video }; WebViewJavascriptBridge.callHandler('createRoom', JSON.stringify(roomData)); // 退出房间 WebViewJavascriptBridge.callHandler('exitRoom', ''); ``` #### 7. 地理位置服务类 | API名称 | 调用方向 | 参数 | 返回值 | 说明 | |---------|----------|------|-------|------| | `startlocation` | JS→Native | 定位类型 | 无 | 开始GPS定位 | | `getlocationinfo` | JS→Native | 无 | 位置信息JSON | 获取当前位置信息 | | `locationinfo` | Native→JS | 位置信息JSON | 无 | 定位结果回调 | **定位功能示例:** ```javascript // 开始定位 WebViewJavascriptBridge.callHandler('startlocation', '1'); // 1-连续定位, 2-单次定位 // 监听定位结果 WebViewJavascriptBridge.registerHandler('locationinfo', function(data) { var location = JSON.parse(data); console.log('纬度:' + location.latitude); console.log('经度:' + location.longitude); console.log('地址:' + location.address); }); ``` #### 8. 系统交互功能类 | API名称 | 调用方向 | 参数 | 返回值 | 说明 | |---------|----------|------|-------|------| | `vibrator` | JS→Native | 震动时长(毫秒) | 无 | 手机震动指定时长 | | `repeatvibrator` | JS→Native | 震动参数 | 无 | 重复震动 | | `canclevibrator` | JS→Native | 无 | 无 | 取消所有震动 | | `orientation` | JS→Native | 方向值 | 无 | 设置屏幕方向锁定 | | `finsh` | JS→Native | 无 | 无 | 退出应用程序 | | `notification` | JS→Native | 通知内容 | 无 | 发送系统通知 | **系统交互示例:** ```javascript // 震动500毫秒 WebViewJavascriptBridge.callHandler('vibrator', '500'); // 设置横屏 WebViewJavascriptBridge.callHandler('orientation', '0'); // 0-横屏, 1-竖屏 // 发送通知 WebViewJavascriptBridge.callHandler('notification', '您有新消息'); ``` #### 9. 摇一摇功能类 | API名称 | 调用方向 | 参数 | 返回值 | 说明 | |---------|----------|------|-------|------| | `startshake` | JS→Native | 无 | 无 | 开始监听摇一摇动作 | | `stopshake` | JS→Native | 无 | 无 | 停止监听摇一摇 | | `SwitchShake` | JS→Native | 开关状态 | 无 | 摇一摇震动声音开关 | | `shake` | Native→JS | 摇一摇事件 | 无 | 摇一摇动作回调 | **摇一摇功能示例:** ```javascript // 开始摇一摇监听 WebViewJavascriptBridge.callHandler('startshake', ''); // 监听摇一摇事件 WebViewJavascriptBridge.registerHandler('shake', function(data) { console.log('检测到摇一摇动作'); // 处理摇一摇逻辑 }); // 停止摇一摇 WebViewJavascriptBridge.callHandler('stopshake', ''); ``` #### 10. 网页操作类 | API名称 | 调用方向 | 参数 | 返回值 | 说明 | |---------|----------|------|-------|------| | `OpenurlTitleData` | JS→Native | 网页参数JSON | 无 | 打开新的WebView页面 | | `browser` | JS→Native | URL | 无 | 使用系统浏览器打开链接 | | `backgameData` | JS→Native | 返回数据 | 无 | 返回上级页面并传递数据 | **页面跳转示例:** ```javascript // 打开新页面 var pageData = { "url": "http://example.com/page.html", "title": "页面标题", "data": "传递数据", "orientation": "1" // 0-横屏, 1-竖屏 }; WebViewJavascriptBridge.callHandler('OpenurlTitleData', JSON.stringify(pageData)); // 返回上级页面 WebViewJavascriptBridge.callHandler('backgameData', '返回的数据'); ``` #### 11. 复制粘贴功能类 | API名称 | 调用方向 | 参数 | 返回值 | 说明 | |---------|----------|------|-------|------| | `gameCopytext` | JS→Native | 要复制的文本 | 无 | 复制文本到系统剪贴板 | | `gamepastetext` | JS→Native | 无 | 剪贴板内容 | 获取剪贴板中的文本 | **复制粘贴示例:** ```javascript // 复制文本 WebViewJavascriptBridge.callHandler('gameCopytext', '要复制的文本内容'); // 获取剪贴板内容 WebViewJavascriptBridge.callHandler('gamepastetext', '', function(response) { console.log('剪贴板内容:' + response); }); ``` #### 12. 电话状态监听类 | API名称 | 调用方向 | 参数 | 返回值 | 说明 | |---------|----------|------|-------|------| | `getphonestate` | JS→Native | 无 | 电话状态码 | 获取当前电话通话状态 | | `phoneStateChanged` | Native→JS | 状态码 | 无 | 电话状态变化回调 | **电话状态监听示例:** ```javascript // 获取电话状态 WebViewJavascriptBridge.callHandler('getphonestate', '', function(response) { // 0-空闲, 1-通话中, 2-来电振铃 console.log('电话状态:' + response); }); // 监听电话状态变化 WebViewJavascriptBridge.registerHandler('phoneStateChanged', function(data) { console.log('电话状态改变:' + data); }); ``` #### 13. 应用管理类 | API名称 | 调用方向 | 参数 | 返回值 | 说明 | |---------|----------|------|-------|------| | `getGameinstall` | JS→Native | 包名 | 安装状态 | 检查指定应用是否已安装 | | `openApplyDownloadpath` | JS→Native | 无 | 无 | 打开应用下载安装包 | | `getmarketname` | JS→Native | 无 | 市场标识 | 获取应用市场来源标识 | | `getothername` | JS→Native | 文件夹名 | 自定义名称 | 获取自定义文件夹名称 | | `getOther` | JS→Native | 无 | 其他信息 | 获取其他配置信息 | **应用管理示例:** ```javascript // 检查应用是否安装 WebViewJavascriptBridge.callHandler('getGameinstall', 'com.tencent.mm', function(response) { if(response === '1') { console.log('微信已安装'); } else { console.log('微信未安装'); } }); // 获取市场来源 WebViewJavascriptBridge.callHandler('getmarketname', '', function(response) { console.log('市场来源:' + response); }); ``` #### 14. 前后台状态管理类 | API名称 | 调用方向 | 参数 | 返回值 | 说明 | |---------|----------|------|-------|------| | `SwitchOverGameData` | JS→Native | 流量提醒参数 | 无 | 设置移动网络流量提醒 | | `appservice` | Native→JS | 前后台状态 | 无 | 应用前后台状态变化通知 | **前后台监听示例:** ```javascript // 监听应用前后台状态 WebViewJavascriptBridge.registerHandler('appservice', function(data) { if(data === '1') { console.log('应用进入前台'); // 恢复游戏逻辑 } else if(data === '2') { console.log('应用进入后台'); // 暂停游戏逻辑 } }); ``` #### 15. 通讯录功能类(已禁用) | API名称 | 调用方向 | 参数 | 返回值 | 说明 | |---------|----------|------|-------|------| | `getAddressBook` | JS→Native | 无 | 通讯录数据 | 获取手机通讯录(已注释禁用) | > **注意**: 通讯录功能因隐私政策要求已被注释禁用。 ### 技术实现细节 #### JS桥接机制 项目采用自定义的JS Bridge实现WebView与原生的双向通信: **核心组件:** - `BridgeWebView.java` - 继承腾讯X5 WebView,实现桥接功能 - `BridgeHandler.java` - 原生端消息处理接口 - `CallBackFunction.java` - JS回调函数接口 - `Message.java` - 消息实体类 - `WebViewJavascriptBridge.js` - JS端桥接脚本 **消息传递流程:** 1. JS调用原生:`WebViewJavascriptBridge.callHandler(handlerName, data, callback)` 2. 消息序列化并添加到消息队列 3. 通过`loadUrl()`触发原生方法`flushMessageQueue()` 4. 原生端解析消息并调用对应的`BridgeHandler` 5. 处理完成后通过`CallBackFunction`返回结果给JS **线程安全保证:** ```java // 确保JS调用在主线程执行 if (Thread.currentThread() == Looper.getMainLooper().getThread()) { this.loadUrl(javascriptCommand); } ``` #### 权限管理机制 应用采用动态权限申请机制,主要权限包括: **存储权限(必需):** ```java // 动态申请存储权限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); } } ``` **位置权限(可选):** - GPS定位:`ACCESS_FINE_LOCATION` - 网络定位:`ACCESS_COARSE_LOCATION` **音频权限(可选):** - 录音权限:`RECORD_AUDIO` - 音频设置:`MODIFY_AUDIO_SETTINGS` #### 资源更新机制 项目支持热更新,无需重新安装APK即可更新游戏内容: **更新流程:** 1. 检查本地版本文件`version.xml` 2. 请求服务器版本信息 3. 比较版本号决定更新策略: - APK版本更新:下载新APK并提示安装 - 资源版本更新:下载资源ZIP包并解压 4. 更新本地版本文件 5. 重新加载游戏 **版本控制文件:** ```xml 资源版本号 游戏标识 游戏名称 ``` #### 微信SDK集成 项目集成微信开放平台SDK,支持登录、分享功能: **回调Activity配置:** ```xml ``` **分享实现:** - 支持链接分享、图片分享、小程序分享 - 区分好友分享和朋友圈分享 - 抖音分享通过Intent方式实现 #### 音视频功能 集成声网Agora SDK实现实时音视频通话: **基本功能:** - 语音房间创建/加入 - 实时语音通话 - 视频悬浮窗显示 - 音频录制播放 **房间管理:** ```javascript // 创建音视频房间 var roomConfig = { "roomId": "房间ID", "userId": "用户ID", "token": "Agora Token", "channelProfile": "COMMUNICATION" }; ``` #### 定位服务 基于高德地图SDK实现精确定位: **定位模式:** - 连续定位:持续获取位置更新 - 单次定位:获取一次高精度位置 **位置信息回调:** ```javascript // 位置信息格式 { "latitude": "31.12345", // 纬度 "longitude": "121.12345", // 经度 "accuracy": "15.0", // 精度(米) "address": "详细地址", "city": "城市名称", "province": "省份" } ``` ### API调用最佳实践 #### 1. 错误处理 ```javascript // JS端错误处理 WebViewJavascriptBridge.callHandler('apiName', data, function(response) { try { var result = JSON.parse(response); if(result.success) { // 处理成功逻辑 } else { console.error('API调用失败:', result.error); } } catch(e) { console.error('响应解析失败:', e); } }); ``` #### 2. 生命周期管理 ```java // 原生端生命周期处理 @Override protected void onDestroy() { super.onDestroy(); // 清理WebView if(x5webview != null) { x5webview.removeAllViews(); x5webview.destroy(); x5webview = null; } // 停止定位服务 if(locationClient != null) { locationClient.stopLocation(); } } ``` #### 3. 内存优化 ```java // WebView内存优化 public void optimizeWebView() { // 清除缓存 x5webview.clearCache(true); // 清除历史记录 x5webview.clearHistory(); // 暂停JavaScript执行 x5webview.onPause(); x5webview.pauseTimers(); } ``` #### 4. 网络优化 ```java // 网络状态监听 private void checkNetworkState() { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); if(activeNetwork != null && activeNetwork.isConnected()) { if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) { // WiFi连接 notifyJSNetworkState("2"); } else { // 移动网络连接 notifyJSNetworkState("3"); } } else { // 无网络连接 notifyJSNetworkState("1"); } } ``` ### 调试和测试 #### WebView调试 ```java // 启用WebView调试模式 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { WebView.setWebContentsDebuggingEnabled(true); } ``` 在Chrome浏览器中访问 `chrome://inspect` 可以调试WebView内容。 #### JS Bridge测试 ```javascript // 测试桥接连通性 function testBridge() { if(typeof WebViewJavascriptBridge !== 'undefined') { console.log('Bridge已就绪'); // 测试简单API调用 WebViewJavascriptBridge.callHandler('getTime', '', function(response) { console.log('当前时间:', response); }); } else { console.error('Bridge未初始化'); } } ``` #### 性能监控 ```java // 监控WebView性能 public class WebViewPerformanceMonitor { private long pageStartTime; @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { pageStartTime = System.currentTimeMillis(); } @Override public void onPageFinished(WebView view, String url) { long loadTime = System.currentTimeMillis() - pageStartTime; Log.d("Performance", "页面加载耗时: " + loadTime + "ms"); } } ``` ### 常见问题和解决方案 #### 1. JS Bridge不响应 **问题**: JS调用原生方法无响应 **解决方案**: - 检查WebView是否已完全加载 - 确认Handler名称拼写正确 - 验证是否在主线程调用 #### 2. 分享功能失效 **问题**: 微信分享无法拉起 **解决方案**: - 检查微信SDK版本兼容性 - 验证应用签名是否与微信开放平台一致 - 确认回调Activity配置正确 #### 3. 定位权限问题 **问题**: 无法获取位置信息 **解决方案**: - 动态申请定位权限 - 检查GPS是否开启 - 验证高德SDK配置 #### 4. 音视频通话异常 **问题**: 声网通话质量差或连接失败 **解决方案**: - 检查网络连接质量 - 验证Agora Token有效性 - 优化音频编码参数 ### 完整集成示例 #### 前端HTML页面集成示例 ```html TSGame Web
``` #### 原生端集成示例 ```java public class GameWebViewActivity extends Activity { private BridgeWebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_webview); // 初始化WebView webView = findViewById(R.id.webview); setupWebView(); registerHandlers(); // 加载游戏页面 webView.loadUrl("file:///android_asset/game.html"); } private void setupWebView() { WebSettings settings = webView.getSettings(); settings.setJavaScriptEnabled(true); settings.setDomStorageEnabled(true); settings.setAllowFileAccess(true); settings.setAllowContentAccess(true); // 设置UserAgent String userAgent = settings.getUserAgentString(); settings.setUserAgentString(userAgent + " TSGame/1.0"); } private void registerHandlers() { // 注册登录处理 webView.registerHandler("accreditlogin", new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) { if("2".equals(data)) { // 触发微信登录 wechatLogin(); } function.onCallBack("success"); } }); // 注册分享处理 webView.registerHandler("friendsSharetypeUrlToptitleDescript", new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) { try { JSONObject shareData = new JSONObject(data); String type = shareData.getString("type"); String shareType = shareData.getString("sharefriend"); if("1".equals(shareType)) { // 微信好友分享 shareToWechatFriend(shareData); } else if("2".equals(shareType)) { // 微信朋友圈分享 shareToWechatTimeline(shareData); } } catch (JSONException e) { e.printStackTrace(); } } }); // 注册设备信息处理 webView.registerHandler("getphoneInfo", new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) { JSONObject deviceInfo = getDeviceInfo(); function.onCallBack(deviceInfo.toString()); } }); // 注册定位处理 webView.registerHandler("startlocation", new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) { if("1".equals(data)) { startContinuousLocation(); } else { startSingleLocation(); } } }); // 注册拍照处理 webView.registerHandler("opencamera", new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) { cameraCallback = function; openCamera(); } }); } private void wechatLogin() { // 微信登录实现 SendAuth.Req req = new SendAuth.Req(); req.scope = "snsapi_userinfo"; req.state = "tsgame_login"; api.sendReq(req); } private JSONObject getDeviceInfo() { JSONObject info = new JSONObject(); try { info.put("model", Build.MODEL); info.put("brand", Build.BRAND); info.put("version", Build.VERSION.RELEASE); info.put("sdk", Build.VERSION.SDK_INT); DisplayMetrics dm = getResources().getDisplayMetrics(); info.put("screenWidth", dm.widthPixels); info.put("screenHeight", dm.heightPixels); info.put("density", dm.density); } catch (JSONException e) { e.printStackTrace(); } return info; } // 微信登录成功回调 public void onWechatLoginSuccess(String openId, String nickname, String headUrl) { JSONObject userInfo = new JSONObject(); try { userInfo.put("openid", openId); userInfo.put("nickname", nickname); userInfo.put("headimgurl", headUrl); // 回调给JS webView.callHandler("sharelogin", userInfo.toString(), null); } catch (JSONException e) { e.printStackTrace(); } } // 定位成功回调 public void onLocationSuccess(double lat, double lng, String address) { JSONObject location = new JSONObject(); try { location.put("latitude", String.valueOf(lat)); location.put("longitude", String.valueOf(lng)); location.put("address", address); // 回调给JS webView.callHandler("locationinfo", location.toString(), null); } catch (JSONException e) { e.printStackTrace(); } } @Override protected void onDestroy() { super.onDestroy(); if(webView != null) { webView.removeAllViews(); webView.destroy(); } } } ``` 这个完整的集成示例展示了: 1. 前端HTML页面如何初始化Bridge连接 2. 如何注册监听原生回调 3. 如何调用各种原生API 4. 原生端如何注册Handler处理JS调用 5. 如何实现完整的登录、分享、定位等功能流程 通过这个示例,开发者可以快速理解和集成TSGame的WebView与原生交互功能。 #### JS端调用原生方法示例 ```javascript // 1. 获取设备信息 WebViewJavascriptBridge.callHandler('getphoneInfo', '', function(response) { console.log('设备信息:', response); }); // 2. 微信分享 var shareData = { type: "1", sharefriend: "1", webpageUrl: "https://example.com", title: "分享标题", description: "分享描述" }; WebViewJavascriptBridge.callHandler('friendsSharetypeUrlToptitleDescript', JSON.stringify(shareData)); // 3. 震动效果 WebViewJavascriptBridge.callHandler('vibrator', '500'); ``` #### 原生端调用JS方法示例 ```java // 1. 发送用户登录信息给JS JSONObject userInfo = new JSONObject(); userInfo.put("openid", openid); userInfo.put("nickname", nickname); x5webview.callHandler("sharelogin", userInfo.toString(), new CallBackFunction() { @Override public void onCallBack(String data) { // JS的回调处理 } }); // 2. 通知JS分享结果 JSONObject result = new JSONObject(); result.put("success", 1); result.put("type", "1"); x5webview.callHandler("sharesuccess", result.toString(), null); ``` ### 注意事项 #### 数据传递规范 1. **数据格式**: 所有传递的数据都是字符串格式,复杂数据需要JSON序列化 2. **异步回调**: 大部分API都支持异步回调机制 3. **错误处理**: 需要在JS和原生端都做好异常处理 4. **线程安全**: 原生端调用JS必须在主线程进行 5. **生命周期**: 注意WebView生命周期,避免内存泄漏 #### WebView与原生通信注意事项 1. **消息队列**: 使用消息队列机制确保数据不丢失 2. **特殊字符转义**: JSON字符串中的特殊字符需要转义处理 3. **回调函数**: 每个API调用可以包含一个回调函数 4. **超时处理**: 长时间无响应的API调用需要超时机制 #### 性能优化建议 1. **减少频繁调用**: 避免在短时间内频繁调用原生API 2. **数据压缩**: 传递大量数据时考虑压缩或分批传输 3. **内存管理**: 及时释放不需要的WebView资源 4. **缓存策略**: 合理利用WebView缓存机制 #### 安全性考虑 1. **数据校验**: 对JS传入的数据进行严格校验 2. **权限控制**: 敏感API需要权限检查 3. **防注入**: 防范恶意JS代码注入 4. **HTTPS通信**: 敏感数据传输使用HTTPS #### 兼容性处理 1. **Android版本**: 针对不同Android版本做适配 2. **设备差异**: 考虑不同设备的硬件差异 3. **WebView版本**: 处理不同WebView内核版本的差异 4. **网络环境**: 适配不同网络环境下的功能表现 ### 3. 主要Activity流转 ``` weclomeactivity1 (启动页) ↓ (配置加载完成) webviewActivity/NewwebviewActivity (主游戏页面) ↓ (外部链接) openwebActivity1 (外部页面) ↓ (微信回调) WXEntryActivity (微信相关) ``` ### 4. 关键配置文件 #### version.xml (版本配置) ```xml 1 game001 游戏名称 ``` #### app_data.js (运行时配置) ```javascript var app_version = 1; var app_gameconfig = 'config_url'; var app_gamedir = 'game_directory'; var app_gamestart = 'start_file'; var app_agent = 'agent_id'; var app_channel = 'channel_id'; var app_market = 'market_id'; ``` ## 平台技术栈与第三方服务 ### Android平台 #### 开发工具和框架 - **Gradle**: 7.0+ (构建工具) - **Android SDK**: API 33 - **最低支持**: API 21 (Android 5.0) - **开发语言**: Java 1.8 / Kotlin 1.8 - **IDE**: Android Studio #### 第三方SDK集成 | 功能模块 | Android SDK | 版本 | |---------|-------------|------| | **WebView** | 腾讯X5 WebView | 44286 | | **网络请求** | OkHttp | 4.12.0 | | **JSON解析** | Gson | 2.8.9 | | **微信SDK** | 微信开放平台SDK | 6.8.11 | | **地图定位** | 高德地图SDK | 5.2.0 | | **音视频** | 声网Agora SDK | 最新版 | | **统计分析** | 友盟统计 | 7.5.0 | | **崩溃收集** | 腾讯Bugly | 3.4.4 | | **二维码扫描** | ZXing | 3.5.0 | ### iOS平台 #### 开发工具和框架 - **Xcode**: 14.0+ - **iOS SDK**: iOS 16.0 - **最低支持**: iOS 11.0 - **开发语言**: Objective-C / Swift 5.0 - **依赖管理**: CocoaPods / Swift Package Manager #### 第三方SDK集成 | 功能模块 | iOS SDK | 版本 | |---------|---------|------| | **WebView** | WKWebView (系统) | - | | **网络请求** | AFNetworking / Alamofire | 5.0+ | | **JSON解析** | 系统JSONSerialization | - | | **微信SDK** | 微信开放平台SDK | 1.9.2 | | **地图定位** | 高德地图SDK / CoreLocation | 9.0+ | | **音视频** | 声网Agora SDK | 最新版 | | **统计分析** | 友盟统计 / Firebase | 最新版 | | **崩溃收集** | Bugly / Crashlytics | 最新版 | | **二维码扫描** | AVFoundation (系统) | - | ### HarmonyOS平台 #### 开发工具和框架 - **DevEco Studio**: 4.0+ - **HarmonyOS SDK**: API 9 - **最低支持**: API 8 (HarmonyOS 3.0) - **开发语言**: ArkTS / TypeScript - **应用模型**: Stage模型 #### 第三方SDK集成 | 功能模块 | HarmonyOS SDK | 版本 | |---------|---------------|------| | **WebView** | Web组件 (系统) | - | | **网络请求** | @ohos.net.http | 系统API | | **JSON解析** | JSON (系统) | - | | **微信SDK** | 微信开放平台SDK | 待适配 | | **地图定位** | 华为地图服务 | 最新版 | | **音视频** | 声网Agora SDK | 最新版 | | **统计分析** | 华为分析服务 | 最新版 | | **崩溃收集** | 华为崩溃服务 | 最新版 | | **二维码扫描** | @ohos.multimedia.camera | 系统API | ### 跨平台共享组件 - **H5游戏引擎**: HTML5 + CSS3 + JavaScript - **JS Bridge**: 统一接口定义 - **音视频通话**: 声网Agora SDK(全平台支持) - **数据存储**: 本地存储 + 云端同步 - **配置管理**: JSON配置文件 ## 跨平台权限管理 ### Android权限配置 #### 核心权限 ```xml ``` #### 定位权限 ```xml ``` #### 音频权限 ```xml ``` #### 其他权限 ```xml ``` ### iOS权限配置 #### Info.plist配置 ```xml NSCameraUsageDescription 应用需要使用相机进行拍照功能 NSMicrophoneUsageDescription 应用需要使用麦克风进行语音通话 NSLocationWhenInUseUsageDescription 应用需要获取位置信息提供定位服务 NSLocationAlwaysAndWhenInUseUsageDescription 应用需要获取位置信息提供定位服务 NSPhotoLibraryUsageDescription 应用需要访问相册选择图片 NSContactsUsageDescription 应用需要访问通讯录获取联系人信息 ``` #### App Transport Security ```xml NSAppTransportSecurity NSAllowsArbitraryLoads ``` ### HarmonyOS权限配置 #### module.json5配置 ```json { "requestPermissions": [ { "name": "ohos.permission.INTERNET", "reason": "网络访问", "usedScene": { "abilities": ["EntryAbility"], "when": "inuse" } }, { "name": "ohos.permission.LOCATION", "reason": "获取位置信息", "usedScene": { "abilities": ["EntryAbility"], "when": "inuse" } }, { "name": "ohos.permission.CAMERA", "reason": "拍照功能", "usedScene": { "abilities": ["EntryAbility"], "when": "inuse" } }, { "name": "ohos.permission.MICROPHONE", "reason": "录音功能", "usedScene": { "abilities": ["EntryAbility"], "when": "inuse" } }, { "name": "ohos.permission.READ_MEDIA", "reason": "读取媒体文件", "usedScene": { "abilities": ["EntryAbility"], "when": "inuse" } }, { "name": "ohos.permission.WRITE_MEDIA", "reason": "写入媒体文件", "usedScene": { "abilities": ["EntryAbility"], "when": "inuse" } } ] } ``` ### 权限动态申请代码示例 #### Android权限申请 ```java // 检查和申请权限 private void checkPermissions() { String[] permissions = { Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, Manifest.permission.ACCESS_FINE_LOCATION }; List permissionsToRequest = new ArrayList<>(); for (String permission : permissions) { if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { permissionsToRequest.add(permission); } } if (!permissionsToRequest.isEmpty()) { ActivityCompat.requestPermissions(this, permissionsToRequest.toArray(new String[0]), REQUEST_PERMISSIONS); } } ``` #### iOS权限申请 ```objc // 请求相机权限 - (void)requestCameraPermission { AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]; if (status == AVAuthorizationStatusNotDetermined) { [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) { dispatch_async(dispatch_get_main_queue(), ^{ if (granted) { // 权限获取成功 } else { // 权限被拒绝 } }); }]; } } // 请求定位权限 - (void)requestLocationPermission { CLLocationManager *locationManager = [[CLLocationManager alloc] init]; [locationManager requestWhenInUseAuthorization]; } ``` #### HarmonyOS权限申请 ```typescript // 申请权限 import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl'; async requestPermissions() { const atManager = abilityAccessCtrl.createAtManager(); const permissions: Permissions[] = [ 'ohos.permission.CAMERA', 'ohos.permission.MICROPHONE', 'ohos.permission.LOCATION' ]; try { await atManager.requestPermissionsFromUser(this.context, permissions); console.log('权限申请成功'); } catch (error) { console.log('权限申请失败:', error); } } ``` ## 安全配置 ### 签名配置 - **Keystore**: gamehall.keystore - **密码**: tswl2015 - **别名**: gamehall - **签名版本**: v1 + v2 ### 网络安全 - `usesCleartextTraffic="true"` - 允许HTTP流量 - 支持HTTPS和HTTP混合请求 ### 文件权限 - 使用FileProvider共享文件 - 适配Android 7.0+文件访问限制 ## 跨平台构建和发布 ### Android平台构建 #### 环境要求 - **JDK**: OpenJDK 11+ - **Android Studio**: 2022.1.1+ - **Gradle**: 7.0+ - **Android SDK**: API 33 #### 构建命令 ```bash # 调试版本 ./gradlew assembleDebug # 发布版本 ./gradlew assembleRelease # 清理项目 ./gradlew clean # 生成签名APK ./gradlew assembleRelease -Pandroid.injected.signing.store.file=keystore/gamehall.keystore ``` #### 签名配置 ```gradle // app/build.gradle android { signingConfigs { release { storeFile file('../keystore/gamehall.keystore') storePassword 'tswl2015' keyAlias 'gamehall' keyPassword 'tswl2015' } } buildTypes { release { signingConfig signingConfigs.release minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } ``` ### iOS平台构建 #### 环境要求 - **macOS**: 12.0+ - **Xcode**: 14.0+ - **iOS SDK**: 16.0+ - **CocoaPods**: 1.11+ #### 构建步骤 ```bash # 安装依赖 cd ios pod install # 清理项目 xcodebuild clean -workspace TSGame.xcworkspace -scheme TSGame # 构建Debug版本 xcodebuild build -workspace TSGame.xcworkspace -scheme TSGame -configuration Debug # 构建Release版本 xcodebuild archive -workspace TSGame.xcworkspace -scheme TSGame -configuration Release -archivePath build/TSGame.xcarchive # 导出IPA xcodebuild -exportArchive -archivePath build/TSGame.xcarchive -exportPath build/ipa -exportOptionsPlist ExportOptions.plist ``` #### 证书配置 ```xml method app-store teamID YOUR_TEAM_ID provisioningProfiles com.jx.jyhd YOUR_PROVISIONING_PROFILE ``` ### HarmonyOS平台构建 #### 环境要求 - **DevEco Studio**: 4.0+ - **HarmonyOS SDK**: API 9 - **Node.js**: 16.0+ - **npm**: 8.0+ #### 构建步骤 ```bash # 清理项目 hvigorw clean # 构建Debug版本 hvigorw assembleHap --mode module -p module=entry@default -p debuggable=true # 构建Release版本 hvigorw assembleHap --mode module -p module=entry@default -p debuggable=false # 构建APP包 hvigorw assembleApp --mode module -p module=entry@default ``` #### 签名配置 ```json5 // build-profile.json5 { "app": { "signingConfigs": [ { "name": "default", "type": "HarmonyOS", "material": { "certpath": "path/to/certificate.p12", "storePassword": "your_password", "keyAlias": "your_key_alias", "keyPassword": "your_key_password", "profile": "path/to/profile.p7b", "signAlg": "SHA256withECDSA", "verify": true, "compatibleVersion": 9 } } ] } } ``` ### 自动化构建配置 #### CI/CD流水线 (GitHub Actions) ```yaml # .github/workflows/build.yml name: Multi-Platform Build on: push: branches: [ main, develop ] pull_request: branches: [ main ] jobs: build-android: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up JDK 11 uses: actions/setup-java@v3 with: java-version: '11' distribution: 'adopt' - name: Build Android APK run: | cd android ./gradlew assembleRelease - name: Upload APK uses: actions/upload-artifact@v3 with: name: android-apk path: android/app/build/outputs/apk/release/ build-ios: runs-on: macos-latest steps: - uses: actions/checkout@v3 - name: Set up Xcode uses: maxim-lobanov/setup-xcode@v1 with: xcode-version: '14.0' - name: Install CocoaPods run: | cd ios pod install - name: Build iOS run: | cd ios xcodebuild build -workspace TSGame.xcworkspace -scheme TSGame -configuration Release build-harmonyos: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Node.js uses: actions/setup-node@v3 with: node-version: '16' - name: Build HarmonyOS run: | cd harmonyos npm install hvigorw assembleHap --mode module -p module=entry@default ``` ### 发布配置 #### Android发布 - **Google Play Store**: 上传AAB包,配置应用签名 - **国内应用市场**: 上传APK包到各大应用商店 - **企业分发**: 配置内部分发渠道 #### iOS发布 - **App Store**: 通过App Store Connect上传IPA - **TestFlight**: 内测版本分发 - **企业证书**: 企业内部分发 #### HarmonyOS发布 - **华为应用市场**: 上传HAP/APP包 - **企业分发**: 通过华为开发者平台配置 ## 跨平台开发指南 ### 平台适配策略 #### 1. 功能对等原则 确保各平台实现相同的核心功能,但可根据平台特性进行优化: - **必须功能**: 游戏核心玩法、登录认证、基础分享 - **平台特色**: 分享渠道、推送通知 - **性能优化**: 根据平台特性调整渲染和网络策略 #### 2. 统一接口设计 所有平台实现相同的JS Bridge API接口: ```typescript // bridge-api.d.ts - 统一接口定义 interface TSGameBridge { // 用户认证 accreditLogin(type: string): Promise; // 设备信息 getPhoneInfo(): Promise; getNetworkStatus(): Promise; // 多媒体 openCamera(): Promise; playAudio(config: AudioConfig): Promise; // 系统交互 vibrate(duration: number): Promise; showNotification(message: string): Promise; // 平台特定功能(可选) platformSpecific?: { [key: string]: any; }; } ``` #### 3. 平台差异处理 ```javascript // platform-detector.js const Platform = { isAndroid: () => /Android/i.test(navigator.userAgent), isIOS: () => /iPhone|iPad|iPod/i.test(navigator.userAgent), isHarmonyOS: () => /HarmonyOS/i.test(navigator.userAgent), // 根据平台调用不同的API shareToSocial: (data) => { if (Platform.isAndroid()) { return TSGameBridge.shareToWechat(data); } else if (Platform.isIOS()) { return TSGameBridge.shareToSystem(data); } else if (Platform.isHarmonyOS()) { return TSGameBridge.shareToHuawei(data); } } }; ``` ### 开发环境搭建 #### 1. Android开发环境 ```bash # 安装Android Studio # 配置环境变量 export ANDROID_HOME=/path/to/android-sdk export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools # 创建项目 cd android ./gradlew build ``` #### 2. iOS开发环境 ```bash # 安装Xcode (仅限macOS) # 安装CocoaPods sudo gem install cocoapods # 创建项目 cd ios pod init pod install open TSGame.xcworkspace ``` #### 3. HarmonyOS开发环境 ```bash # 下载DevEco Studio # 安装HarmonyOS SDK # 创建项目 cd harmonyos hvigorw assembleHap ``` ### 代码复用策略 #### 1. 共享Web资源 ```javascript // shared/webview/js/game-core.js class GameCore { constructor() { this.platform = this.detectPlatform(); this.bridge = this.initBridge(); } detectPlatform() { if (/Android/i.test(navigator.userAgent)) return 'android'; if (/iPhone|iPad/i.test(navigator.userAgent)) return 'ios'; if (/HarmonyOS/i.test(navigator.userAgent)) return 'harmonyos'; return 'unknown'; } initBridge() { // 统一的桥接初始化逻辑 return new PlatformBridge(this.platform); } } ``` #### 2. 平台抽象层 ```java // Android抽象层 public abstract class PlatformService { public abstract void login(String type, Callback callback); public abstract void share(ShareData data, Callback callback); public abstract DeviceInfo getDeviceInfo(); } public class AndroidPlatformService extends PlatformService { @Override public void login(String type, Callback callback) { // Android特定的登录实现 } } ``` ```objc // iOS抽象层 @protocol TSPlatformService - (void)loginWithType:(NSString *)type callback:(void(^)(NSDictionary *result))callback; - (void)shareData:(NSDictionary *)data callback:(void(^)(BOOL success))callback; - (NSDictionary *)getDeviceInfo; @end @interface TSIOSPlatformService : NSObject @end ``` ```typescript // HarmonyOS抽象层 abstract class PlatformService { abstract login(type: string): Promise; abstract share(data: ShareData): Promise; abstract getDeviceInfo(): DeviceInfo; } class HarmonyOSPlatformService extends PlatformService { async login(type: string): Promise { // HarmonyOS特定的登录实现 } } ``` ### 测试策略 #### 1. 单元测试 ```javascript // 跨平台测试用例 describe('Bridge API Tests', () => { test('should get device info on all platforms', async () => { const deviceInfo = await TSGameBridge.getPhoneInfo(); expect(deviceInfo).toHaveProperty('model'); expect(deviceInfo).toHaveProperty('version'); expect(deviceInfo).toHaveProperty('platform'); }); test('should handle network status correctly', async () => { const network = await TSGameBridge.getNetworkStatus(); expect(['1', '2', '3']).toContain(network); }); }); ``` #### 2. 集成测试 ```yaml # test-plan.yml test_scenarios: - name: "登录流程测试" platforms: ["android", "ios", "harmonyos"] steps: - "打开应用" - "点击登录按钮" - "验证登录结果" - name: "分享功能测试" platforms: ["android", "ios", "harmonyos"] steps: - "进入游戏页面" - "点击分享按钮" - "选择分享平台" - "验证分享成功" ``` ### 性能优化建议 #### 1. WebView优化 ```javascript // 通用WebView优化配置 const webViewConfig = { android: { hardwareAccelerated: true, cacheMode: 'LOAD_CACHE_ELSE_NETWORK', domStorageEnabled: true }, ios: { allowsInlineMediaPlayback: true, mediaTypesRequiringUserActionForPlayback: 'none', scrollView: { bounces: false } }, harmonyos: { javaScriptAccess: true, domStorageAccess: true, imageAccess: true } }; ``` #### 2. 资源加载优化 ```javascript // 预加载关键资源 class ResourceManager { preloadAssets() { const criticalAssets = [ 'images/logo.png', 'audio/bgm.mp3', 'fonts/game-font.woff2' ]; return Promise.all( criticalAssets.map(asset => this.loadAsset(asset)) ); } loadAsset(url) { return new Promise((resolve, reject) => { const ext = url.split('.').pop(); if (['png', 'jpg', 'gif'].includes(ext)) { const img = new Image(); img.onload = resolve; img.onerror = reject; img.src = url; } else if (['mp3', 'wav'].includes(ext)) { const audio = new Audio(); audio.oncanplaythrough = resolve; audio.onerror = reject; audio.src = url; } }); } } ``` ### 维护建议 #### 1. 版本管理 ```json // version-config.json { "version": "3.6.3", "platforms": { "android": { "versionCode": 36300, "minSdkVersion": 21, "targetSdkVersion": 33 }, "ios": { "buildNumber": "36300", "minimumOSVersion": "11.0" }, "harmonyos": { "versionCode": 36300, "minAPIVersion": 8, "targetAPIVersion": 9 } } } ``` #### 2. 更新策略 - **强制更新**: 影响安全性和关键功能的更新 - **建议更新**: 新功能和体验优化 - **静默更新**: 资源文件和配置更新 - **灰度发布**: 分阶段推送给不同用户群体 #### 3. 兼容性处理 ```javascript // 版本兼容性检查 class CompatibilityChecker { checkPlatformSupport() { const requirements = { android: { minVersion: 21 }, ios: { minVersion: '11.0' }, harmonyos: { minAPIVersion: 8 } }; const current = this.getCurrentPlatformVersion(); const required = requirements[this.platform]; return this.compareVersions(current, required.minVersion) >= 0; } } ``` ## 项目总结与展望 ### 技术特色 1. **跨平台统一**: 基于WebView + JS Bridge的跨平台解决方案 2. **功能完备**: 涵盖认证、分享、定位、音视频等完整功能 3. **性能优化**: 针对不同平台特性进行深度优化 4. **易于维护**: 统一的API接口和代码架构 ### 适用场景 - **棋牌游戏**: 完整的棋牌游戏解决方案 - **社交游戏**: 支持实时音视频和社交分享 - **地方特色应用**: 可快速适配不同地区需求 - **跨平台应用**: 一套代码适配多个平台 ### 开发优势 - **开发效率**: H5游戏 + 原生能力,快速开发 - **维护成本**: 统一的业务逻辑,降低维护成本 - **用户体验**: 原生性能 + Web灵活性 - **迭代速度**: 支持热更新,快速迭代 ### 扩展方向 1. **平台支持**: 扩展到更多平台(Windows、Web) 2. **技术升级**: 升级到最新的SDK版本和技术栈 3. **功能增强**: 添加更多游戏类型和社交功能 4. **性能优化**: 进一步优化启动速度和运行性能 ### 常见问题解答 #### Q: 如何在现有项目基础上开发iOS版本? A: 1. 复制`shared/`目录下的所有Web资源 2. 创建iOS项目,实现相同的JS Bridge接口 3. 根据iOS平台特性调整权限配置和第三方SDK 4. 参考本文档的iOS开发指南进行适配 #### Q: HarmonyOS版本开发有什么注意事项? A: 1. 使用ArkTS语言开发,语法类似TypeScript 2. 权限管理更加严格,需要详细配置使用场景 3. 部分第三方SDK可能需要寻找替代方案 4. 遵循华为应用市场的审核规范 #### Q: 如何保证各平台功能一致性? A: 1. 使用统一的API接口定义 2. 建立跨平台测试用例 3. 定期进行功能对比测试 4. 维护详细的功能兼容性文档 #### Q: 性能优化的重点是什么? A: 1. WebView初始化和资源加载优化 2. JS Bridge通信效率优化 3. 内存管理和垃圾回收优化 4. 网络请求和数据缓存优化 ### 技术支持 - **文档更新**: 定期更新技术文档和API说明 - **问题反馈**: 通过Issue跟踪和解决技术问题 - **技术交流**: 建立开发者交流群组 - **版本发布**: 提供稳定的版本发布和更新通知 --- **文档版本**: v2.0 **更新时间**: 2025年7月5日 **适用版本**: TSGame 3.6.3+ **支持平台**: Android、iOS、HarmonyOS > 本文档为TSGame跨平台项目的完整技术说明,涵盖了项目架构、开发指南、API参考等所有必要信息。开发者可以基于本文档快速理解项目结构,并在任意支持的平台上实现相同功能的应用。