作業記録[続]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
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は外部書き込み権限がないからです。(これはもっと安全でいいことだと思いますが、最初からそうするべきです。今突然このようにするとソフトウェアの互換性が問題になります。)外部読みに問題があるかどうかは分かりません。