学而实习之 不亦乐乎

Android:assets目录及使用

2022-07-12 08:09:07

一、概述

Android 中不同的资源文件,它们在生成 apk 时,会以不同的方式存在,如下:

  • 第一种是 res 目录下存放的可编译的资源文件:这种资源文件系统会在R.java里面自动生成该资源文件的ID,所以访问这种资源文件比较简单,通过R.XXX.ID即可;
  • 第二种是 assets 目录下存放的原生资源文件:因为系统在编译的时候不会编译assets下的资源文件,所以我们不能通过R.XXX.ID的方式访问它们。当 apk 安装之后会放在 /data/app/**.apk 目录下,以apk形式存在,并不会解压到/data/data/YourApp目录下去,所以我们无法直接获取到assets的绝对路径。Android系统为我们提供了一个AssetManager工具类来对应用程序的原始资源文件进行访问。

二、AssetManager 类

AssetManager 类提供了一个低级别的 API,它允许你以简单的字节流的形式打开和读取和应用程序绑定在一起的原始资源文件。通过 getAssets()方法获取 AssetManager 对象。

AssetManager 类常用方法:
String[] getLocales()
String[] list(String path):返回指定路径下的所有文件及目录名。
InputStream open(String fileName):使用 ACCESS_STREAMING模式打开assets下的指定文件。
InputStream open(String fileName, int accessMode):使用显示的访问模式打开assets下的指定文件。
AssetFileDescriptor    openFd(String fileName):通过映射打开未压缩的 asset 并返回 asset 文件描述符。
AssetFileDescriptor    openNonAssetFd(String fileName)
AssetFileDescriptor    openNonAssetFd(int cookie, String fileName)
XmlResourceParser    openXmlResourceParser(int cookie, String fileName):检索已编译的XML文件的解析器.
XmlResourceParser    openXmlResourceParser(String fileName):检索已编译的XML文件的解析器.

三、应用实例

1.加载assets目录下的网页

webView.loadUrl("file:///android_asset/win8_Demo/index.html");

2.访问assets目录下的资源文件

//返回的是一个InputSteam类型的字节流,这里的filename必须是文件,而不能是文件夹。
AssetManager.open(String filename); 

3.获取assets的文件及目录名

//获取assets目录下的所有文件及目录名,context(当前的上下文如Activity,Service等ContextWrapper的子类的都可以)
String fileNames[] =context.getAssets().list(path);  

4.将assets下的文件复制到SD卡

/** 
 *  从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);
    }
}

5.使用assets目录下的图片资源

InputStream is=getAssets().open("wpics/0ZR424L-0.jpg");
Bitmap bitmap=BitmapFactory.decodeStream(is);
imgShow.setImageBitmap(bitmap);

6.播放assets目录下的音乐

首先,获取通过openFd()的方法获取asset目录下指定文件的 AssetFileDescriptor 对象。
其次,通过MediaPlayer对象的setDataSource (FileDescriptorfd, longoffset, long length)方法加载音乐文件。
最后,调用prepare方法准备音乐,start方法开始播放音乐。

// 打开指定音乐文件,获取assets目录下指定文件的AssetFileDescriptor对象
AssetFileDescriptor afd = am.openFd(music);
mPlayer.reset(); // 使用MediaPlayer加载指定的声音文件。
mPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(), afd.getLength());

mPlayer.prepare();// 准备声音
mPlayer.start();// 播放