Android的AssetManager使用

Android  2020年9月24日 pm11:01发布4年前 (2020)更新 91es.com站长
78 0 0

前言

Androidassetsresources两大资源系统。resources资源系统设计有良好的检索系机制,但它无法应付图形和声音文件这样的大文件,因此这些资源实际是保存在assets系统里的。

/res和/assets的不同点是,Android不为/assets下的文件生成ID。如果使用/assets下的文件,需要指定文件的路径和文件名。

assets和res/raw的对比

res/raw和assets的相同点:

两者目录下的文件在打包后会原封不动的保存在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.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。

参考文章

  1. AssetManager中常用的list()方法和open()
  2. context.getAssets().openNonAssetFd
  3. Android之资源打包方式——Assets

 历史上的今天

  1. 2021: Windows 文本大文件查看工具glogg(0条评论)
  2. 2019: 莫泊桑:巴蒂斯特太太(0条评论)
版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站内容: 部分来源于网络,仅供学习和参考,若侵权请留言
3、 本站申明: 个人流水账日记,内容并不保证有效

暂无评论

暂无评论...

随机推荐

addr2line.exe的简单使用

前言不常用,偶尔需要,在学习JNI时也学习addr2line工具的使用,记录于此,方便自己查阅。正文addr2line工具在Android NDK包中,我这里以Window版的为例。我这下载的是android-ndk-r21d-windows-x86_64.zip解压和环境配置我这不解...

Android磁盘之Vold启动

前言Volume Daemon,简写Vold,用于管理和控制Android平台外部存储设备的后台进程。这些管理或控制包括SD卡的插拔事件检测/SD卡挂载/卸载/格式化等。记录一下Vold进程启动的源码分析,方便自己查阅。Android P这里很多都是网上的,我就走走流程。正文先看看...

王朔:上一秒痛苦,下一秒无聊

每天晚上我都睡得很晚,不是不困,而是不想睡,强迫自己不要睡。我似乎得了强迫症,我很忧郁。因为我总觉得一天什么都没干就这么过去了,实在不甘心!于是我就尽量延长这一天的时间。我真是个有志气的人,我很欣慰。志气是有了,可是找不到有志气的事情干,我很忧郁。幸好还有个电视,最妙的是还有个遥控器。遥控器真...

王小波:人为什么活着

银河,你好!我在家里给你写信。你问我人为什么活着,我哪能知道啊?我又不是牧师。释迦牟尼为了解决这个问题出了家,结果得到的结论是人活着为了涅,就是死。这简直近乎开玩笑了。不过活着总得死,这一点是不错的,我有时对这一点也很不满意呢。还有人活着有时候有点闷,这也是很不愉快的。过去我想,人活着都得为别人...

Android静态换肤-日夜主题切换之不继承Activity

前言记录一下,有Activity换肤之日夜主题无缝切换。一般来说,换肤分为静态换肤和动态换肤,Android的日夜模式可以看做静态换肤的一种。是以资源存放位置来说的,其实不是很严谨,但换肤的本质都是一样的。正文Android高版本都支持日夜模式切换,资源放在对应日夜目录,比如//有...

Source Insight 4.0安装

前言简单记录一下Source Insight 4.0的安装,方便自己使用。Source Insight确实是个好软件。正文下载下载Source Insight 4.0安装包://官网https://www.sourceinsight.com/download/下载程序破解补丁包:...