[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】【3404】【USACO2009 Open】Cow Digit Game又见数字游戏
博弈论 Orz ZYF 从前往后递推……反正最大才10^6,完全可以暴力预处理每个数的状态是必胜还是必败(反正才两个后继状态),然后O(1)查询……我是SB /******************** ...
- iframe嵌入其他网站,如何自适应高度
终于有一周时间,工作不那么忙了,腾出手来总结下工作过程中学到的知识. 每天遇到新问题,解决新问题,但是却很少有时间去仔细研究下,或者总结下.攒的多了,就得从头捋一遍. 说下iframe自适应高度: 搜 ...
- Web应用中的轻量级消息队列
Web应用中为什么会需要消息队列?主要原因是由于在高并发环境下,由于来不及同步处理,请求往往会发生堵塞,比如说,大量的insert,update之类的请求同时到达mysql,直接导致无数的行锁表锁,甚 ...
- 漫谈CGI FastCGI WSGI
作者:auxten链接:https://zhuanlan.zhihu.com/p/20054757来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. CGI(Common ...
- linux上部署应用
1.编写traffic.sh 引入相关的jar包及java环境路径 2.crontab -e 加入: */10 * * * * cd /opt/sys/traffic_version/bin & ...
- C# 常用的工具类
编码解码.图片与byte[].日志文件写入和读取 /// <summary> /// 将字符串编码为Base64字符串 /// </summary> /// <param ...
- codeforces 295E Yaroslav and Points (离线操作+离散化+区间合并)
参考链接:http://blog.csdn.net/dyx404514/article/details/8817717 写的很详细,这里就不再赘述,附上我的代码. #include <iostr ...
- POJ 1781
#include <iostream> #include <string> #include <cmath> using namespace std; unsign ...
- URAL 1244. Gentlemen (DP)
题目链接 题意 : 给出一幅不完全的纸牌.算出哪些牌丢失了. 思路 : 算是背包一个吧.if f[j]>0 f[j+a[i]] += f[j];然后在记录一下路径. #include < ...
- hdu 2837 Calculation
公式:a^b%p=a^(b%phi(p)+phi(p))%p b>=phi(p) #include<iostream> #include<stdio.h> #incl ...