什么是从NDK中的扩展文件加载文件的最佳方式
问题描述:
我编写了一个使用openGL ES和APK扩展文件的原生android应用程序,因为它大于50MB。 我所有的纹理都在.obb文件中,我使用java加载(使用APKExpansionSupport)。什么是从NDK中的扩展文件加载文件的最佳方式
这里是我的方法从扩张加载图像
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);
....
}
}
...
}
纹理加载很长,大约需要30我的CPU时间百分比(BitmapFactory.decodeStream占用了大部分时间)。有没有人有更好的解决方案来加载它?
答
我正在尝试使用zzip来解决此问题。
答
我使用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中克隆和编译repo),但最近我发现jobb似乎能够完成这项工作,并且包含在Android SDK中? (未测试)