作業記録[続]android OBB
11426 ワード
前二篇はここです
Androidには、native IOを使用しています。
最近仕事中の問題ノート
最近の問題は、
java.io.IOException:FATフル
StockOverflowの結果:
http://stackoverflow.com/questions/18906055/what-causes-jobb-tool-to-throw-fat-full-ioexception
質問者は自分で原因を説明しました。原因はOBが512 Mを超えるとエラーになります。しかし、FAT 16は最大で2 Gをサポートできます。これはjobbのバグです。
同時に作者はjobbの修復コードとbinを提供します。
https://github.com/monkey0506/jobbifier/tree/master/jObbifier/bin (Java/eclipseが分からないので、時間をかけてコンパイルして包装します。)
最後に、nativeでmountがずっとエラーを報告している問題(AOBB_STATEU_ERRORHuINTERNALについて、 AOBB_STATEUERRORHULD_logcatは出力がありません。また、ネット上では何の解決方法もありません。ここで発生した問題を解決できます。
最後にjava端mountに変えたら、なんと間違いなく成功しました。言葉がないです。What's wrong with the NDK team?why mounting obb in native fails but in Java end succedes?
また、インターネットでは、native APIコードに関する問題を見つけることができます。 https://code.google.com/p/android/issues/detail?id=41983
アスタージュManager:getMountedObPath
https://github.com/android/platform_frame eworksbase/blob/master/native/android/storge_manager.cpp
この問題は長い間提起されましたが、誰も変わりませんでした。
Obbのmountは例外的ですが、javaのコールバックは同期されています。また、コールバックはメッセージループを開始した後だけ呼び出されます。一方、nativeのcalbackは他のスレッドで呼び出されると確定しました。メッセージサイクルが始まってからでないといけませんか?それでもこのような穴は文書の中ではっきり言います。あるいはnative sampleをください。今はjavaのobsampleしかありません。
native APIでobbに対するサポートにはまだ多くの穴が見つかっていないようです。この部分はまずjavaを使うことにしました。
06/05/2014を更新します
nativeコードはこうです。
また、テストの時、いくつかの設備はpush OBB以降のappで読み取れないことが分かりました。最後に新しい標準パスが使われていないことを発見しました。ある設備には/sdcard/Android/obb/comp.XX.XXX/は訪問できません。sdk/tools/monitorを使ってmountの本当のルートを確認して、中に入ります。
http://stackoverflow.com/questions/18064114/expansion-file-cant-load-obb-from-sdcard-android-obb-on-android-4-2
例えばサムスンのGalaxy S 4は、4.4.2のシステムに更新されて、直接adb pushから/sdcard/Android/ob/XXX/main.1.xX.obまでは大丈夫です。
Galaxy Note 10 2014新版はシステムバージョンが4.3ですが、この問題があります。push以降、アプリケーションはファイルが見つかりません。
でも、これはデバッグの時にしかない問題です。本当にリリースする時、私達は真実なパスを知る必要がなくて、appはシステムからのパスを持ってきます。そして、obbをダウンロードしてこのフォルダの下に置きます。 デバッグ時は手動でアップロードしたカバンなので、パスが間違っているかもしれません。
現在、各種設備でテストしてJavaのmountに問題が発生したことがないと確定しました。
今はテストを便利にするために、優先的に読み取ります。
しかし、まだ新しいAndroidシステムがappプライベートのデータに対して読み取り権限の制限があるかどうかは分かりません。ないはずですが、文書を見て確認してください。
Android 4.4 KitKatは外部書き込み権限がないからです。(これはもっと安全でいいことだと思いますが、最初からそうするべきです。今突然このようにするとソフトウェアの互換性が問題になります。)外部読みに問題があるかどうかは分かりません。
Androidには、native IOを使用しています。
最近仕事中の問題ノート
最近の問題は、
java.io.IOException:FATフル
StockOverflowの結果:
http://stackoverflow.com/questions/18906055/what-causes-jobb-tool-to-throw-fat-full-ioexception
質問者は自分で原因を説明しました。原因はOBが512 Mを超えるとエラーになります。しかし、FAT 16は最大で2 Gをサポートできます。これはjobbのバグです。
同時に作者はjobbの修復コードとbinを提供します。
https://github.com/monkey0506/jobbifier/tree/master/jObbifier/bin (Java/eclipseが分からないので、時間をかけてコンパイルして包装します。)
最後に、nativeでmountがずっとエラーを報告している問題(AOBB_STATEU_ERRORHuINTERNALについて、 AOBB_STATEUERRORHULD_logcatは出力がありません。また、ネット上では何の解決方法もありません。ここで発生した問題を解決できます。
最後にjava端mountに変えたら、なんと間違いなく成功しました。言葉がないです。What's wrong with the NDK team?why mounting obb in native fails but in Java end succedes?
また、インターネットでは、native APIコードに関する問題を見つけることができます。 https://code.google.com/p/android/issues/detail?id=41983
アスタージュManager:getMountedObPath
https://github.com/android/platform_frame eworksbase/blob/master/native/android/storge_manager.cpp
155 const char* getMountedObbPath(const char* filename) {
156 String16 filename16(filename);
157 String16 path16;
158 if (mMountService->getMountedObbPath(filename16, path16)) {
159 return String8(path16).string(); //WTF? return a temp object's buffer? 160 } else {
161 return NULL;
162 }
163 }
Stering 8の実現を見ていないので、表面だけを見てlocalに戻ります。 temp objectのbufferは問題があるはずです。bufferはmallocの場合を除いて、文書はfreeなどと言っていないようです。実際には文字化けに戻ることもあります。この問題は長い間提起されましたが、誰も変わりませんでした。
Obbのmountは例外的ですが、javaのコールバックは同期されています。また、コールバックはメッセージループを開始した後だけ呼び出されます。一方、nativeのcalbackは他のスレッドで呼び出されると確定しました。メッセージサイクルが始まってからでないといけませんか?それでもこのような穴は文書の中ではっきり言います。あるいはnative sampleをください。今はjavaのobsampleしかありません。
native APIでobbに対するサポートにはまだ多くの穴が見つかっていないようです。この部分はまずjavaを使うことにしました。
06/05/2014を更新します
nativeコードはこうです。
1 Callback(const char* filename, const SYSTEM::int32_t state, void* callbackdata )
2 {
3 Android_App* app = (Android_App*)data;
4 if( state == AOBB_STATE_MOUNTED )
5 {
6 int isMounted = AStorageManager_isObbMounted(app->storage, filename);
7 assert( isMounted != 0 );
8
9 const char* mntPath = AStorageManager_getMountedObbPath(app->storage, filename);
10
11 //save persistent path data - current NDK returns tmp string that may even corrupted right after AStorageManager_getMountedObbPath() return
12 //https://code.google.com/p/android/issues/detail?id=41983
13 static char mountPath[PATH_MAX];
14 app->storageRoot = strcpy(mountPath, mntPath);
15 append(mountPath, "/data");
16
17 LOGI("OBB mounted: %s", filename);
18 pthread_cond_broadcast(&app->cond);
19 }
20 else if( state == AOBB_STATE_UNMOUNTED )
21 {
22 LOGI("OBB unmounted: %s", filename);
23 }
24 else if( state != AOBB_STATE_ERROR_NOT_MOUNTED)
25 {
26 LOGE("VCAndroid_ObbCallbackFunc: %d", state);
27 if( app != null )
28 pthread_cond_broadcast(&app->cond);
29 }
30 }
31
32
33 mountOBB()
34 {
35 AStorageManager_mountObb( Callback );
36 pthread_cond_wait(&app->cond, &app->mutex);
37
38 }
39
40
41 //Main thread entry for activity create, called by NactiveActivity.java
42 NativeActivity_onCreate()
43 {
44 ...
45 mountOBB();
46 createthread: android_main(); //this is pseudo code
47 return;
48 }
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(...)) >= 0 )
{
if( isOBBMounted() )
continue_app();
}
}
最後に、nativeコードも全部android_に入れてみます。メインスレッドの中で、そしてウィンドウの作成を待って、Javaコードのようにループして調べたら、まだ失敗しました。また、テストの時、いくつかの設備はpush OBB以降のappで読み取れないことが分かりました。最後に新しい標準パスが使われていないことを発見しました。ある設備には/sdcard/Android/obb/comp.XX.XXX/は訪問できません。sdk/tools/monitorを使ってmountの本当のルートを確認して、中に入ります。
http://stackoverflow.com/questions/18064114/expansion-file-cant-load-obb-from-sdcard-android-obb-on-android-4-2
例えばサムスンのGalaxy S 4は、4.4.2のシステムに更新されて、直接adb pushから/sdcard/Android/ob/XXX/main.1.xX.obまでは大丈夫です。
Galaxy Note 10 2014新版はシステムバージョンが4.3ですが、この問題があります。push以降、アプリケーションはファイルが見つかりません。
でも、これはデバッグの時にしかない問題です。本当にリリースする時、私達は真実なパスを知る必要がなくて、appはシステムからのパスを持ってきます。そして、obbをダウンロードしてこのフォルダの下に置きます。 デバッグ時は手動でアップロードしたカバンなので、パスが間違っているかもしれません。
現在、各種設備でテストしてJavaのmountに問題が発生したことがないと確定しました。
今はテストを便利にするために、優先的に読み取ります。
しかし、まだ新しいAndroidシステムがappプライベートのデータに対して読み取り権限の制限があるかどうかは分かりません。ないはずですが、文書を見て確認してください。
Android 4.4 KitKatは外部書き込み権限がないからです。(これはもっと安全でいいことだと思いますが、最初からそうするべきです。今突然このようにするとソフトウェアの互換性が問題になります。)外部読みに問題があるかどうかは分かりません。