resources资源可以存储声音文件,但当处理多个音乐文件时,效率会很低。

assets可以被看作随应用打包的微型文件系统,支持任意层次的文件目录结构。类似游戏这样需要加载大量图片和声音资源的应用通常都会使用它

 

1. 导入assets

在app模块下创建assets目录,然后建立需要的资源文件夹并放入资源。

 

2. 处理assets

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

 

 1 public class BeatBox {
 2 
 3     //用于日志记录
 4     private static final String TAG = "BeatBox";
 5 
 6     //用于存储声音资源文件目录名
 7     private static final String SOUNDS_FOLDER = "sample_sounds";
 8 
 9     //访问assets需要用到AssetManager类,可以从context中获取到它,这里添加一个带Contex参数的构造函数获取并留存它。
10     private AssetManager mAssets;
11 
12     public BeatBox(Context context){
13         /*
14          * 访问assets时,可以不用关心究竟使用哪个Contex对象,
15          * 而且在实际开发的任何场景下,所有Context中的AssetManager管理的都是同一套assets资源。
16          */
17         mAssets = context.getAssets();
18         loadSounds();
19     }
20 
21     private void loadSounds(){
22         String[] soundNames;
23         try{
24             //list(S)方法取得assets中的资源清单。能够列出指定目录中的所有文件名。
25             //只要传入声音资源所在的目录,就能看到其中所有的.wav文件。
26             soundNames = mAssets.list(SOUNDS_FOLDER);
27             Log.i(TAG, "Found "+ soundNames.length + " sounds");
28         }catch (IOException ioe){
29             Log.e(TAG, "Could not list assets",ioe );
30             return;
31         }
32     }
33 }

 

3. 使用Assets

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

创建一个Sound管理类。

 1 public class BeatBox {
 2 
 3     //用于日志记录
 4     private static final String TAG = "BeatBox";
 5 
 6     //用于存储声音资源文件目录名
 7     private static final String SOUNDS_FOLDER = "sample_sounds";
 8 
 9     //访问assets需要用到AssetManager类,可以从context中获取到它,这里添加一个带Contex参数的构造函数获取并留存它。
10     private AssetManager mAssets;
11 
12     //创建一个Sound列表
13     private List<Sound> mSounds = new ArrayList<>();
14 
15     public BeatBox(Context context){
16         /*
17          * 访问assets时,可以不用关心究竟使用哪个Contex对象,
18          * 而且在实际开发的任何场景下,所有Context中的AssetManager管理的都是同一套assets资源。
19          */
20         mAssets = context.getAssets();
21         loadSounds();
22     }
23 
24     private void loadSounds(){
25         String[] soundNames;
26         try{
27             //list(S)方法取得assets中的资源清单。能够列出指定目录中的所有文件名。
28             //只要传入声音资源所在的目录,就能看到其中所有的.wav文件。
29             soundNames = mAssets.list(SOUNDS_FOLDER);
30             Log.i(TAG, "Found "+ soundNames.length + " sounds");
31         }catch (IOException ioe){
32             Log.e(TAG, "Could not list assets",ioe );
33             return;
34         }
35 
36         for(String fileName : soundNames){
37             String assetPath = SOUNDS_FOLDER + "/" + fileName;
38             Sound sound = new Sound(assetPath);
39             mSounds.add(sound);
40         }
41     }
42 
43     public  List<Sound> getSounds(){
44         return mSounds;
45     }
46 }

4. 访问Assets

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

String assetPath = sound.getAssetPath();

InputStream sounData = mAssets.open(assetPath);  //这样就得到了标准的InputStream数据流,随后,和java中的其他InputStream一样,该怎么用就怎么用。

 

不过有些API可能还会需要FileDescriptor。只需要改为调用AddetManager.openFd(String)方法就行了。

String assetPath = sound.getAssetPath();

AssetFileDescriptor assetFd = mAssets.openFd(assetPath);

FileDescriptor fd = assetFd.getFileDescriptor();