0

50MBを超えるため、openGL ESとAPK拡張ファイルを使用するネイティブAndroidアプリを作成しました。すべてのテクスチャは .obb ファイルにあり、これを Java にロードします (APKExpansionSupport を使用)。

展開から画像をロードする私の方法は次のとおりです

public static Bitmap getImageWithName(String a_path)
{
    Bitmap t_image = null;  
    try
    {
        InputStream t_inputStream = expansionFile.getInputStream(a_path);
        t_image = BitmapFactory.decodeStream(t_inputStream);            
        t_inputStream.close();
    }
    catch (Exception e)
    {
        Log.e(LOG_TAG, e.getMessage());
    }
    return t_image;
}

そして、ここに画像を取得するための私のjniメソッドがあります:

BImage * WFileLoader::getImage(const BString& a_path, FileLocation a_location)
{
    ...

    jmethodID javaMethod = env->GetStaticMethodID(cls, "getImageWithName","(Ljava/lang/String;I)Landroid/graphics/Bitmap;");

    if( javaMethod )
    {
        jobject t_bitmap = env->CallStaticObjectMethod(cls, javaMethod, t_path, t_location);

        if(t_bitmap)
        {
            jclass t_bitmapClass = env->FindClass("android/graphics/Bitmap");

            jmethodID t_getWidthMethod = env->GetMethodID(t_bitmapClass, "getWidth", "()I");
            jmethodID t_getHeightMethod =env->GetMethodID(t_bitmapClass, "getHeight", "()I");

            jint t_width = env->CallIntMethod(t_bitmap,t_getWidthMethod);
            jint t_height = env->CallIntMethod(t_bitmap,t_getHeightMethod);

            jmethodID t_getPixelsMethod = env->GetMethodID(t_bitmapClass, "getPixels", "([IIIIIII)V");

            jintArray t_intBuffer = env->NewIntArray(t_width*t_height);
            jint t_offset = 0;
            jint t_stride = t_width;
            jint t_x = 0;
            jint t_y=0;

            env->CallVoidMethod(t_bitmap,t_getPixelsMethod,t_intBuffer,t_offset,t_stride,t_x,t_y,t_width,t_height);

        ....    
    }
}

... 
}

テクスチャの読み込みは非常に長く、CPU 時間の約 30% を占めます (BitmapFactory.decodeStream がより大きな部分を占めます)。誰かがそれをロードするためのより良い解決策を持っていますか?

4

2 に答える 2

0

Android SDK の mountObb() を使用して APK ファイルをマウントします。APK に保存されているファイルの読み取りが高速で効率的です。

// Get OBB path
mSM = (StorageManager) getApplicationContext().getSystemService(STORAGE_SERVICE);
String tPackageName = "main." + versionCode + "." + getPackageName() + ".obb";
mObbPath = new File(Helpers.getSaveFilePath(this), tPackageName).getPath();

// Mount OBB
try {
    // We don't need to synchronize here to avoid clobbering the
    // content of mStatus because the callback comes to our main
    // looper.
    if (mSM.mountObb(mObbPath, null, mEventListener)) {
        Log.d(TAG, "Attempting to mount OBB");
    } else {
        Log.e(TAG, "Failed to start OBB mount.");
    }
} catch (IllegalArgumentException e) {
    Log.e(TAG, "OBB already mounted.");
}       

マウントしたら、getMountedObbPath() で指定されたファイル パスを使用してファイルにアクセスできます。

String tObbPath = mSM.getMountedObbPath(mObbPath)+ "/";

ファイルシステム内のファイルでマウント可能な obb ファイルを作成する必要があります。

AOSP の obbtool を使用しています (Linux でレポを複製してコンパイルする必要があります) が、最近、ジョブを実行できるようで、Android SDK に含まれている jobb を見つけましたか? (未テスト)

http://developer.android.com/tools/help/jobb.html

于 2014-01-12T01:17:28.903 に答える