HABIT IS POWER

习惯就是力量

0%

问题描述

iOS下,游戏使用cocos2d-js 3.1和语音聊天,单独只有语音聊天或者只有游戏音效时,两者都正常,但是语音和音效同时使用时,就会有一方无法正常播放或者两者都无法正常播放。

问题排查

各种尝试后,发现了这篇文章:调用录音后,游戏音效播放不出来的问题,这篇给了我们一个新的解决思路:

会不会是iOS下AVAudioSession的category导致的问题?

在语音使用麦克风录音的前后,已经播放音效的前后,都将AVAudioSession的category属性Log打印出来,发现一旦我们使用了cocos2d-js提供的cc.audioEngine.playEffect方法,category就会变成kAudioSessionCategory_SoloAmbientSound,而像我们这种既有语音又有音效的情况,我们需要的其实是:AVAudioSessionCategoryPlayAndRecord。

好了,找到直接的原因了,但是怎么改呢?

阅读代码,寻找解决方案

带着上面的问题,看下cocos2d-x的代码,看看能不能找到解决方案。

  • 如果没有设置或CDaudioManager的configured,会使用默认的mode:kAMM_FxPlusMusicIfNoOtherAudio
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# ./frameworks/js-bindings/cocos2d-x/cocos/audio/ios/CDAudioManager.m

// Init
+ (CDAudioManager *) sharedManager
{
@synchronized(self) {
if (!sharedManager) {
if (!configured) {
//Set defaults here
configuredMode = kAMM_FxPlusMusicIfNoOtherAudio;
}
sharedManager = [[CDAudioManager alloc] init:configuredMode];
_sharedManagerState = kAMStateInitialised;//This is only really relevant when using asynchronous initialisation
[[NSNotificationCenter defaultCenter] postNotificationName:kCDN_AudioManagerInitialised object:nil];
}

}
return sharedManager;
}
  • 而默认的这个mode对应的正是AVAudioSessionCategorySoloAmbient
