在做安卓小项目的时候,一般图片都是放在res/drawable文件夹中,需要访问的时候通过R.drawable.xxxx来访问该图片,但是如果项目比较大的话,而图片又特别多,那么如果依然通过R.drawable.xxx来访问图片的话,那是相当的累。安卓中,有一个assets目录,我们可以把图片放在这个目录下,通过I/O流来访问其中的图片。
assets和drawable的区别。
相同点:
1.文件会原封不动的存储在设备上,不会被编译成二进制。
不同点:
1.引用资源方式不同:
drawable中的资源会在R类中生成相应的int型变量。
assets中的资源不会。
故:引用drawable中资源的时候可以通过R.drawable.xxxx的方式引用,而引用assets中资源需要用文件名引用。
2.子目录不同:
drawable不能继续建文件夹(不能有子文件夹),但是assets中可以建任意层次的子目录(操作更加灵活)。
那么到底如何才能获取到assets中的资源呢?通过Android提供的AssetManager工具类。
知识储备:
1.概述:
Provides access to an application's raw asset files; seeResources
for the way most applications will want to retrieve their resource data. This class presents a lower-level API that allows you to open and read raw files that have been bundled with the application as a simple stream of bytes.
这是API里面写的,大概意思是,提供一个访问对原始资源文件进行访问的方式。应用程序使用该方式查看资源,大多是要获取资源中的数据。这个类提供了一个较低的API允许你以简单的字节流打开和读取和应用程序绑定在一起的资源文件(自行翻译,一切以原文为准)。
2.常用方法:
String[] | list(String path) 返回指定路径下的所有文件及目录名 |
InputStream | open(String fileName) 使用ACCESS_STREAMING模式打开 |
InputStream | open(String fileName ,int accessMode) 使用显示的访问模式打开assets下的指定文件 |
3.使用
3.1加载网页
WebView w;
w.loadUrl(url);
3.2访问文件
InputStream is = getAssets().open(fileName);
3.3获取文件和目录名
String fileNames[] = content.getAssets().list(path);
/**
* 从assets目录中复制整个文件夹内容
* @param context Context 使用CopyFiles类的Activity
* @param oldPath String 原文件路径 如:/aa
* @param newPath String 复制后路径 如:xx:/bb/cc
*/
public void copyFilesFassets(Context context,String oldPath,String newPath) {
try {
String fileNames[] = context.getAssets().list(oldPath);//获取assets目录下的所有文件及目录名
if (fileNames.length > 0) {//如果是目录
File file = new File(newPath);
file.mkdirs();//如果文件夹不存在,则递归
for (String fileName : fileNames) {
copyFilesFassets(context,oldPath + "/" + fileName,newPath+"/"+fileName);
}
} else {//如果是文件
InputStream is = context.getAssets().open(oldPath);
FileOutputStream fos = new FileOutputStream(new File(newPath));
byte[] buffer = new byte[1024];
int byteCount=0;
while((byteCount=is.read(buffer))!=-1) {//循环从输入流读取 buffer字节
fos.write(buffer, 0, byteCount);//将读取的输入流写入到输出流
}
fos.flush();//刷新缓冲区
is.close();
fos.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
//如果捕捉到错误则通知UI线程
MainActivity.handler.sendEmptyMessage(COPY_FALSE);
}
}