学而实习之 不亦乐乎

Android:AssetFileDescriptor 类

2022-07-12 08:08:31

一、概述

Android 应用程序是将代码逻辑和界面资源进行分离的,Android应用程序资源可以分为两大类,分别是 assets res

  • assets类资源放在工程根目录的assets子目录下,它里面保存的是一些原始的文件,可以以任何方式来进行组织。这些文件最终会被原装不动地打包在apk文件中。如果我们要在程序中访问这些文件,那么就需要指定文件名来访问。
  • res类资源放在工程根目录的res子目录下,它里面保存的文件大多数都会被编译,并且都会被赋予资源ID。这样我们就可以在程序中通过ID来访问res类的资源。


文件描述符 AssetFileDescriptor 是 AssetManager 的入口。提供了您自己打开的文件描述符,可用于读取数据,以及该文件中数据的偏移量和长度。常用方法如下(参考自官方文档):

AssetFileDescriptor(ParcelFileDescriptor fd, long startOffset, long length)
AssetFileDescriptor(ParcelFileDescriptor fd, long startOffset, long length, Bundle extras)

close():Convenience for calling getParcelFileDescriptor().close().

FileInputStream createInputStream():Create and return a new auto-close input stream for this asset.This will either return a full asset AutoCloseInputStream, or an underlying ParcelFileDescriptor.AutoCloseInputStream depending on whether the the object represents a complete file or sub-section of a file. You should only call this once for a particular asset.

FileOutputStream createOutputStream():Create and return a new auto-close output stream for this asset.This will either return a full asset AutoCloseOutputStream, or an underlying ParcelFileDescriptor.AutoCloseOutputStream depending on whether the the object represents a complete file or sub-section of a file. You should only call this once for a particular asset.

int describeContents():Describe the kinds of special objects contained in this Parcelable instance's marshaled representation.For example, if the object will include a file descriptor in the output of writeToParcel(android.os.Parcel, int), the return value of this method must include the CONTENTS_FILE_DESCRIPTOR bit.

long getDeclaredLength():Return the actual number of bytes that were declared when the AssetFileDescriptor was constructed. Will be UNKNOWN_LENGTH if the length was not declared, meaning data should be read to the end of the file.

Bundle getExtras():Returns any additional details that can be used to interpret the underlying file descriptor.
FileDescriptor getFileDescriptor():Returns the FileDescriptor that can be used to read the data in the file.
long getLength():Returns the total number of bytes of this asset entry's data.May be UNKNOWN_LENGTH if the asset extends to the end of the file. If the AssetFileDescriptor was constructed with UNKNOWN_LENGTH, this will use ParcelFileDescriptor.getStatSize() to find the total size of the file, returning that number if found or UNKNOWN_LENGTH if it could not be determined.

ParcelFileDescriptor getParcelFileDescriptor():The AssetFileDescriptor contains its own ParcelFileDescriptor, which in addition to the normal FileDescriptor object also allows you to close the descriptor when you are done with it.
long getStartOffset():Returns the byte offset where this asset entry's data starts.
String toString():Returns a string representation of the object.In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method.

The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of: getClass().getName() + '@' + Integer.toHexString(hashCode())

void writeToParcel(Parcel out, int flags):Flatten this object in to a Parcel.


二、实例

1、使用 AssetFileDescriptor 来读取(android)app的raw文件夹下的数据

try {
    AssetFileDescriptor fd = getResources().openRawResouceFd(R.raw.greet_1);
    mp.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
    mp.start();
    fd.close();
} catch (IllegalArgumentException e) {
    // handle exception
} catch (IllegalStateException e) {
    // handle exception
} catch (IOException e) {
    // handle exception
}

2、解码 bmp 图像

private static Bitmap decodeBitmap(Context context, Uri theUri, int sampleSize) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = sampleSize;

    AssetFileDescriptor fileDescriptor = null;
    try {
        fileDescriptor = context.getContentResolver().openAssetFileDescriptor(theUri, "r");
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    Bitmap actuallyUsableBitmap = BitmapFactory.decodeFileDescriptor(
            fileDescriptor.getFileDescriptor(), null, options);

    Log.d(TAG, options.inSampleSize + " sample method bitmap ... " +
            actuallyUsableBitmap.getWidth() + " " + actuallyUsableBitmap.getHeight());

    return actuallyUsableBitmap;
}