1
-(void) setMode:(tAudioManagerMode) mode {
  • 解决方案出来了
1
2
# 调用下CDAudioManager的这个方法,初始化下我们的mode
+ (void) configure: (tAudioManagerMode) mode;

最终的解决方案

  1. 确认工程配置的Header目录包含CDAudioManager.h所在的目录

  2. 在播放音效之前初始下CDAudioManager的mode为kAMM_PlayAndRecord

[CDAudioManager configure:kAMM_PlayAndRecord];

问题

如果你遇到过XCode下的开发者证书怎么都无法正确获取,无法真机调试,各种抓狂,那么你应该也非常需要下面的吐槽和解决方案。

解决方案:一切重头再来

重头再来不是说,安装教程从头到尾再操作一次,因为你会抓狂,基本上你应该已经按照教程操作的多次,所以这里说的重头再来,我想告诉大家的是:

如何清除本地的证书信息

  1. 打开”钥匙串”,切换到证书,删除所有Apple Developer相关的证书
  2. 打开XCode,Performance,Account,删除之前的登录信息,重新登录开发者账号
  3. 删除本地的证书,服务器上配置的iOS Provisioning Profiles (Development)其实也是可以删除的,不删除也没问题,因为使用XCode重新申请证书的话,会自动把老的配置置为无效
    证书

做了上面的事情,你就可以安装各种教程,重新申请下证书了,这时你应该已经可以成功了。

参考:Maintaining Your Signing Identities and Certificates
Valid signing identity not found(有关真机调试)

这里有一点需要特别说的是:

No signing identity found 不影响真机调试

如果你已经重新来过了,而且Build Setting-》Code Signing-》Provisioning Profiles已经有了正确的配置文件了,那么这个时候你看到

1
No signing identity found 

这个提示是可以忽略的,已经可以真机调试了。

Certificates, Identifiers & Profiles

Provisioning Profiles 到底是干什么的?

简单说,这个配置文件做的事情就是校验调试流程的三个主体的合法性:苹果开发者,XCode使用者,iPhone使用者。

所以在developer.apple.com后台生成Provisioning Profiles的时候,你需要分别选择:

  1. 开发者的证书(手动生成的时候是需要本地调用钥匙串来生成秘钥的)

  2. App ID,应用的名称,可以使用通配符

  3. Deviece ID,设备ID

我为什么会遇到这个问题

公司的开发者账号很容易满员,所以我加入了三个开发者账号……

需求

cocos2d-js-3.1中的spidermonkey是直接以头文件+.a文件的方式整合的,但是有些代码会crash在spidermonkey的代码中,所以我需要调试spidermonkey的C++代码。

解决

寻找cocos2d-js-3.1使用的spidermonkey版本

尝试1,v23版本

版本 v23,看当前使用的版本,一开始的想法是查看本地cocos2d-x目录下的CHANGELOG,我看到的最新的是:

1
2
cocos2d-x-3.0alpha0 @Sep.19 2013
Upgraded SpiderMonkey to Firefox v23

而spidermonker目录下的README告诉我们需要去这个github仓库取代码

1
2
.\frameworks\js-bindings\external\spidermonkey\README.md
https://github.com/ricardoquesada/Spidermonkey

找了下v23的log,发下没有release,所以只能从特定的commit下载zip包下来

https://github.com/ricardoquesada/Spidermonkey/tree/c8f78c30b633025f48fc0075e5f9a706639c7ac4

结论:编译后发现版本不对,头文件不对

尝试2,v28版本

本地的CHANGELOG不对,那么就看下在线版本的;

我们的cocos2d-js版本是3.1对应到在线的CHANGELOG,其中的Spidermonkey版本是v28

https://github.com/cocos2d/cocos2d-js/blob/develop/CHANGELOG

同样的还是没有release版本,所以还是到对应的commit页面下载

https://github.com/ricardoquesada/Spidermonkey/tree/90747bc0ccb8e9fa1d56ef7e9c1b8b7b1bee4c96

1
2
3
4
5
6
7
8
9
10
Cocos2d-JS-v3.0 beta @ May.23, 2014
[JSB]Upgraded SpiderMonkey to v28.

Cocos2d-JS-v3.0 alpha2 @ April.14, 2014
[JSB]Update precompiled SpiderMonkey to support iOS 64 bit devices.


ricardoquesada authored on 25 Apr 2014
Merge pull request #28 from pandamicro/v28 …
[v28] Upgrade to Spidermonkey v28
编译

进入js/src/build-android,执行./build.sh -r
对比生成的apidermonkey-android中的include文件和cocos2d-js目录下的文件,一致,看来应该是这个版本了

结论

cocos2d-js-3.1 使用的spidermonkey版本是v28,可以从这里下载到:
https://github.com/ricardoquesada/Spidermonkey/tree/90747bc0ccb8e9fa1d56ef7e9c1b8b7b1bee4c96

进入js/src/build-android目录下执行./build.sh -r后将生成的三个目录覆盖到工程目录就可以调试了。

问题描述

双击SDK Manager.exe,闪退;

网上找了下资料,SDK Manager.exe启动其实调用的是android.bat这个批处理,而闪退的直接原因就是find_java.bat执行没有获取到正确的java.exe路径

问题根源

问题的根源在于android.bat中的这一段脚本执行出错了,没有获取到正确的java.exe路径

1
2
3
4
rem Check we have a valid Java.exe in the path.
set java_exe=
call lib\find_java.bat
if not defined java_exe goto :EOF

其实问题最终的根源在于find_java.bat中调用的find_java.exe没有返回正确的路径

解决方案

简单粗暴的解决方案

  • 简单的改法就是修改Android.bat中的java_exe路径,直接写死;

  • 当然这是个非常粗暴的解决方案,方案的风险在于:下次你复制这个目录到别的电脑上使用的时候,这里设置的路径需要重新设置。

1
set java_exe=C:\Program Files\Java\jdk1.7.0_40\bin\java.exe

正确的解决方案

其实这个更简单,在系统环境变量中,添加一个JAVA_HOME的变量定义

1
2
JAVA_HOME
C:\Program Files\Java\jdk1.7.0_40

验证的方法

直接调用下find_java.exe看看能否返回正确的路径。

参考

64位win7下Android SDK Manager闪退的解决方法

解决64位Win7下的android sdk manager一闪而过的问题

安装Android SDK时,点击SDK Manager.exe闪退

需求

cocos2d-js-v3.1生成的工程,添加了C++的代码,想要调试C++部分的代码,所以需要在cocos console或者cocos code IDE生成的工程上配置NDK调试,以便我们可以Debug As->Android Native Application。

解决过程

环境配置

Windows跟Mac下都统一使用ADT,除了路径格式有点区别,其他的配置都是一样的。

1
2
3
4
5
6
Android Developer Tools
Build: v22.3.0-887826

NDK
D:\android-ndk-r9d

为了说明这个问题,我用cocos code IDE创建了一个工程NativeDemo,下面中的.\NativeDemo就是这个工程的根目录

Add Native Support

默认生成的工程是找不到Add Native Support的

用ADT打开工程后,没有办法使用Native来调试,这样就没办法调试NDK了,排查了下:

1.右键工程Android Tools中没有Add Native Support菜单

2.到工程属性中查看,有C/C++ Build这个Tab页,但是点开却提示这不是一个CDT工程

3.对比之前的CDT工程,发现了下面的区别,而根目录下并没有.cproject文件存在:

cproject

使用cocos console和cocos studio创建的工程有什么不同

首先,这两种方式创建的工程,都有上面的这个问题,也就是缺失了.cproject这个文件;

除此之外cocos console创建的工程是个empty project,而cocos studio创建工程的时候会有一个简单的向导,帮你生成第一个页面。

出现这个问题的原因:

工程创建的时候生成的.project已经添加了”Add Native Support”支持,但是同时生成的.cproject文件却没有入库,从而导致了上面的问题

解决方案:

打开.\NativeDemo\frameworks\runtime-src\proj.android.project,查找并删除cdt相关的两部分配置:
1.BuildCommand

2.natures

删除成功的标准就是右键工程-》Android Tools的菜单下可以看到Add Native Support;

另外删除成功后工程属性下也看不到C/C++ Build的Tab页;

而工程属性的Builder下会看不到 Scanner Configuration Builder。

修改好了之后,右键工程,Android Tools,Add Native Support

参考

How to build and run HelloWorld on Android NDK r5 and above

无需cygwin,使用NDK进行开发

配置NDK build

添加一个C++变量

1
2
COCOS2DX_HOME
../../js-bindings/cocos2d-x

build var

配置NDK build的命令行

1
2
3
4
5
6
#Windows
ndk-build NDK_DEBUG=1 -C "${ProjDirPath}" "NDK_MODULE_PATH=${COCOS2DX_HOME}/..;${COCOS2DX_HOME};${COCOS2DX_HOME}/external;${COCOS2DX_HOME}/cocos;../Classes"

#Mac
ndk-build NDK_DEBUG=1 -C "${ProjDirPath}" "NDK_MODULE_PATH=${COCOS2DX_HOME}/..:${COCOS2DX_HOME}:${COCOS2DX_HOME}/external:${COCOS2DX_HOME}/cocos:../Classes"

ndk build

  • NDK_DEBUG=1这个参数记得加上

R_ARM_THM_CALL

C++编译过程中出现

1
Failed Android build: “error: relocation overflow in R_ARM_THM_CALL”

解决方案:

/runtime-scr/proj.android/jni/Android.mk 中添加一行:

LOCAL_ARM_MODE := arm

参考:http://blog.csdn.net/mingzznet/article/details/41120551

SDK版本号导致的Unknown Application ABI

1
2
Unknown Application ABI: 
Android NDK: WARNING: APP_PLATFORM android-19 is larger than android:minSdkVersion 9 in ./AndroidManifest.xml

解决方案:

手机上的版本需要和安装了的SDK已经配置的SDK版本一致,以我的小米2S为例,我的系统版本是4.1,也就是对应SDK 的API Level 16;

下面这两个文件需要对应的都修改成16:

AndroidManifest.xml
1
<uses-sdk android:minSdkVersion="16"/>
project.properties
1
target=android-16

NDK_MODULE_PATH

切换到Mac下,使用SDK 16来编译,提示NDK Module找不到,想起来之前做过类似的事情,NDK build命令行设置的NDK_MODULE_PATH适用于编译,但是调试的时候还是会提示找不到路径,解决方案是在Android.mk中加上调试用的配置,不调试的时候关掉:

1
2
3
4
5
6
# 调试NDK用的定义,平常不要打开 linyhui
$(call import-add-path, ../../js-bindings)
$(call import-add-path, ../../js-bindings/cocos2d-x)
$(call import-add-path, ../../js-bindings/cocos2d-x/external)
$(call import-add-path, ../../js-bindings/cocos2d-x/cocos)
$(call import-add-path, ../Classes)

import-module的注意事项与NDK_MODULE_PATH的配置

1
如果NDK_MODULE_PATH 没有设置或者设置不正确。编译时都是报错 Are you sure your NDK_MODULE_PATH variable is properly defined。

bindings目录下的Android.mk有语法错误

排查了半天发现是这个文件有语法错误,导致无法调试,但不知道为什么编译是没有问题的,这个算是cocos2d的一个Bug:

1
2
3
4
5
./NativeDemo/frameworks/js-bindings/bindings/Android.mk

#### 注释掉这个文件末尾中的这一行:

#$(call import-module,.)

注释后,Build下C++,就可以Debug As->Android Native Application

搞定了

可以Debug As->Android Native Application

初衷

儿子第一次发烧,作为新手爸爸的我非常紧张,特别是第一天晚上每隔不到半个小时就起来量下体温,但还是担心不小心睡着了,我非常迫切的需要有这么一款智能温度计:

方便、准确的测量孩子的体温,能定时上报体温,发现温度异常并发出警报。

豆芽智能体温计

豆芽智能体温计

Day1

凌晨发烧,当天我就在JD上买了豆芽智能体温计,因为很久之前听说过这款产品,所以想尝试下看能否解决我的问题。

Day2

儿子发烧的第二天,我收到了体温计,第一次测试,发现测量出来的体温最高才35.6°,而实际我儿子的体温应该是在38°左右。

怀疑可能是我使用的不对,于是加了微信公众账号和QQ群,询问了体温测量不准的问题,得到其他用户给的答案是:“要夹紧”!!

在总共16个人的用户群里,后续得到的官方答复也是我使用的方式不对,需要再调整下帖的位置,并要贴紧一点。

同时APP也有一堆的体验Bug,我记得住有:

1.蓝牙连接后会自动添加成员,导致和之前的成员重复(同名的圆圈出现多个,温度记录里也会出现多个)

2.远程实时监控没成功过

Day3

儿子低烧过去了,虽然我后面还尝试了下,但智能温度计测量到的最高温度也只是36.4度(耳温计37.6左右,没用水银温度计验证),我姑且理解应该是我没有贴的很好,如果我夹紧的话,应该会更准一点。

可惜我已经没有动力去夹紧这款产品了。

评测结论:不可用

1. 最根本的问题是体温测量误差太大

小孩对温度计本来就比较抗拒,所以才会出现耳温枪这类产品,快速测量体温,虽然也有误差,但没那么大,我们家的耳温枪和水银体温计对比,偏差在0.4°左右。

如果一定要像水银体温计那样夹紧几分钟,才能测量准确的话,那个号称的“智能”我只能说:呵呵。

从这个角度,我认为这款产品的现状是:

水银体温计(使用体验上来说)+蓝牙同步+APP提醒

期待:至少也应该达到耳温枪的测试精度,而且使用起来应该想手环那样自然,而不是“夹紧”……

2. 其他的体验问题,包括无法远程查看,相比第一点,反而没有那么紧急了

你想,如果小孩高烧不退,你肯定就在身边了,也不需要远程查看。

期待:这一点都是小问题,持续改Bug优化体验就好了

感想

产品的初衷是好的,也确实是刚需,但是解决的不是很好。

产品有硬伤的情况下,不是投入人力去解决硬伤,却做了更远的事情:健康大数据,云同步等,主次不分。

要是把做APP的精力花在优化体温测量上,哪怕做一个定时测量体温,温度报警发出的是嘀嘀嘀的电子手表闹钟声,都比现在的产品体验要好得多。

嘴上说的轻巧,实践过程都是艰辛的,希望豆芽能越来越好。

三句话

1
2
3
4
5
1. GoDaddy.com 千万不要用,还有域名在上面的赶紧逃离吧。

2. 偷域名的要么孤独终老,要么生孩子没屁眼。

3. 这个博客主要是写给自己看的,什么域名其实不重要,换个新域名继续写,希望2015可以继续坚持下来。

Have Fun :)

