所谓坑, 就是文档中没有标明的特别需要处理的细节, 工作中会被无故的卡住各种令人恼火的问题. 包括系统级的bug和没有文档化的限制.

继Android的各种坑后, 现在做Amazon平台, 遇到的坑很多, 这里记录一下备忘:

先汇总下Android Native下的各种问题, 当然有些限制有明确文档说明,不算坑,但是限制太多还是很不爽:

android平台下的某些限制: android下的各种坑 (我的C/C++/汇编/计算机原理博客)

OBB的各种bug: OBB的解决方案

arm gcc toolchain 的链接错误和编译器崩溃: NDK: GCC 4.6 crashes [原]android 链接错误

Modified UTF8 崩溃: crash - JNI WARNING: input is not valid modified utf-8: illegal continuation byte

BACK键无消息:[工作记录] NDK: AKEYCODE_DEL not notified

以上这些还不包括其他API, 如GLES, OpenSL ES的坑.

比如GLES2.0用复杂shader编译通过但是runtime崩溃或者渲染不正确, 比如下面代码, GLES2.0某些硬件shader条件分支代码渲染不正确或者黑屏,

//GLES2.0 fragment shader

float	factor	 = ( dir >= 0 ) ? 1 : 0;   //doesn't work! artifacts!
float factor = step(0, dir); //f*******k! it works! the hell why?

还比如GLES2.0竟然没有统一的压缩贴图格式, 而且ETC1竟然不支持Alpha等等, 总的来说GLES2.0不适合做大一点儿的3D游戏.

而OpenSLES上也是各种限制, 比如声音数量的限制, 音频解码接口的限制(导致可用声音数量减半)等等, 这些比iOS差远了.

再来说说最近Amazon平台遇到的坑:

1. GameCircle无法登录, 一直为GUEST.

文档里相关的 FAQ 如下

Q: Which countries does Amazon GameCircle support?A: Amazon GameCircle is available in more than 200 countries, including the United States, the United Kingdom (England, Scotland, Wales, and Northern Ireland), Germany, France, Spain, Italy, Japan, and Brazil. In China and other non-supported countries, your customers can earn achievements and track their high scores without logging in; the data is stored locally and not synced to the cloud.

