Android-原始资源文件的使用详解_第1页
Android-原始资源文件的使用详解_第2页
Android-原始资源文件的使用详解_第3页
Android-原始资源文件的使用详解_第4页
Android-原始资源文件的使用详解_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Android 原始资源文件的使用详解背景知识介绍与其他平台的应用程 序一样,Android中的应用程序也会使用各种资源,比如图片,字串等,会把它们放入源码的相应文件夹下面,如/res/drawable, /res/xml, /res/values/, /res/raw, /res/layout和/assets。Android也支持并鼓励开发者把UI相关的布局和元素,用XML资源来实现。总结起来,Android中支持的资源有:颜色值/res/values 以resources为Root的XML文件,定义形式为value字串/res/values 以resources为Root的XML文件value图片/res/drawable 直接放入,支持9 Patch可自由拉伸图片的颜色/res/values 以resources为Root的XML文件,定义形式为value单位资源/res/values 以resources为Root的XML文件value菜单/res/menu 以menuo为root的XML文件布局/res/layout 这个就是GUI的布局和元素风格和主题 /res/values 以resources为Root的XML文件value 动画/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的文件类似于这样:代码如下:/* AUTO-GENERATED FILE. DO NOT MODIFY.* This class was automatically generated by the* aapt tool from the resource data it found. It* should not be modified by hand.*/package com.android.explorer;public final class R public static final class attr public static final class drawable public static final int icon=0x7f020000; public static final class id public static final int action=0x7f060004; public static final int description_panel=0x7f060001; public static final int fileinfo=0x7f060003; public static final int filename=0x7f060002; public static final int linearlayout_test_1=0x7f060005; public static final int linearlayout_test_2=0x7f060006; public static final int linearlayout_test_3=0x7f060007; public static final int thumbnail=0x7f060000; public static final class layout public static final int fileant_list_item=0x7f030000; public static final int linearlayout_test=0x7f030001; public static final class raw public static final int androidmanifest=0x7f040000; public static final class string public static final int app_name=0x7f050001; public static final int hello=0x7f050000; 从这个R.java就可看出在/res中定义或提供资源时的注意事项:1. 同一个类型,或同一文件夹下面的资源不可以使用相同的文件名,也就是说不能用文件扩展名来区别不同的文件,因为R.java中只保留资源的文件名而不管扩 展名,所以如果有二个图片一个是icon.png另一个是icon.jpg,那么在R.java中只会有一个R.drawable.icon。另外一个则 会无法访问到。2. 资源文件的名字必须符合Java变量的命名规则,且不能有大写,只能是a-z0-9._,否则会有编译错误,因为R.java中的变量Id要 与资源中的文件一一对应,也就是说用资源文件名来作为Id的变量名,所以一定要符合Java变量的命名规则,另外它还不能有大写。3. 除了SDK支持的folder外,不能再有子Folder,虽不会有编译错误,但是子Folder会被完全忽略,如在/res/layout下在建一个子 Folder activity(/res/layout/acitivity/, 那么你在生成的R.java中是看不到activity和其内的内容的。4. 对于资源文件的大小有限制,最好不要让单个文件大于1M,这是SDK文档说明的限制,但具体的我没有进行试验(据说2.2版本以后的可支持到10M,不知道是真的还是假的)5. 所有/res下面的资源都能通过Resources()并提供Id来访问。使用原始资源对于大多数资源在编译时会对文件内容进行特殊处理,以方便Apk在运行时访问。 如果想要运行时使用未经处理的原始资源,可以把资源文件放在/res/raw和/assets目录下面,这二个目录的主要区别在于:1. /res/raw中的文件会被映射到R.java中虽然/res/raw中的文件不会被aapt处理成为二进制,但是它的文件还是被映射到R.java中,以方便以资源Id形式来访问2. 子目录结构如上面所述,/res/raw中虽可以有子目录,但是在程序运行时是无法访问到的,因为/res下面的所有非法子目录在R.java中都是看不到的。而且这些子目录和文件都不会被编译进入Apk中,解压Apk文件后也看不到/res/raw下面去找了。而/assets是允许有子目录的,并且完全可以访问到,并且会被打包进Apk,解压Apk后,这些文件仍然存在并且与源码包中的一样。3. 访问方式/res/raw下面的文件(子文件夹是访问不到的了)的访问方式是通过Resources,并且必须提供资源的Id代码如下:InputStream in = Context.getResources().openRawResource(R.id.filename);所以为什么子文件夹无法访问,因为没有Id啊。而/assets则要通过AssetManager来访问。下面着重讲解如何访问/assets下面的资源文件。通过AssetManager来访问/assets下面的原始资源文件1. 文件的读取方式用AssetManager.open(String filename)来打开一个文件,这是一组重载方法,还有其他参数可以设置打开模式等,可以参考文档这里的filename是相对于/assets的路径,比如:复制代码 代码如下:InputStream in = mAssetManager.open(hello.txt); / /assets/hello.txtInputStream in2 = mAssetManager.open(config/ui.txt); / /assets/config/ui.txt2. 文件夹处理 - 如何遍历/assets可以看到如果想要访问/assets下面的文件,必须要知道文件名和相对于/assets的路径。所以,如果你不预先知道其下面有什么的时候又该如何处理 呢?那就需要列出它下面所有的文件,然后再选取我们需要的,所以新的问题来了,如何列出/assets下面所有的文件呢?AssetManager提供了一个列出/assets下某个路径下面的方法:代码如下:public finalStringlist(String path)Since: API Level 1Return a String array of all the assets at the given path.Parameterspath A relative path within the assets, i.e., docs/home.html. ReturnsString Array of strings, one for each asset. These file names are relative to path. You can open the file by concatenating path and a name in the returned string (via File) and passing that to open().其实这个文档写的有问题,list()是列出一个文件夹下面的文件,所以应该传入一个文件夹路径而非文档中的docs/home.html。还有一个最大的问题就是如何列出根目录/assets下面的内容,因为只有知道了根目录下面的东西,才能去相对的子目录去找东西,所以这是个必须最先解决的问题。其实文档没有说的太明白这个方法到底如何使用,也就是说这个String参数到底如何传。猜想着根目录为/assets,所以尝试了以下:复制代码 代码如下:mAssetManager.list(.); / returns array size is 0mAssetManager.list(/); / returns AndroidManifest.xml, META-INF, assets, classes.dex, res, resources.arsc / dont worry, u can see these files though, no way to access themmAssetManager.list(/assets); / returns array size is 0/Google了一下,找到了正解:mAssetManager.list(); / returns stuff in /assets然后再根据所列出的子项去递归遍历子文件,直到找到所有的文件为止。常见的问题1. 资源文件只能以InputStream方式来获取如 果想操作文件怎么办,如果想要用文件Uri怎么办。光靠API当然不行,它只给你InputStream,也就是说它是只读的。可行的办法就是读取文件然 后写入一个临时文件中,再对临时文件进行想要的文件操作。可以在内部存储或外部存储上面用Context提供的接口来创建文件,详细的请参考。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 .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 mEntriesposition; 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 = mEntriesposition; 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

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论