需求

cocos2dx 3.0之后的版本从对于标准库的使用从原来的GNU版libstdc++改成了LLVM的libc++,导致了我们需要用到的一部分第三方库.a文件无法使用了。

解决方案

因为这两个库的API接口是一致的,所以理论上不存在语法使用上的差异,你只需要修改下编译选项,重编下对应的第三方库即可。

举例说明

开源库

boost,QT等都提供了指引

第三方SDK

国内像友盟提供的SDK已经分别对应两个标准库提供了.a文件用于适配

自己的库

修改下编译选项,重编下

两者的区别

简单描述

Using libstdc++ compiled libraries with clang++ -stdlib=libc++

1
2
3
4
Although they are API compatible, they are not ABI compatible. 
That means that if you construct a std::string with libstdc++,
and then pass it to other code that is linked against libc++,
the receiving code would think it has a libc++ std::string.

详细描述

Defining a Portable C++ ABI - Open Standards

为什么要有两个库?

GPLv3

GCC 4.2.1之后的版本License改成了GPLv3,这个许可协议和Apple在AppStore里使用的DRM技术不相容,也就是说Apple以及第三方开发者不能使用GCC4.2.1之后的版本生成AppStore应用,libstdc++其实一直是GCC工具集的一部分,所以只好停留在GCC 4.2.1自带的那个版本。