那么在天朝做global app development, 也没法调试了么, 有什么解决办法没? 虽然手里的Kindle Fire设备有全局VPN设定,但是还没有VPN可用啊... 最后在支持论坛(https://forums.developer.amazon.com/forums/thread.jspa?threadID=2946)看到这句话:

GameCircle is not supported for the users using Chinese Amazon account. The users with a non-China account may attempt to use GameCircle from China, however they will be connecting to the US and may be subject to China firewall issues.

好吧,  怎么创建非中国账号? 我的账号是在amazon.com, 非amazon.cn上创建的, 应该不是中国账号吧, 为什么还是不行?... 最后拿着设备折腾了一番, 终于搞定了:

设置 => 我的账号 => 当前国家 : 设置为美国

这样就可以了...

2. GameCircle Jni崩溃.

logcat 输出一堆错误: ... NoClassDefFoundError: com/amazon/ags/api/AGResponseHandle(关键字) ...

一开始以为是library reference 或者 class loader的线程问题, 搜索了所有错误信息后, 最后使用上面关键字, 得到的一下解答(https://forums.developer.amazon.com/forums/thread.jspa?threadID=767):

From my own experimentation it seems that the handles just don't work for me.

They
make the calls to java and return a handle, but after this, the amazon
C++ code try to do something (what I don't know) that creates a
classdefnotfound exception which crashes the application. I switched to
using the callbacks.

查看自己代码发现有部分代码为了省事使用了Handle, 而没有使用callbak, 所以一部分函数调用会崩溃, 一部分不会.

全部改用callback 解决.

3. Amazon AppStore: 没有APK expansion

这个起码有文档说明. 但Google Play的APK和Amazon的限制不同, 导致非常恶心.

Amazon的APK没有大小限制, 100M以上需要用FTP传, 没有expansion file, 这样OBB什么的都是浮云了, 而且要为Amazon做新的包了. 综合之前Google Play的OBB问题,
最佳方案是使用ZIP格式, 因为APK是zip包, 那么使用ZIP可以同时支持OBB模式和APK模式,

使用同一套代码库的维护成本低, 加上复用度高导致稳定性高, 比两套代码要好很多.

目前工作中由于进度原因, 可能选择最快的,而且不降低运行效率的解决方案:

http://stackoverflow.com/questions/7937368/how-to-pass-arguments-to-aapt-when-building-android-apk

http://stackoverflow.com/questions/2651816/reading-resource-files-from-my-own-apk-in-android-native-environment

http://ponystyle.com/blog/2010/03/26/dealing-with-asset-compression-in-android-apps/

即把OBB文件放入APK, 同时禁止APK对OBB的zip压缩, 然后native直接读文件, 这样只需要初始化时通过Jni调用一次Java, 获取seeking offset和size,之后都可以在native读取. 准备着手做这一步.


更新:

上面方法经过测试可行, 除了遇到几个小问题.

问题1. OBB文件过大, 导致AAssetManager_open()打开失败, logcat输出 mmap失败, 不管使用哪种打开方式( AASSET_MODE_UNKNOWN, AASSET_MODE_BUFFER, AASSET_MODE_STREAMING) 都是同样错误, 也就是说系统固定使用mmap来把APK内文件映射到进程地址空间. 当然我只需要获取offset和size, 所以可以不要求mmap, 但是没有这个选项.
解决办法: 不使用obb嵌套, 直接把打包前的所有文件打包进apk.

问题2: AAsset_openFileDescriptor/AAsset_openFileDescriptor64 在一定次数执行成功后, 返回值-1

这是个坑啊:

根据注释/文档, 只有无法直接访问的文件才会返回失败, 比如被压缩过的文件. 但是用rar/zip工具查看过, 可以肯定APK里面的文件都没有压缩.

最后发现问题是 返回的fd需要关闭, 否则fd数量有限制或者占用内存太多, 后续创建fd会失败.

 int fd = ::AAsset_openFileDescriptor64(asset, (off64_t*)&Offset, (off64_t*)&Size);
...
::close(fd);

可以看注释中没有任何说明需要关闭, 或者如何处理函数返回的资源.

/**
* Open a new file descriptor that can be used to read the asset data. If the
* start or length cannot be represented by a 32-bit number, it will be
* truncated. If the file is large, use AAsset_openFileDescriptor64 instead.
*
* Returns < 0 if direct fd access is not possible (for example, if the asset is
* compressed).
*/

或许有人会笑了: fd当然是要关闭的啊. 但最重要的原因在这里:

/**
* Close the asset, freeing all associated resources.
*/
void AAsset_close(AAsset* asset);

既然fd是由asset创建出来的, 那么是否属于"associated resources"? 如果我脑补为"是"的话, 调用完AAsset_close()后就不需要close(fd)了, 有什么问题(兵库北笑脸)?
这种不说清楚的文档太坑爹了, 真心令人恼火. 网上甚至有人说这个是泄露的bug.

android ndk里真的是遍地坑啊, 自从接触了android natvie开发, 就经常感叹, 以往只靠c/c++标准文档,和msdn,man文档就可以轻松编写代码的日子, 一去不复返了 :D.


更新2:

图标大小

http://developer.android.com/design/style/iconography.html

LDPI – 36 x 36

MDPI – 48 x 48

HDPI – 72 x 72

XHDPI – 96 x 96

XXHDPI – 144 x 144

XXXHDPI –  192 x 192

https://developer.amazon.com/public/solutions/devices/kindle-fire/specifications/03-ux-specifications

Kindle Fire (1st Gen) – 322 x 322

Kindle Fire (2nd Gen) – 365 x 365

Kindle Fire HD 7″ – 425 x 425

Kindle Fire HD 8.9″ – 675 x 675

Kindle Fire HD 7″  (2nd Gen) – 425 x 425

Kindle Fire HD 8.9″ (2nd Gen) – 675 x 675

Kindle Fire HDX 7″  - 562 x 562

Kindle Fire HDX 8.9″  - 624 x 624


更新2(08.29.2014): 发现一个新bug

最近在引用第三方jar的时候总是说找不到symbol(引用class失败)

设置了jar的引用lib无效:

ar.libs.dir=../external/libs

然后又折腾了一番,

最后发现这个是ant的bug, 但是issue将不被修复, 因为那帮哥们儿忙着搞Gradle, 准备放弃ANT了.

http://code.google.com/p/android/issues/detail?id=33194

修复方法在这里:

http://stackoverflow.com/questions/11637852/is-jar-libs-dir-not-being-overridden-properly


Fire Phone Hero widget:

the home widget (HeroWidget stuff of FirePhone) initialization takes too long time on Activity.onCreate() (7-8 secs), and we found using resource id directly will take too long time

here's the code copied from Fire phone sample, with the change that we don't use uri to access remote URL (line 36):

     /**
* Create a ListEntry based on the given parameters.
* @param visualStyle
* @param groupName
* @param iconUri
* @param showExtraText true if the sample should set the secondary text
* @param startActivity true if the sample should start activities, otherwise just log clicks.
* @param index index of this Entry in the list. Used for setting UI text only.
* @return A new ListEntry object
*/
private ListEntry createListEntry(final VisualStyle visualStyle,
final String groupName, final Uri iconUri,
final boolean showExtraText, final boolean startActivity, final int index) {
final HeroWidgetIntent heroIntent;
if (startActivity) {
// For intents that start Activities, use HeroWidgetActivityStarterIntent
heroIntent = new HeroWidgetActivityStarterIntent(LIST_TARGET_ACTIVITY);
} else {
// Otherwise, use WidgetBroadcastReceiver to receive intents
heroIntent = new HeroWidgetIntent(WIDGET_BROADCAST_RECEIVER);
} heroIntent.setData(getString(R.string.group_item_in_group, index, groupName)); // Sets the texts, intent, etc.
final ListEntry listEntry = new ListEntry(this);
listEntry.setContentIntent(heroIntent);
listEntry.setVisualStyle(visualStyle);
listEntry.setPrimaryText(getString(R.string.group_primary, index));
// Star rating and review count have to be set simultaneously for them to show up.
// listEntry.setStarRating(5f - (index % 10) / 2f);
// Review count cannot be set to 0, otherwise it won't show.
listEntry.setReviewCount(index + );
// Sets the icons
log.d(TAG, "start set icon");
listEntry.setPrimaryIcon(R.drawable.towk_icon); //WTF? this operation takes too long time!
log.d(TAG, "end set icon"); if (showExtraText) {
// Show extra text in the ListEntry
listEntry.setSecondaryText(getString(R.string.group_secondary, index));
listEntry.setTertiaryText(getString(R.string.group_tertiary, index));
} return listEntry;
}

here's the doc:

https://developer.amazon.com/public/binaries/content/assets/javadoc/fire-phone/reference/com/amazon/device/home/groupedlistherowidget.listentry.html#setPrimaryIcon(int)

and our icon is 512x512, tried to change it to smaller size(32x32),

by using the URL, i.e. https://images-na.ssl-images-amazon.com/images/G/01/AmazonMobileApps/amazon-apps-store-us-white.png, as the sample does, we don't have this problem.

current workaournd is extracting the png from APK to local path( i.e. /data/data/appHome/files/cacheIcon.png ), and use Uri to locate the extracted png icon.

[工作积累] Google/Amazon平台的各种坑的更多相关文章

  1. [工作积累] Google Play Game SDK details

    https://developers.google.com/games/services/cpp/api/structgpg_1_1AndroidSupport For apps which targ ...

  2. [工作积累] Google Play Services

    注意添加APP_ID <meta-data android:name="com.google.android.gms.games.APP_ID" android:value= ...

  3. [工作积累] NBA 2K16 mobile终于发布了

    忙了大半年, 终于出来了. iOS: https://itunes.apple.com/us/app/nba-2k16/id984732818?mt=8 Android: https://play.g ...

  4. Google云平台对于2014世界杯半决赛的预测,德国阿根廷胜!

    由于本人是个足球迷,前段日子Google利用自己云平台预测世界杯八进四的比赛并取得了75%的正确率的事情让我振动不小.虽然这些年一直听说大数据的预测和看趋势能力如何如何强大,但这次的感受更加震撼,因为 ...

  5. Google协作平台

    本博文的主要内容有 .Google协作平台的介绍 1.Google协作平台的介绍 https://zh.wikipedia.org/wiki/Google%E5%8D%8F%E4%BD%9C%E5%B ...

  6. [工作积累] bitfield

    ISO/IEC 14882:2003: 9.6 Bit-fields [class.bit] A member-declarator of the form identifieropt : const ...

  7. Google Firebase Unity接入的坑

    就说跑demo碰到的坑吧 https://firebase.google.com/docs/unity/setup 这是Firebase Unity的setup指南 大概写写步骤: 1. Fireba ...

  8. Google云平台技术架构

    Google Cloud  设计原理: 1.分布式文件系统: Google Distributed File System(GSF)   为了满足Google迅速增长的数据处理需求,我们设计并实现了G ...

  9. Google云平台使用方法 | Hail | GWAS | 分布式回归 | LASSO

    参考: Hail Hail - Tutorial  windows也可以安装:Spark在Windows下的环境搭建 spark-2.2.0-bin-hadoop2.7 - Hail依赖的平台,并行处 ...

随机推荐

  1. Linux 结束进程

    一个进程由于以下5个原因中的一个终止 --main函数调用return; --调用exit函数--C语言库函数: --调用_exit函数--系统调用 --调用abort函数 --被一个信号终止.(ki ...

  2. C语言 函数理解(以数组做参数)

    #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int run(int *p){ // ...

  3. 解决 Windows Update 时提示当前无法检查更新,因为未运行服务

    故障:打开“Windows Update”出现红色盾牌图标 点击“检查更新”,出现“Windows Update 当前无法检查更新,因为未运行服务.您可能需要重新启动计算机” 查看“Windows U ...

  4. 基于IHttpAsyncHandler的TCP收发器

    上一篇文章中,我们提到使用IHttpAsyncHandler来进行UDP的收发操作.由于UDP模型比较简单,所以运行没什么问题.这一篇我主要是使用IHttpAsyncHandler来进行TCP的收发操 ...

  5. python数字图像处理(6):图像的批量处理

    有些时候,我们不仅要对一张图片进行处理,可能还会对一批图片处理.这时候,我们可以通过循环来执行处理,也可以调用程序自带的图片集合来处理. 图片集合函数为: skimage.io.ImageCollec ...

  6. Android清单文件详解(三)----应用程序的根节点<application>

    <application>节点是AndroidManifest.xml文件中必须持有的一个节点,它包含在<manifest>节点下.通过<application>节 ...

  7. 系分过了,mark一下,就从这里开始吧

    算是重新归回吧,发现写博客还是这里人气比较旺,开源中国不行,动弹人气还可以,不过都没啥节操, 这么多年没来了,发现竟然还排名1150,不容易,继续加油.有种回娘家的赶脚

  8. [CareerCup] 4.4 Create List at Each Depth of Binary Tree 二叉树的各层创建链表

    4.4 Given a binary tree, design an algorithm which creates a linked list of all the nodes at each de ...

  9. 20145208实验一 Java开发环境的熟悉

    20145208实验一 Java开发环境的熟悉 使用JDK编译.运行简单的java程序 命令行下程序开发 在命令行下建立实验目录,然后创建并进入该目录后的子目录. 编译并运行一个代码 使用IDEA 编 ...

  10. [转]MySQL5.5 my.cnf配置参考

    主要配置参数转载自: http://www.linuxyw.com/a/shujuku/20130506/216.html 并稍微做了修改MyISAM部分以适应当前的环境 此配置是老男孩生产线上使用的 ...