Usage of the original Android resource file

Source: Internet
Author: User

Background
Like applications on other platforms, apps in Android also use various resources, slice, and strings and place them in the corresponding folders of the source code, such as/res/drawable, /res/xml,/res/values/,/res/raw,/res/layout and/assets. Android also supports and encourages developers to use XML resources to implement UI-related layout and elements. To sum up, Android supports the following resources:
• The color value/res/values is defined as <color name> value </color> in the XML file with resources as Root.
• String/res/values: XML file with resources as Root <string name> value </string>
• Images/res/drawable can be placed directly, and 9 patches can be stretched freely
• The image color/res/values uses the resources Root XML file and is defined as <drawable name> value </drawable>
• XML file <dimen name> value </dimen> with resources as the Root unit resource/res/values
• Menus/res/menus use menuo as the root XML file
• Layout/res/layout: GUI layout and elements
• Style and subject/res/values XML file with resources as Root <style name> value </style>
• There are two types of animation/res/anim: one is frame animation, that is, the XML file that continuously transforms the image with the animation-list as the Root; the other is tweened animation, which corresponds to the Animation and AnimationSet In the API. It can be defined as "translate", "scale", "rotate", and "alpha" based on "set as root, this set is equivalent to the AnimationSet.
In addition, the following directory:
•/Res/anim used to store animations
•/Res/drawable stores images, or resources equivalent to images such as shape or selector
•/Res/menu stores the Menu
•/Res/values: String, color, unit, style, and topic
•/Res/layout stores UI layout and elements
•/Res/raw stores the original files you want to use during running.
•/Assets stores the original files you want to use during running.
Except for the original file directories/res/raw and/assets, other resources will be processed by the third-party software aapt during compilation. One is to process images and XML files, for example, compile XML into a binary format. In addition, the purpose of processing is to generate R. java file, which is required to access resources.
All files under the/res directory will be mapped to R. in the java file, it is identified as an integer Id. Resources of the same type are encapsulated by an internal class, a R. java files are similar to the following: Copy codeThe Code is as follows:/* AUTO-generated file. do not modify.
*
* This class was automatically generated by
* Aapt tool from the resource data it found. It
* Shoshould 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;
}
}

From this R. java, you can see the precautions when defining or providing resources in/res:
1. For example, only one R. drawable. icon is available in R. java. The other one cannot be accessed.
2. the name of the resource file must comply with the naming rules of Java variables, and cannot contain uppercase letters. It can only be '[a-z] [0-9]. _ ', otherwise there will be a compilation error because R. the variable Id in java must correspond one to one with the file in the resource. That is to say, the variable name using the resource file name as the Id must comply with the naming rules of Java variables. In addition, the variable Id cannot be capitalized.
3. in addition to the folder supported by the SDK, sub-Folder cannot be added. Although there are no compilation errors, sub-Folder will be completely ignored, for example, if you create a Folder activity (/res/layout/acitivity/In/res/layout, then you are generating the R. java does not see the activity and its content.
4. there is a limit on the size of resource files. It is best not to make a single file larger than 1 MB. This is the limit described in the SDK documentation, but I did not conduct the test (it is said that the version later than 2.2 can support up to 10 M, I do not know whether it is true or false)
5. All Resources under/res can be accessed through Resources () and the Id is provided.
Use Original Resources
Most resources perform special processing on the file content during compilation to facilitate Apk access at runtime. If you want to use unprocessed raw resources during running, you can put the resource files under the/res/raw and/assets directories. The main differences between these two directories are:
1. files in/res/raw will be mapped to R. java.
Although files in/res/raw are not processed as binary by aapt, their files are still mapped to R. java to facilitate access by resource Id.
2. subdirectory Structure
As described above, although/res/raw can have sub-directories, it cannot be accessed when the program is running, because all the invalid sub-directories under/res are in R. java is invisible. These subdirectories and files will not be compiled into the Apk. After extracting the Apk file, you cannot find them under/res/raw.
The/assets allow sub-directories that are completely accessible and packaged into the Apk. After the Apk is decompressed, these files still exist and are the same as those in the source package.
3. Access Method
Files under/res/raw (subfolders cannot be accessed) are accessed through Resources and the resource Id must be provided.Copy codeThe Code is as follows: InputStream in = Context. getResources (). openRawResource (R. id. filename );

So why can't the subfolders be accessed because there is no Id.
And/assets are accessed through AssetManager. The following describes how to access the resource files under/assets.
Use AssetManager to access the original resource files under/assets
1. File Reading Method
Use AssetManager. open (String filename) to open a file. This is a set of overload methods, and other parameters can be set to open mode. For details, refer to the documentation.
Here, filename is the path relative to/assets, for example:Copy codeThe Code is as follows: InputStream in = mAssetManager. open ("hello.txt"); // '/assets/hello.txt'
InputStream in2 = mAssetManager. open ("config/ui.txt"); // '/assets/config/ui.txt'

2. Folder processing --- How to traverse/assets
You can see that if you want to access the files under/assets, you must know the file name and the path relative to/assets. So what should you do if you don't know what's under it in advance? Then we need to list all the files under it and then select what we need. So the new question is, how can we list all the files under/assets?
AssetManager provides a method to list a path under/assets:Copy codeThe Code is as follows: public finalString [] list (String path)
Since: API Level 1
Return a String array of all the assets at the given path.
Parameters
Path A relative path within the assets, I. e., "docs/home.html ".
Returns
• String [] 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 ().

In fact, there is a problem with writing this document. list () is to list the files under a folder, so you should input a folder path instead of "docs/home.html" in the document ".
Another major problem is how to list the content under the root directory/assets, because only the content under the root directory can be searched through the corresponding sub-directories, therefore, this is the first problem to be solved.
In fact, the document does not explain how to use this method, that is, how to transmit this String parameter. I guess the root directory is/assets, so I tried the following:Copy codeThe Code is as follows: mAssetManager. list ("."); // returns array size is 0
MAssetManager. list ("/"); // returns [AndroidManifest. xml, META-INF, assets, classes. dex, res, resources. arsc] // don't worry, u can see these files though, no way to access them
MAssetManager. list ("/assets"); // returns array size is 0
// Google:
MAssetManager. list (""); // returns stuff in/assets

Then, recursively traverse the sub-files based on the listed sub-items until all files are found.
FAQs
1. resource files can only be obtained in InputStream Mode
What should I do if I want to operate on a file? What should I do if I want to use a file Uri. API alone is certainly not good. It only gives you InputStream, that is, it is read-only. A feasible method is to read the file, write it into a temporary file, and then perform the desired file operation on the temporary file. You can use the interfaces provided by Context to create files in internal or external storage. For more information, see<Android Development Notes: Data Storage Methods>. Java experts may want to use Java's own capabilities:Copy codeThe Code is as follows: File. createTempFile (String prefix, String suffix );
File. createTempFile (String prefix, String suffix, File path );

This is also possible, but we need to consider the features of the Android system, that is, whether the written path has permissions. For example, the first method uses "java. io. tmpdir", which is "/sdcard" in Android. Therefore, if no SD card is available, this method will throw an exception.
2. All resource files are read-only and cannot be changed during running.
Because, when running the program, the Apk is dynamically parsed and loaded into the memory. That is to say, the Apk will not change, and it cannot be changed.
3. All resource folders/res and/assets are read-only., Cannot be written
As mentioned above, the Apk cannot be changed after compilation.
Instance
The following is an example of recursively traversing all the folders and files under/assets.Copy codeThe Code is as follows: 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;
/*
* Need e 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 ();
}
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.