GCC对Objective-C新特性的支持很有限

GCC4.2.1及对应的libstdc++太老旧,不支持新的C和C++标准,也不支持Apple加入到Objective-C里的新特性比如Block、ARC等。

知乎:Apple 为什么在 Mavericks 里把 C++ 标准库从 libstdc++ 改成 libc++?

一件小事

由于我自己的疏忽,我的GoDaddy账号被盗了,上面的6个域名(包括linyehui.com)被小偷转移,目前还在申诉中。

虽然事情还没结束,但处理的过程让我对GoDaddy非常失望,以后绝不会在他们家注册任何服务:GoDaddy对你的财产安全根本不在乎。

1
2
3
4
5
6
7
8
1.如果小偷拥有了你的密码,小偷做了任何事情GoDaddy都不认账;

2.稍微有点安全意识的网站,改个密码都要短信或者邮件验证下,
而GoDaddy转移货真价实的财产(域名)竟然连个验证邮件都没有;

3.域名被转移后,GoDaddy只会事后发一封知会邮件,而且虽然邮件上面说15天之内可以undo,
但是所谓的undo只是一句空话,还是要走非常无力的申诉流程。

后续

万一域名要不回来,这也不是什么大事情,关注博客的同学还可以继续从linyehui.github.com访问。

要加强防范,做好密码分级,并且定期修改密码。

