Android编程权威指南(第二版)学习笔记(十八)—— 第18章 Assets

本章介绍了 assets。assets 是有别于 resources 的另一种资源打包方式,可以被看作随应用打包的微型文件系统,支持任意层次的文件目录结构。因为这个优点,类似游戏这样需要加载大量图片和声音资源的应用通常都会使用它。

GitHub 地址:
完成18章

这章需要用到一个 RecyclerView,其中每个 ViewHolder 对应一个音频文件。如果使用 resources 来管理声音文件,那么 Android 一个一个处理效率将极其低下(毕竟声音是时间敏感的),所以我们使用 Assets 来处理。

1 导入 Assets

在模块的根目录下新建 assets 文件(或者右键点击模块的根目录新建),然后建立需要的资源文件夹并放入资源。

2 处理 Assets

assets 导入后,我们还要能在应用中进行定位、管理记录以及播放。这需要新建一个名为 BeatBox 的资源管理类,代码和相应注释如下:

public class BeatBox {
    // TAG 变量用于记录日志
    private static final String TAG = "BeatBox";

    // 用于存储声音资源文件目录名
    private static final String SOUNDS_FOLDER = "sample_sounds";

    // 访问 assets 需要用到 AssetManager 对象
    private AssetManager mAssets;

    public BeatBox(Context context) {
    // 在初始化的时候获取 assets 的管理对象
    // 不用在意 Context 是哪个,因为
    // 所有的 AssetManager 管理的都是一套 assets 资源
        mAssets = context.getAssets();
        loadSounds();
    }

    private void loadSounds() {
        String[] soundNames = new String[]{};
        try {
            // 获取所有文件的名字
            soundNames = mAssets.list(SOUNDS_FOLDER);
            Log.i(TAG, "Found " + soundNames.length + " sounds");
        } catch (IOException ioe) {
            Log.e(TAG, "Could not list assets", ioe);
        }
    }
}

3 使用 Assets

获取到资源文件名之后,要将其展示给用户,最终还需要播放这些声音文件。所以,我们得创建一个对象,让它管理资源文件名、用户应该看到的文件名以及其他一些相关信息。在这里,我们创建了一个叫 Sound 的类用来管理一个声音:

public class Sound {
    private String mAssetPath;
    private String mName;

    public Sound(String assetPath) {
        mAssetPath = assetPath;
        // 将文件路径用"/"分割
        String[] components = assetPath.split("/");
        // 取最后一个,即文件名
        String filename = components[components.length - 1];
        // 在知道文件名结尾是 .wav 的情况下,直接将 .wav 替换为空
        mName = filename.replace(".wav", "");
    }

    public String getAssetPath() {
        return mAssetPath;
    }

    public String getName() {
        return mName;
    }
}

然后在 BeatBox 类中获取所有的 Sound 对象,这样我们就有了 RecyclerView 的数据集,然后就能够绑定声音和 ViewHolder 了。

4 访问 Assets

Sound 对象定义了 assets 文件路径。但是尝试使用 File 对象打开资源文件是行不通的;
正确的方式是使用 AssetManager:

String assetPath = sound.getAssetPath();
InputStream soundData = mAssets.open(assetPath);

这样才能得到标准的 InputStream 数据流。随后,和 Java 中的其他 InputStream 一样,该怎么用就怎么用。
不过,有些 API 可能还会需要 FileDescriptor。(下一章的 SoundPool 类会用到。)这也好办, 如下列代码所示,改调用 AssetManager.openFd(String)方法就行了。

String assetPath = sound.getAssetPath();
// AssetFileDescriptors are different from FileDescriptors,
AssetFileDescriptor assetFd = mAssets.openFd(assetPath);
// but you get can a regular FileDescriptor easily if you need to.
FileDescriptor fd = assetFd.getFileDescriptor();

GitHub Page: kniost.github.io
:http://www.jianshu.com/u/723da691aa42

你可能感兴趣的:(Android编程权威指南(第二版)学习笔记(十八)—— 第18章 Assets)