Android学习--Assets资源文件读取及AssetManager介绍
APK安装过程
复制APK安装包到data/app目录下,解压并扫描安装包,把dex文件(Dalvik字节码)保存到dalvik-cache目录,并data/data目录下创建对应的应用数据目录,Android系统在sdcard上为每一个应用分配了存储路径:/sdcard/Android/data/$(应用的包路径),该路径可以通过 context.getExternalFilesDir 得到,一般应用卸载的时候,该目录也会随之被删除。
Android资源文件分为两类:
第一种是res目录下存放的可编译的资源文件,编译时,系统会自动在R.java中生成资源文件的ID,所以访问这种资源比较简单,通过在程序中调用R.id.filenam e即可。
另一种是assets目录下存放的原始资源文件,因为系统在编译的时候不会编译assets下的资源文件,所以我们不能通过R.id.filename的方式访问它们。那我么能不能通过该资源的绝对路径去访问它们呢?因为apk安装之后会放在/data/app/**.apk目录下,assets被绑定在apk里,以apk形式存在,并不会解压到/data/data/YourApp目录下去,所以我们无法直接获取到assets的绝对路径,因为它们根本就没有独立存在。
res/raw和assets的相同点:
1.两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。
res/raw和assets的不同点:
1.res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
2.res/raw不可以有目录结构,而assets则可以有目录结构(在其目录下可以再建文件夹)
3.读取res/raw下的文件资源,通过以下方式获取输入流:InputStream is=getResources().openRawResource(R.id.filename); 读取assets下的文件资源,通过以下方式获取输入流:InputStream is =getResources()..getAssets().open("filename");
AssetManager管理对assets文件夹资源的访问
查看官方API可知,AssetManager提供对应用程序的原始资源文件进行访问;这个类提供了一个低级别的API=1,它允许你以简单的字节流的形式打开和读取和应用程序绑定在一起的原始资源文件。主要用到list()及open()方法。
finalString[] list(Stringpath) 返回指定路径下的所有文件及目录名,path是相对路径,是assets子目录。
finalInputStream open(String fileName) 使用 ACCESS_STREAMING模式打开assets下的指定文件,fileName是相对路径,是assets子目录。
finalInputStream open(String fileName,int accessMode) 使用显示的访问模式打开assets下的指定文件。
下面这个类,主要功能是通过递归方式,实现对assets下的某个子目录文件读取操作,并复制到指定路径。
- package com.study.asset;
-
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
-
- import com.study.mylog.MyLog;
-
- import android.content.Context;
- import android.content.res.AssetManager;
-
- public class AssetsCopy {
-
- private Context mContext;
- public AssetsCopy(Context context) {
- mContext = context;
- }
-
- public boolean CopyFiles(String oldPath, String newPath) throws IOException {
- boolean isCopy = true;
- AssetManager mAssetManger = mContext.getAssets();
- String[] fileNames=mAssetManger.list(oldPath);// 获取assets目录下的所有文件及有文件的目录名
-
- if (fileNames.length > 0) {//如果是目录,如果是具体文件则长度为0
- File file = new File(newPath);
- file.mkdirs();//如果文件夹不存在,则递归
- for (String fileName : fileNames) {
- if(oldPath=="") //assets中的oldPath是相对路径,不能够以“/”开头
- CopyFiles(fileName,newPath+"/"+fileName);
- else
- CopyFiles(oldPath+"/"+fileName,newPath+"/"+fileName);
- }
- }else {//如果是文件
- InputStream is = mAssetManger.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();
- }
- return isCopy;
- }
-
- }