这一切没有想象的那么糟,不是吗 :)

遇到的问题

下载GarageBand内容,下载GarageBand音效库,很慢!很慢!很慢!

我这提示需要125个小时!

而且还总是下载失败!

Alt text

解决方案

1.打开GarageBand开始下载

2.使用lsof命令查看GarageBand把文件下载到那里去了

  • 内容太多,所以先用ps命令找到GB的进程ID,我这里是291

  • 然后再使用lsof,并把输出重定向到log.txt中去

1
2
3
4
ps aux | grep GarageBand  

lsof -g 291 > ~/log.txt

  • 打开log.txt,搜索.pkg,你会找到类似下面的路径,对了,这个就是下载的临时文件
    1
    /private/var/folders/37/1bzl8_j50wxcxgmj0dv805lm0000gn/C/com.apple.garageband10/com.apple.MusicApps/audiocontentdownload.apple.com/lp10_ms3_content_2013/MAContent10_GarageBandPremiumContent.pkg

3.退出GarageBand,得到下载地址,使用第三方工具下载好pkg文件

  • 退出GarageBand,取消下载,GarageBand会在下载的临时文件旁边生成这么一个文件,文件中有实际的下载地址

** MAContent10_GarageBandCoreContent_v3.pkg.resumeData **

1
2
3
4
http://audiocontentdownload.apple.com/lp10_ms3_content_2013/MAContent10_GarageBandPremiumContent.pkg
http://audiocontentdownload.apple.com/lp10_ms3_content_2013/MAContent10_GarageBandCoreContent_v3.pkg
http://audiocontentdownload.apple.com/lp10_ms3_content_2013/MAContent10_GB_StereoDrumKitsSongWriter.pkg

  • 使用第三方下载工具,下载这个ULR对应的文件

