前两篇在这里:

Android上使用native IO

最近工作中的问题笔记

最近遇到的问题是,

java.io.IOException: FAT Full

StackOverflow的结果:

http://stackoverflow.com/questions/18906055/what-causes-jobb-tool-to-throw-fat-full-ioexception

提问者自己解释了原因, 原因是obb超过512M就出错了. 但是FAT16最大可以支持2G, 这个是jobb的bug.

同时作者提供了jobb修复的代码和bin:

https://github.com/monkey0506/jobbifier/tree/master/jObbifier/bin (由于不懂Java/eclipse,花了点时间才编译打包出来)

最后关于在native下 mount一直报错的问题(AOBB_STATE_ERROR_INTERNAL, AOBB_STATE_ERROR_COULD_NOT_MOUNT)
logcat没有任何输出, 同时网上也没有任何解决方法可以解决我这里遇到的问题.

最后改用在java端mount, 竟然毫无错误的成功了...表示很无语. What's wrong with the NDK team? why mounting obb in native fails but in Java end succeeds?

另外, 网上可以找到关于native API code里的问题 https://code.google.com/p/android/issues/detail?id=41983

AStorageManager::getMountedObbPath

https://github.com/android/platform_frameworks_base/blob/master/native/android/storage_manager.cpp

     const char* getMountedObbPath(const char* filename) {
String16 filename16(filename);
String16 path16;
if (mMountService->getMountedObbPath(filename16, path16)) {
return String8(path16).string(); //WTF? return a temp object's buffer?
} else {
return NULL;
}
}

由于没有看String8的实现, 但是单从表面上看, 返回一个local temp object的buffer, 应该是有问题的, 除非buffer是malloc的,但貌似文档又没有说要free之类的(或者是mountService内部的也可以). 而实际中我也遇到返回乱码的情况.

这个问题有人提出很久了, 但是一直没有人去改..

虽然obb的mount都是异步的, 但java的回调是同步的, 而且回调只有在开始了消息循环以后才会被调用. 而native的callback确定是在另外一个线程调用的,难道也要等到消息循环开始以后才可以? 即便是这样, 这种坑也应该在文档里面说清楚,或者给个native sample吧..现在只有java的obb sample.

感觉native API上对obb的支持有很多坑还没有发现. 这部分决定先用java了.


更新06/05/2014

native代码是这样的:

 Callback(const char* filename, const SYSTEM::int32_t state, void* callbackdata )
{
Android_App* app = (Android_App*)data;
if( state == AOBB_STATE_MOUNTED )
{
int isMounted = AStorageManager_isObbMounted(app->storage, filename);
assert( isMounted != ); const char* mntPath = AStorageManager_getMountedObbPath(app->storage, filename); //save persistent path data - current NDK returns tmp string that may even corrupted right after AStorageManager_getMountedObbPath() return
//https://code.google.com/p/android/issues/detail?id=41983
static char mountPath[PATH_MAX];
app->storageRoot = strcpy(mountPath, mntPath);
append(mountPath, "/data"); LOGI("OBB mounted: %s", filename);
pthread_cond_broadcast(&app->cond);
}
else if( state == AOBB_STATE_UNMOUNTED )
{
LOGI("OBB unmounted: %s", filename);
}
else if( state != AOBB_STATE_ERROR_NOT_MOUNTED)
{
LOGE("VCAndroid_ObbCallbackFunc: %d", state);
if( app != null )
pthread_cond_broadcast(&app->cond);
}
} mountOBB()
{
AStorageManager_mountObb( Callback );
pthread_cond_wait(&app->cond, &app->mutex); } //Main thread entry for activity create, called by NactiveActivity.java
NativeActivity_onCreate()
{
...
mountOBB();
createthread: android_main(); //this is pseudo code
return;
}

调用java的native代码是这样:

//pseudo codes:

mountOBB()
{
call Java code to mount
} bool isOBBMounted()
{
query Java code whether mount ready
} NativeActivity_onCreate(...)
{
...
mountOBB();
create thread: android_main();
} android_main()
{ while ((ident= ALooper_pollAll(...)) >= )
{
if( isOBBMounted() )
continue_app();
}
}

最后尝试把native代码也全放在android_main()线程里,而且等窗口创建好, 像用Java代码那样循环查询, 还是失败...

还有, 测试的时候还发现, 某些设备push OBB以后app读取不出来, 最后发现是没有使用新的标准路径,
有的设备上/sdcard/Android/obb/com.XXX.XXX/ 是无法访问的. 要使用sdk/tools/monnitor查看mount的真正路径,然后方进去

http://stackoverflow.com/questions/18064114/expansion-file-cant-load-obb-from-sdcard-android-obb-on-android-4-2

比如三星的Galaxy S4, 更新到4.4.2的系统, 直接adb push到/sdcard/Android/obb/XXX/main.1.XXX.obb就没有问题,

而Galaxy Note 10 2014新版虽然系统版本是4.3, 但是就有这个问题, push以后, 应用程序找不到该文件.

不过这个是调试的时候才有的问题. 真正发布的时候, 我们不需要知道真实路径, app会拿到系统给的路径, 然后下载obb放到该文件夹下. 调试的时候因为是手动上传的包, 可能路径不对.


