Android 原始资源文件的使用详解


背景知识介绍
与其他平台的应用程序一样,Android中的应用程序也会使用各种资源,比如图片,字串等,会把它们放入源码的相应文件夹下面,如/res/drawable, /res/xml, /res/values/, /res/raw, /res/layout和/assets。Android也支持并鼓励开发者把UI相关的布局和元素,用XML资源来实现。总结起来,Android中支持的资源有:
•颜色值                 /res/values               以resources为Root的XML文件,定义形式为<color name>value</color>
•字串                    /res/values                以resources为Root的XML文件<string name>value</string>
•图片                    /res/drawable            直接放入,支持9 Patch可自由拉伸
•图片的颜色        /res/values               以resources为Root的XML文件,定义形式为<drawable name>value</drawable>
•单位资源            /res/values               以resources为Root的XML文件<dimen name>value</dimen>
•菜单                    /res/menu                以menuo为root的XML文件
•布局                    /res/layout                 这个就是GUI的布局和元素
•风格和主题        /res/values                以resources为Root的XML文件<style name>value</style>
•动画                    /res/anim                 有二种:一个是帧动画(frame animation),也就是连续变换图片以animation-list为Root的XML文件;另外一种就是补间动画(tweened animation),它对应于API中的Animation和AnimationSet,有translate、scale、rotate、alpha四种,以set为root来定义,这个set就相当于AnimationSet
再说下目录:
•/res/anim                  用于存放动画
•/res/drawable          存放图片,或等同于图片的资源如shape,或selector
•/res/menu                 存放Menu
•/res/values               存放修饰性资源:字串,颜色,单位,风格和主题
•/res/layout                存放UI布局和元素
•/res/raw                    存放运行时想使用的原始文件
•/assets                     存放运行时想使用的原始文件
除了原始文件目录/res/raw和/assets以外,其他的资源在编译的时候都会被第三方软件aapt进行处理,一个是把图片和XML文件进行处理,例如把XML编译成为二进制形式;另外处理的目的就是生成R.java文件,这个文件是访问资源时必须要用到的。
/res目录下面的所有文件都会映射到R.java文件中,以整数Id的形式被标识,相同类型的资源被一个内部类来封装,一个R.java的文件类似于这样:
<Android开发笔记之: 数据存储方式详解>。Java牛人可能想要用Java本身的能力:
复制代码 代码如下:

File File.createTempFile(String prefix, String suffix); 
File File.createTempFile(String prefix, String suffix, File path); 

这也是可以的,但要考虑Android系统的特性,也就是说所写的路径是否有权限。比如对于第一个方法,用的是"java.io.tmpdir"这个在Android当中就是"/sdcard",所以当没有SD卡时这个方法必抛异常。
2. 所有资源文件都是只读的,运行时无法更改
因为,程序运行时是把Apk动态解析加载到内存中,也就是说,Apk是不会有变化的,它是无法被改变的。
3. 所有的资源文件夹/res和/assets也都是只读的,不可写入
如上面所说,Apk是在编译后是无法再改变的了。
实例
下面是一个实例,可以递归式的遍历/assets下面所有的文件夹和文件
复制代码 代码如下:

package com.android.explorer;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.MimeTypeMap;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
/*
 * Explore all stuff in /assets and perform actions specified by users.
 */
public class FileAntActivity extends ListActivity {
    private static final String TAG = "FileAntActivity";
    private AssetManager mAssetManager;
    private static final String EXTRA_CURRENT_DIRECTORY = "current_directory";
    private static final String EXTRA_PARENT = "parent_directory";
    public static final String FILEANT_VIEW = "com.android.fileant.VIEW";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = getIntent();
        String current = null;
        String parent = null;
        if (intent != null && intent.hasExtra(EXTRA_CURRENT_DIRECTORY)) {
            current = intent.getStringExtra(EXTRA_CURRENT_DIRECTORY);
        }
        if (current == null) {
            current = "";
        }
        if (intent != null && intent.hasExtra(EXTRA_PARENT)) {
            parent = intent.getStringExtra(EXTRA_PARENT);
        }
        if (parent == null) {
            parent = "";
        }
        mAssetManager = getAssets();
        if (TextUtils.isEmpty(parent)) {
            setTitle("/assets");
        } else {
            setTitle(parent);
        }
        try {
            // List all the stuff in /assets
            if (!TextUtils.isEmpty(parent)) {
                current = parent + File.separator + current;
            }
            Log.e(TAG, "current: '" + current + "'");
            String[] stuff = mAssetManager.list(current);
            setListAdapter(new FileAntAdapter(this, stuff, current));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private class FileAntAdapter extends BaseAdapter {
        private Context mContext;
        private String[] mEntries;
        private String mParentDirectory;

        public FileAntAdapter(Context context, String[] data, String parent) {
            mContext = context;
            this.mEntries = data;
            mParentDirectory = parent;
        }

        public int getCount() {
            return mEntries.length;
        }
        public Object getItem(int position) {
            return mEntries[position];
        }
        public long getItemId(int position) {
            return (long) position;
        }
        public View getView(final int position, View item, ViewGroup parent) {
            LayoutInflater factory = LayoutInflater.from(mContext);
            if (item == null) {
                item = factory.inflate(R.layout.fileant_list_item, null);
                TextView filename = (TextView) item.findViewById(R.id.filename);
                TextView fileinfo = (TextView) item.findViewById(R.id.fileinfo);
                ImageButton action = (ImageButton) item.findViewById(R.id.action);
                final String entry = mEntries[position];
                filename.setText(entry);
                boolean isDir = isDirectory(entry);
                if (isDir) {
                    fileinfo.setText("Click to view folder");
                    action.setVisibility(View.GONE);
                    item.setClickable(true);
                    item.setOnClickListener(new View.OnClickListener() {
                        public void onClick(View view) {
                            Intent intent = new Intent(FILEANT_VIEW);
                            intent.putExtra(EXTRA_CURRENT_DIRECTORY, entry);
                            intent.putExtra(EXTRA_PARENT, mParentDirectory);
                            startActivity(intent);
                        }
                    });
                } else {
                    final String type =
                        MimeTypeMap.getSingleton().getMimeTypeFromExtension(getExtension(entry));
                    fileinfo.setText(type);
                    item.setClickable(false);
                    action.setOnClickListener(new View.OnClickListener() {
                        public void onClick(View view) {
                             String filepath = entry;
                             if (!TextUtils.isEmpty(mParentDirectory)) {
                                 filepath = mParentDirectory + File.separator + filepath;
                             }
                             BufferedInputStream in = new BufferedInputStream(mManager.open(filepath));
                             // Do whatever you like with this input stream
                        }
                    });
                }
            }
            return item;
        }
     }

    /**
     * Test Whether an entry is a file or directory based on the rule:
     * File: has extension *.*, or starts with ".", which is a hidden files in Unix/Linux,
     * otherwise, it is a directory
     * @param filename
     * @return
     */
    private boolean isDirectory(String filename) {
        return !(filename.startsWith(".") || (filename.lastIndexOf(".") != -1));
    }

    private String getExtension(String filename) {
        int index = filename.lastIndexOf(".");
        if (index == -1) {
            return "";
        }
        return filename.substring(index + 1, filename.length()).toLowerCase();
    }
}


« 
» 

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3