前言
Android有assets和resources两大资源系统。resources资源系统设计有良好的检索系机制,但它无法应付图形和声音文件这样的大文件,因此这些资源实际是保存在assets系统里的。
/res和/assets的不同点是,Android不为/assets下的文件生成ID。如果使用/assets下的文件,需要指定文件的路径和文件名。
assets和res/raw的对比
res/raw和assets的相同点:
两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。
res/raw和assets的不同点:
- res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
- res/raw不可以有目录结构,而assets则可以有目录结构(在其目录下可以再建文件夹)
- 读取res/raw下的文件资源,通过以下方式获取输入流:InputStream is = getResources().openRawResource(R.raw.filename); 读取assets下的文件资源,通过以下方式获取输入流:InputStream is = getAssets().open("filename");
访问assets文件
由于asset文件是不会生成资源id,因此不能通过getresource()获取。
Android给我们AssetManager来访问assets中的内容。
//获取AssetManager
AssetManager mAssetManager = getAssets();
list
AssetsManager.list(String)方法能列出指定目录中的所有文件和文件夹。
/**
*
* @param assetManager
* @param folderPath [assets中的目录,根目录“”(空字符串),其他的写目录名image]
*/
private void findALlFile(AssetManager assetManager, String folderPath) {
if (null == assetManager || null == folderPath) {
Log.d(TAG, "findALlFile null...");
return;
}
try {
String[] files = assetManager.list(folderPath);
if (null != files && files.length > 0) {
for (int i = 0; i < files.length; i++) {
//打印查询内容
Log.d(TAG, "assetsUsed [" + i + "]: " + files[i]);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return;
}
open
AssetsManager.open(String)方法能标准的InputStrem数据流,然后就随便你怎么处理。
/**
*
* @param assetManager
* @param imageView
* @param fileName [是在assets根目录中的"abc.png"或者"image/test.png"]
*/
private void updateAssetImage(AssetManager assetManager, ImageView imageView, String fileName){
if (null == assetManager || null == imageView || null == fileName) {
Log.d(TAG, "updateAssetImage null...");
return;
}
InputStream mInputStream = null;
try {
mInputStream = assetManager.open(fileName);
if (null != mInputStream) {
Drawable mDrawable = Drawable.createFromStream(mInputStream, null);
imageView.setImageDrawable(mDrawable);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != mInputStream) {
try {
mInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return;
}
openNonAssetFd
mAssetManager出了处理获取assets内的文件,还可以获取res中的指定文件。
可以使用openNonAssetFd()
代码片段
/**
*
* @param assetManager
* @param imageView
* @param resPath 注意格式为[res/drawable/ic_launcher.png]
*/
private void updateResImage(AssetManager assetManager, ImageView imageView, String resPath){
if (null == assetManager || null == imageView || null == resPath) {
Log.d(TAG, "updateResImage null...");
return;
}
InputStream mInputStream = null;
AssetFileDescriptor mAssetFileDescriptor= null;
try {
mAssetFileDescriptor = assetManager.openNonAssetFd(resPath);
if (null != mAssetFileDescriptor) {
mInputStream = mAssetFileDescriptor.createInputStream();
if (null != mInputStream) {
Drawable mDrawable = Drawable.createFromStream(mInputStream, null);
if (null != mDrawable) {
imageView.setImageDrawable(mDrawable);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(null!= mInputStream){
try {
mInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null!=mAssetFileDescriptor){
try {
mAssetFileDescriptor.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return;
}
上面的resPath必须写res开头的,其他的就会出现java.io.FileNotFoundException。