目前在各种设备上测试确定Java的mount没有出现过问题.

现在为了方便测试, 会优先读取/sdcard/main.1.XXX.obb 这样测试的时候obb直接放到sd卡里面就好了,一般测试的时候都是这么做吧.

但是还是不确定新的安卓系统对于非app私有的数据是否有读取权限限制, 应该没有, 不过最好先看文档确认下.

因为Android4.4 KitKat已经没有外部写权限了(我觉得这样更安全,本来是个好事,但是应该一开始就这么搞,现在突然这么搞会出现软件兼容性问题), 不知道外部读会不会有问题, 现在测过一两个4.4的设备还没有发现问题.

工作记录[续] android OBB的更多相关文章

  1. 【工作记录】android手势事件操作记录

    /* 用户按下触摸屏.快速移动后松开 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float vel ...

  2. 工作记录 - OBB的解决方案

    之前关于OBB的内容: Android上使用native IO 最近工作中的问题笔记 工作记录[续] android OBB 自从用了Java来mount OBB, 再也没有遇到挂载的问题. 但最近在 ...

  3. [工作记录] Android OpenGL ES: non-square texture - continue

    previous: [工作记录] Android OpenGL ES 2.0: square texture not supported on some device recently I found ...

  4. [转]倍数提高工作效率的 Android Studio 奇技

    转自:http://android.jobbole.com/81687/ 倍数提高工作效率的 Android Studio 奇技 2015/10/08 · 技术分享 · 4 评论· Android S ...

  5. MySQL跨表更新字段 工作记录

    工作中遇到两表查询,从user表中获取用户唯一id字段 写入到另外一张qiuzu表中的uid字段中; 二者可以关联起来的只有用户的手机号码tel字段; 了解需求后数据量稍多,不可能一个一个的手动修改 ...

  6. 最近的linux工作记录

    最近的linux工作记录 最近公司走了一些同事,部分服务器交到了我的手里,总结一些常用的操作 注:大写的字符串一般是用来占位,需要替换 创建账户和使用密钥对登陆 1,账户系列 useradd 选项 用 ...

  7. 『记录』Android参考资料

    欢迎留言推荐好的教程.资料.博客及作者等. 『记录』Android参考资料 1.前期环境 Android Studio使用Git Android Studio快捷键总结 Android Studio及 ...

  8. 工作记录--WPF自定义控件,实现一个可设置编辑模式的TextBox

    原文:工作记录--WPF自定义控件,实现一个可设置编辑模式的TextBox 1. 背景 因为最近在使用wpf开发桌面端应用,在查看页面需要把TextBox和Combox等控件设置为只读的.原本是个很简 ...

  9. 图书馆管理系统程序+全套开发文档(系统计划书,系统使用说明,测试报告,UML分析与设计,工作记录)

    图书馆管理系统程序+全套开发文档(系统计划书,系统使用说明,测试报告,UML分析与设计,工作记录): https://download.csdn.net/download/qq_39932172/11 ...

随机推荐

  1. Observer,观察者模式,C++描述

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  2. L1-056 猜数字

    一群人坐在一起,每人猜一个 100 以内的数,谁的数字最接近大家平均数的一半就赢.本题就要求你找出其中的赢家. 输入格式: 输入在第一行给出一个正整数N(≤10​4​​).随后 N 行,每行给出一个玩 ...

  3. DevExpress v18.1新版亮点——Reporting篇(三)

    用户界面套包DevExpress v18.1日前终于正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了DevExpress Reporting v18.1 的新功能,快来下载试用新版本 ...

  4. 201621123001 《Java程序设计》第8周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 2. 书面作业 1. ArrayList代码分析 1.1 解释ArrayList的contains源代码 Answer: 源 ...

  5. CSS学习笔记-02. 2D转换模块-形变中心点

    简单粗暴,直接上重点:  transform-origin 接下来是代码. 首先 勾勒出 3个重叠的div 接着 给3个div分别添加 transform: rotate . <!DOCTYPE ...

  6. centos installation of matlab R2015b

    the source of installation is in the website: http://blog.csdn.net/hejunqing14/article/details/50265 ...

  7. elk之logstash

    环境: centos7 jdk8 1.创建Logstash源 rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch touch ...

  8. python3.6 安装第三方库 pyCryptodome 实现AES加密

    起因 前端日子写完的Python入库脚本,通过直接读取配置文件的内容(包含了数据库的ip,数据库的用户名,数据库的密码),因为配置文件中的数据库密码是明文显示的,所以不太安全,由此对其进行加密. 编码 ...

  9. centos安装python3虚拟环境和python3安装

    1.本文的系统命令一般会在语句前加上#号,以区分系统命令及其他内容.输入命令时,无需输入#号. # yum install vim 2.本文系统输出的信息,会在前面加上>>号. # whi ...

  10. python 元组攻略

    1.元组中只包含一个元素时,需要在元素后面添加逗号来消除歧义 tup1=(50,) 2.元组中的元素值使不允许修改的,但可以对元组进行连接组合复制代码 1 tup1=(12,34.56)2 tup2= ...