[cocos2d-x·解Bug]关于cocos2d-x游戏在android锁屏状态下播放Bgm的解决方法
最近《宠物联萌》在三星App上发布遇到一个问题:如果用户在锁定屏幕时解锁解到一半时取消解锁,这时用cocos2d-x开发的游戏就会出现游戏Bgm会恢复播放,但手机屏幕仍然是锁屏状态的Bug。
简述情况:
·游戏运行平台:Android
·Cocos2d-x引擎版本:cocos2d-1.0.1-x-0.13.0-beta
·问题出现操作:Android手机在锁屏状态下,玩家解锁解到一半时取消解锁(用圆环锁比较容易重现)
·是否经过测试:已测试,暂无发现问题
遇到Bug后初步分析了原因,估计是因为玩家解锁到一半时,触发了Android系统恢复游戏进程的操作,触发AppDelegate的applicationWillEnterForeground(),这个函数一般包括SimpleAudioEngine的resumeBackgroundMusic(),即游戏进程重新进入时,恢复游戏音乐。
简单来说,就是玩家解锁到一半时,游戏已经恢复到屏幕上了,但此时被手机的锁屏界面覆盖住,导致这个Bug的发生:锁屏界面下能听到游戏Bgm。
要验证这个问题很简单,当游戏进入后台时,Android系统会把纹理资源全部释放掉,之所以玩家重新进入游戏时会出现黑屏几秒的现象,是因为游戏此刻在重新加载资源,写得好的游戏控制好纹理数量其实还是可以做到“秒进”屏幕的,不过《宠物联萌》代码写得比较挫,会黑屏几秒。在这个Bug的情况下,我们在锁屏界面听到音乐后直接解锁,可以看到游戏已经显示在屏幕,并没有出现黑屏加载资源,是因为游戏已经把纹理数据都加载好显示到屏幕上了,只是被锁屏界面覆盖住了。
因为游戏其实已经恢复到屏幕上,所以想在OnEnter里面恢复游戏Bgm是不可行的,CTO给了一个解决方案:AppDelegate不作恢复音乐操作,而是由用户自己第一次点击屏幕时恢复音乐。不过这个解决方案治标不治本,而且每个CCLayer都要做这样的处理,改动太多容易产生别的Bug,而且如果玩家一直不点击屏幕,那么游戏会一直“静音”,所以觉得这个方案不太好。于是我没有用这个解决方案。
知道问题来源,简单做了个设想:假设在锁屏状态下,游戏Activity虽然恢复界面了,因为有锁屏界面,所以Activity没有被系统Focus;而当手机解锁时,锁屏界面被系统移除,然后系统会Focus Activity,如果Activity有Focus的响应函数,那么我们在失去Focus时暂停音乐,而在触发Focus时恢复游戏Bgm,不就可以了~。
带着这个假设翻了一下Android的Activity类,看看有没有这样的响应方法,幸运地发现了:public void onWindowFocusChanged(boolean hasFocus) {}。到这一步其实已经成功了,只要我们在游戏的Activity上重写该方法即可,比如:
public class TestsDemo extends Cocos2dxActivity{ @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); MMJNIUtilities.handleOnWindowFocusChanged(hasFocus); } } public class MMJNIUtilities { public static native void handleOnWindowFocusChanged(boolean hasFocus); }
note:很久没写Java,上面代码有错误请见谅。
最后通过javah生成这个MMJNIUtilities的头文件,并实现handleFocus方法即可,比如:
JNIEXPORT void JNICALL Java_org_cocos2dx_tests_MMJNIUtilities_handleOnWindowFocusChanged( JNIEnv * env, jclass jClass , jboolean hasFocus ) { if (hasFocus) { SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic(); SimpleAudioEngine::sharedEngine()->resumeAllEffects(); } else { SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic(); SimpleAudioEngine::sharedEngine()->pauseAllEffects(); } }
漏了一点,因为现在是通过Activity的Focus来控制音乐开关,所以AppDelegate也要做相应修改:
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too void AppDelegate::applicationDidEnterBackground() { CCDirector::sharedDirector()->pause(); // SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic(); // SimpleAudioEngine::sharedEngine()->pauseAllEffects(); } // this function will be called when the app is active again void AppDelegate::applicationWillEnterForeground() { CCDirector::sharedDirector()->resume(); // SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic(); // SimpleAudioEngine::sharedEngine()->resumeAllEffects(); }
随后编个Apk在手机上测了一下,锁屏状态下没有声音了,搞定。这个解决方案感觉比较治本,而且对游戏的改动不多,不必修改整个游戏的CCLayer。不过这个方法暂时没经过测试,不保证没有任何风险,对cocos2d-x的tests做了点修改作为例子,有兴趣可以下来看看。
http://files.cnblogs.com/j1223jesus/%E4%BF%AE%E6%94%B9%E8%BF%87%E7%9A%84tests_0.13.0-beta.zip
[cocos2d-x·解Bug]关于cocos2d-x游戏在android锁屏状态下播放Bgm的解决方法的更多相关文章
- Centos7解压.tar.bz2提示tar (child): bzip2: Cannot exec: No such file or directory解决方法
Centos7解压.tar.bz2提示tar (child): bzip2: Cannot exec: No such file or directory解决方法 原因是因为该centos没有bzip ...
- [Bug]转:使用jquery的 uploadify,在谷歌浏览器上总会崩溃的解决方法
最近做的项目使用了jquery的uploadify,但是在谷歌浏览器测试总是会出现崩溃.如: 因为是java项目. 解决的办法是: 给引入的js加上一个参数,时间戳就可以,防止缓存,使每一次都请求.( ...
- Mac系统下的zip压缩包解压到Windows下出现乱码的解决方法
环境变量 环境变量是具有特殊名字的一个特定对象,包含了一个或多个应用程序运行所需的信息.(例如PATH,可执行程序的搜索路径,当要求系统运行一个程序,而没告诉系统它的具体路径时,系统就要在PTAH值的 ...
- ie6,ie7,ie8 css bug兼容解决方法
IE浏览器以不支持大量的css 属性出名,同时也因其支持的css属性中存在大量bug. 这里收集了好多的bug以及其解决的办法,都在这个文章里面记录下来了!希望以后解决类似问题的时候能够快速解决,也希 ...
- 解Bug之路-TCP粘包Bug
解Bug之路-TCP粘包Bug - 无毁的湖光-Al的个人空间 - 开源中国 https://my.oschina.net/alchemystar/blog/880659 解Bug之路-TCP粘包Bu ...
- 老程序员解Bug的通用套路
千万不要当程序员面说有bug 对于新手程序员而言,在复杂代码中找BUG是一个难点.下面我们总结下老从程序员解Bug的通用套路,希望对大家有帮助. 1.IDE调试 根据项目特点和语言特点选择一个最合适的 ...
- 解Bug之路-记一次中间件导致的慢SQL排查过程
解Bug之路-记一次中间件导致的慢SQL排查过程 前言 最近发现线上出现一个奇葩的问题,这问题让笔者定位了好长时间,期间排查问题的过程还是挺有意思的,正好博客也好久不更新了,就以此为素材写出了本篇文章 ...
- 解Bug之路-记一次存储故障的排查过程
解Bug之路-记一次存储故障的排查过程 高可用真是一丝细节都不得马虎.平时跑的好好的系统,在相应硬件出现故障时就会引发出潜在的Bug.偏偏这些故障在应用层的表现稀奇古怪,很难让人联想到是硬件出了问题, ...
- 解Bug之路-记一次JVM堆外内存泄露Bug的查找
解Bug之路-记一次JVM堆外内存泄露Bug的查找 前言 JVM的堆外内存泄露的定位一直是个比较棘手的问题.此次的Bug查找从堆内内存的泄露反推出堆外内存,同时对物理内存的使用做了定量的分析,从而实锤 ...
随机推荐
- BZOJ 4341 [CF253 Printer] 解题报告
乍一看这个题好像可以二分优先度搞搞... 实际上能不能这么搞呢...? 我反正不会... 于是开始讲我的乱搞算法: 首先肯定要把任务按照优先度排序. 用一棵在线建点的线段树维护一个时刻是否在工作. 然 ...
- cf 363D
贪心加二分 虽然比赛后才过 ........ /************************************************************************* &g ...
- 安卓 unit 测试与 instrument 测试的代码共享
假如你有一款安卓应用,其包含一系列测试类,其中一部分是unit 测试(位于 src/test),其余为instrument 测试(位于 src/androidTest). 那么问题来了:你有一些想在所 ...
- jQuery从主页面存取控制 iframe 中的元素,参数及方法
从主页面上获取iframe下的某个对象,或使用iframe下的方法,或是获取iframe下某个doc元素,要求兼容各类浏览器,不仅仅ie; $(function() { $('#abgne_ifram ...
- Linqer工具
这些天写Linq挺烦人的,就上网搜搜可有什么好的sql转Linq的工具,咦,马上就看上了Linqer. 哈哈,介绍一下使用方法吧: 官方下载网站:http://sqltolinq.com/downlo ...
- python自省指南
深入python中对自省的定义: python的众多强大功能之一,自省,正如你所知道的,python中万物皆对象,自省是指代码可以查看内存中以对象形式存在的其他模块和函数,获取它们的信息,并对它们进行 ...
- [iOS]修改开发者中心Bundle Identifier的一些配置
登录开发者中心https://developer.apple.com 然后找到你的Bundle Identifier. 这里暂时只讲开启推送的功能,如果需要别的直接勾选前面的选择框 然后拉到最下面点击 ...
- Failed to allocate memory: 8
Failed to allocate memory: 8This application has requested the Runtime to terminate it in an unusual ...
- ios 使用GCD 多线程 教程
什么是GCD Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法.该方法在Mac OS X 10.6雪豹中首次推出,并随后被引入到了iOS4.0中.GCD ...
- Hibernate的一个注释 @Transient
@Transient表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性. 如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则,ORM框架默认其注解为@Basi ...