4.下载后了之后,有两种方式进行安装

4.1 方案一:替换文件

把下载到的文件替换到第2步得到的路径上,修改.resumeData中的文件大小,然后重启GarageBand。

4.2 方案二:删除临时文件,双击pkg安装

删除步骤2得到的目录下的文件,然后双击下载好的pkg,安装后,打开GarageBand。

5.遗留问题

安装后还是会提示需要下载,而且看临时文件还是在下载MAContent10_GarageBandPremiumContent.pkg,太奇怪了

参考

2013新版GarageBand下载基本音乐、声效库缓慢的解决办法

天朝重装GarageBand下载几十个小时基础包的盆友们进来看

[原创]Logic Pro X全部扩展包下载地址 34.3GB

logic-x-mainstage-3-content

GarageBand全部素材包下载地址

GarageBand及随附增值包快速安装方法

遇到的问题

系统升级到OS X 10.10.1 + CocoaPods 0.34后遇到了下面的问题,之前是一切正常的:

[!] The use of implicit sources has been deprecated. To continue using all of the sources currently on your machine, add the following to the top of your Podfile:

source ‘https://github.com/CocoaPods/Specs.git

[!] CocoaPods was not able to update the master repo. If this is an unexpected issue and persists you can inspect it running >pod repo update --verbose

解决思路

尝试1:重装CocoaPods,问题依旧

1
2
3
4
5
6
gem list --local | grep cocoapods

# 好几个,全部uninstall
gem uninstall cocoapods

gem install cocoapods

尝试2:清除CocoaPods缓存后重新pod setup,解决问题

1
2
sudo rm -fr ~/.cocoapods/repos/master
pod setup

原因分析

解决问题后再次搜索总是能得到正确答案:

I’m getting permission errors while running pod commands

简单来说就是0.32之后的CocoaPods repo目录访问现在不需要root权限了,之前版本生成的目录权限在新版本下会有权限问题,所以需要删除重新生成一次。