Lets say I want to store a JavaScript file in my app for an Android WebView to use. Where should I put this file? My first though would be somewhere in the assets folder, but I am not too sure.
Check the following link and explanations:
http://www.41post.com/3985/programming/android-loading-files-from-the-assets-and-raw-folders
The Assets folder is an 'appendix' directory. The R class does not
generate IDs for the files placed there, so its less compatible with
some Android classes and methods. Also, it’s much slower to access a
file inside it, since you will need to get a handle to it based on a
String. There is also a 1MB size limit for files placed inside the
Assets folder, however some operations are more easily done by placing
files in this folder, like copying a database file to the system’s
memory. There’s no (easy) way to create an Android XML reference to
files inside the Assets folder.
There is also a raw folder you can even use that, but:
it’s important to highlight the main differences between the raw
folder and the Assets folder. Since raw is a subfolder of Resources
(res), Android will automatically generate an ID for any file located
inside it. This ID is then stored an the R class that will act as a
reference to a file, meaning it can be easily accessed from other
Android classes and methods and even in Android XML files.
Using the
automatically generated ID is the fastest way to have access to a file
in Android.
For completing the answer, you can easily use file:///android_asset/
Have a look at this question:
Android WebView Javascript from assets
Related
I know that files in the res directory are accessible from R.class while assets behaves like a file system, but I would like to know, in general, when it's best to use one and the other.
Can anyone help me in knowing the real differences between res and assets?
With resources, there's built-in support for providing alternatives for different languages, OS versions, screen orientations, etc., as described here. None of that is available with assets. Also, many parts of the API support the use of resource identifiers. Finally, the names of the resources are turned into constant field names that are checked at compile time, so there's less of an opportunity for mismatches between the code and the resources themselves. None of that applies to assets.
So why have an assets folder at all? If you want to compute the asset you want to use at run time, it's pretty easy. With resources, you would have to declare a list of all the resource IDs that might be used and compute an index into the the list. (This is kind of awkward and introduces opportunities for error if the set of resources changes in the development cycle.) (EDIT: you can retrieve a resource ID by name using getIdentifier, but this loses the benefits of compile-time checking.) Assets can also be organized into a folder hierarchy, which is not supported by resources. It's a different way of managing data. Although resources cover most of the cases, assets have their occasional use.
One other difference: resources defined in a library project are automatically imported to application projects that depend on the library. For assets, that doesn't happen; asset files must be present in the assets directory of the application project(s). [EDIT: With Android's new Gradle-based build system (used with Android Studio), this is no longer true. Asset directories for library projects are packaged into the .aar files, so assets defined in library projects are merged into application projects (so they do not have to be present in the application's /assets directory if they are in a referenced library).]
EDIT: Yet another difference arises if you want to package a custom font with your app. There are API calls to create a Typeface from a font file stored in the file system or in your app's assets/ directory. But there is no API to create a Typeface from a font file stored in the res/ directory (or from an InputStream, which would allow use of the res/ directory). [NOTE: With Android O (now available in alpha preview) you will be able to include custom fonts as resources. See the description here of this long-overdue feature. However, as long as your minimum API level is 25 or less, you'll have to stick with packaging custom fonts as assets rather than as resources.]
Both are pretty similar. The real main difference between the two is that in the res directory each file is given a pre-compiled ID which can be accessed easily through R.id.[res id]. This is useful to quickly and easily access images, sounds, icons...
The assets directory is more like a filesystem and provides more freedom to put any file you would like in there. You then can access each of the files in that system as you would when accessing any file in any file system through Java. This directory is good for things such as game details, dictionaries,...etc.
I know this is old, but just to make it clear, there is an explanation of each in the official android documentation:
from http://developer.android.com/tools/projects/index.html
assets/
This is empty. You can use it to store raw asset files. Files that you save here are compiled into an .apk file as-is, and the original filename is preserved. You can navigate this directory in the same way as a typical file system using URIs and read files as a stream of bytes using the AssetManager. For example, this is a good location for textures and game data.
res/raw/
For arbitrary raw asset files. Saving asset files here instead of in the assets/ directory only differs in the way that you access them. These files are processed by aapt and must be referenced from the application using a resource identifier in the R class. For example, this is a good place for media, such as MP3 or Ogg files.
Following are some key points :
Raw files Must have names that are valid Java identifiers , whereas
files in Assets Have no location and name restrictions. In other
words they can be grouped in whatever directories we wish
Raw files Are easy to refer to from Java as well as from xml (i.e
you can refer a file in raw from manifest or other xml file).
Saving asset files here instead of in the assets/ directory only
differs in the way that you access them as documented here
http://developer.android.com/tools/projects/index.html.
Resources defined in a library project are automatically imported to
application projects that depend on the library. For assets, that
doesn't happen; asset files must be present in the assets directory
of the application project(s)
The assets directory is more like a filesystem provides more freedom
to put any file you would like in there. You then can access each of
the files in that system as you would when accessing any file in any
file system through Java . like Game data files , Fonts , textures
etc.
Unlike Resources, Assets can can be organized into subfolders in the
assets directory However, the only thing you can do with an asset is
get an input stream. Thus, it does not make much sense to store your
strings or bitmaps in assets, but you can store custom-format data
such as input correction dictionaries or game maps.
Raw can give you a compile time check by generating your R.java file
however If you want to copy your database to private directory you
can use Assets which are made for streaming.
Conclusion
Android API includes a very comfortable Resources framework that is
also optimized for most typical use cases for various mobile apps.
You should master Resources and try to use them wherever possible.
However, if you need more flexibility for your special case, Assets
are there to give you a lower level API that allows organizing and
processing your resources with a higher degree of freedom.
If you need to refer them somewhere in the Java Code, you'd rahter put your files into the "res" directory.
And all files in the res folder will be indexed in the R file, which makes it much faster (and much easier!) to load them.
Use assets like a filesystem to dump any kind of files. And use res to store what it is made for, layouts, images, values.
Ted Hopp answered this quite nicely. I have been using res/raw for my opengl texture and shader files. I was thinking about moving them to an assets directory to provide a hierarchical organization.
This thread convinced me not to. First, because I like the use of a unique resource id. Second because it's very simple to use InputStream/openRawResource or BitmapFactory to read in the file. Third because it's very useful to be able to use in a portable library.
Assets provide a way to include arbitrary files like text, xml, fonts, music, and video in your application. If you try to include these files as "resources", Android will process them into its resource system and you will not be able to get the raw data. If you want to access data untouched, Assets are one way to do it.
I'm reusing my iphone resources, I have myriads of resources which have many subdirectories
I'm reusing much of native code aswell, I understand that to open assets we MUST provide relative path for ex if I have file name test1.png in assets/subdir1/subdir2/subdir3/test1.png
I have to mention whole of the relative path, As I already said I'm using much of native code so is there any way I can just access asset files using just the filename without full relative path "test1.png"? Or if this is not possible is there anyway we can logically structure our resources but the folder name actually doesn't exist physically.
I understand that to open assets we MUST provide relative path for ex if I have file name test1.png in assets/subdir1/subdir2/subdir3/test1.png I have to mention whole of the relative path
With AssetManager and methods like open(), you would not have the assets/ portion of the relative path. In your example, you would use open("subdir1/subdir2/subdir3/test1.png").
As I already said I'm using much of native code so is there any way I can just access asset files using just the filename without full relative path "test1.png"?
Of course not. You might have 10,000 files named test1.png in your entire assets/ tree -- we need to know which of those to open.
Moreover, AFAIK, native code has no access to assets.
Or if this is not possible is there anyway we can logically structure our resources but the folder name actually doesn't exist physically.
Whatever you physically put as your directory tree in assets/ in your project is what you will need to use when accessing them through AssetManager. If you do not want to have to deal with subdirectories with AssetManager, do not create subdirectories inside of assets/
I'm in the mid of my Android studies, and I just covered the Assets and Raw resources. I'm trying to understand the reason for using Raw resources vs. Assets.
They both provide with an uncompiled resource input stream.
It seems that Assets provide much more flexibility and functionality than Raw resources.
a. You can create folder structures under assets but not under raw
b. You can list all resources dynamically in the assets folder but not in the raw folder.
So, why would I use Raw resources in Android?
The main differences between the raw folder and the assets folder.
Since raw is a subfolder of Resources (res), Android will
automatically generate an ID for any file located inside it. This
ID is then stored in the R class that will act as a reference to
a file, meaning it can be easily accessed from other Android classes
and methods and even in Android XML files. Using the automatically
generated ID is the fastest way to have access to a file in Android.
The assets folder is an “appendix” directory. The R class does
not generate IDs for the files placed there, which is less compatible
with some Android classes and methods. File access in the assets folder is slower since you will need to get a handle to it
based on a String. However some operations are more easily done by
placing files in this folder, like copying a database file to the
system’s memory. There’s no (easy) way to create an Android XML
reference to files inside the Assets folder.
From the Android documentation, the raw/ directory is used for:
Arbitrary files to save in their raw form. To open these resources with a raw InputStream, call Resources.openRawResource() with the resource ID, which is R.raw.filename.
However, if you need access to original file names and file hierarchy, you might consider saving some resources in the assets/ directory (instead of res/raw/). Files in assets/ are not given a resource ID, so you can read them only using AssetManager.
In one line, the files in the raw/ directory are not compiled by the platform, are assigned a resource ID and cannot be grouped into sub-folders whereas if you want the otherwise use the assets/ directory.
Adding to the answers given above...
/res/strings,/res/layout,/res/xml files etc all gets compiled into binary format. But if you place files, including XML files, in the /res/raw/ directory instead, they don’t get compiled into binary format.
One big advantage of using assets over raw resources is the
file:///android_asset/ Uri prefix.This is useful for loading an
asset into a WebView. For example, for accessing an asset located in
assets/foo/index.html within your project, you can call
loadUrl("file:///android_asset/foo/index.html") loading that HTML
into the WebView.
I'm very new to android. I would like to create a package that upon install would put files in the app folder (/data/data/my.app/...) of the android file system.
I would like to do this, so I could access the files using standard java File methods (in order to reuse my own code), and not have to use the android resource accessing methods.
The only way I thought might achieve something in this direction, is to put the files in the /res folder, and copy them to the file system in runtime (on first run, for example). This has the disadvantage of having two copies of each file for no reason.
Another way could be to get my app to download these files from a server (saw this option in another answer as well). This is possible, but I would wish to avoid having to put up a file server for such a simple task...
To my understanding, DDMS will not help here, as it only allows me to access the folder manually, after the application is installed.
My question is: Is there a different way to achieve my original goal (accessing files using standard java methods)? If not, is there a cleaner way to put files on the file system?
Thanks!
There are 3 methods I can think of that avoid duplication:
As you mentioned using the res/raw folder. You can avoid duplication if your existing code uses can use InputStream instead of File and use Resources.openRawResource().
Use the assets folder and access the file using file using AssetManager.openNotAssetFd(). Again this would require the use of Streams not File class. This can get a bit messy if your file is compressed because assets are memory mapped.
If you code is really tied to File (doesn't just use it to open an InputStream). To avoid duplication you could download the file from the web on the first time it is run and store it into the external storage.
You can put your files on under /res/raw and then use:
Resources res = context.getResources();
InputStream in_s = res.openRawResource(R.raw.myfile);
Or if you want the File object
File f = new File(context.getResources().openRawResource(R.raw.myfile));
Then you can use normal Java apis to work with your files.
I know that files in the res directory are accessible from R.class while assets behaves like a file system, but I would like to know, in general, when it's best to use one and the other.
Can anyone help me in knowing the real differences between res and assets?
With resources, there's built-in support for providing alternatives for different languages, OS versions, screen orientations, etc., as described here. None of that is available with assets. Also, many parts of the API support the use of resource identifiers. Finally, the names of the resources are turned into constant field names that are checked at compile time, so there's less of an opportunity for mismatches between the code and the resources themselves. None of that applies to assets.
So why have an assets folder at all? If you want to compute the asset you want to use at run time, it's pretty easy. With resources, you would have to declare a list of all the resource IDs that might be used and compute an index into the the list. (This is kind of awkward and introduces opportunities for error if the set of resources changes in the development cycle.) (EDIT: you can retrieve a resource ID by name using getIdentifier, but this loses the benefits of compile-time checking.) Assets can also be organized into a folder hierarchy, which is not supported by resources. It's a different way of managing data. Although resources cover most of the cases, assets have their occasional use.
One other difference: resources defined in a library project are automatically imported to application projects that depend on the library. For assets, that doesn't happen; asset files must be present in the assets directory of the application project(s). [EDIT: With Android's new Gradle-based build system (used with Android Studio), this is no longer true. Asset directories for library projects are packaged into the .aar files, so assets defined in library projects are merged into application projects (so they do not have to be present in the application's /assets directory if they are in a referenced library).]
EDIT: Yet another difference arises if you want to package a custom font with your app. There are API calls to create a Typeface from a font file stored in the file system or in your app's assets/ directory. But there is no API to create a Typeface from a font file stored in the res/ directory (or from an InputStream, which would allow use of the res/ directory). [NOTE: With Android O (now available in alpha preview) you will be able to include custom fonts as resources. See the description here of this long-overdue feature. However, as long as your minimum API level is 25 or less, you'll have to stick with packaging custom fonts as assets rather than as resources.]
Both are pretty similar. The real main difference between the two is that in the res directory each file is given a pre-compiled ID which can be accessed easily through R.id.[res id]. This is useful to quickly and easily access images, sounds, icons...
The assets directory is more like a filesystem and provides more freedom to put any file you would like in there. You then can access each of the files in that system as you would when accessing any file in any file system through Java. This directory is good for things such as game details, dictionaries,...etc.
I know this is old, but just to make it clear, there is an explanation of each in the official android documentation:
from http://developer.android.com/tools/projects/index.html
assets/
This is empty. You can use it to store raw asset files. Files that you save here are compiled into an .apk file as-is, and the original filename is preserved. You can navigate this directory in the same way as a typical file system using URIs and read files as a stream of bytes using the AssetManager. For example, this is a good location for textures and game data.
res/raw/
For arbitrary raw asset files. Saving asset files here instead of in the assets/ directory only differs in the way that you access them. These files are processed by aapt and must be referenced from the application using a resource identifier in the R class. For example, this is a good place for media, such as MP3 or Ogg files.
Following are some key points :
Raw files Must have names that are valid Java identifiers , whereas
files in Assets Have no location and name restrictions. In other
words they can be grouped in whatever directories we wish
Raw files Are easy to refer to from Java as well as from xml (i.e
you can refer a file in raw from manifest or other xml file).
Saving asset files here instead of in the assets/ directory only
differs in the way that you access them as documented here
http://developer.android.com/tools/projects/index.html.
Resources defined in a library project are automatically imported to
application projects that depend on the library. For assets, that
doesn't happen; asset files must be present in the assets directory
of the application project(s)
The assets directory is more like a filesystem provides more freedom
to put any file you would like in there. You then can access each of
the files in that system as you would when accessing any file in any
file system through Java . like Game data files , Fonts , textures
etc.
Unlike Resources, Assets can can be organized into subfolders in the
assets directory However, the only thing you can do with an asset is
get an input stream. Thus, it does not make much sense to store your
strings or bitmaps in assets, but you can store custom-format data
such as input correction dictionaries or game maps.
Raw can give you a compile time check by generating your R.java file
however If you want to copy your database to private directory you
can use Assets which are made for streaming.
Conclusion
Android API includes a very comfortable Resources framework that is
also optimized for most typical use cases for various mobile apps.
You should master Resources and try to use them wherever possible.
However, if you need more flexibility for your special case, Assets
are there to give you a lower level API that allows organizing and
processing your resources with a higher degree of freedom.
If you need to refer them somewhere in the Java Code, you'd rahter put your files into the "res" directory.
And all files in the res folder will be indexed in the R file, which makes it much faster (and much easier!) to load them.
Use assets like a filesystem to dump any kind of files. And use res to store what it is made for, layouts, images, values.
Ted Hopp answered this quite nicely. I have been using res/raw for my opengl texture and shader files. I was thinking about moving them to an assets directory to provide a hierarchical organization.
This thread convinced me not to. First, because I like the use of a unique resource id. Second because it's very simple to use InputStream/openRawResource or BitmapFactory to read in the file. Third because it's very useful to be able to use in a portable library.
Assets provide a way to include arbitrary files like text, xml, fonts, music, and video in your application. If you try to include these files as "resources", Android will process them into its resource system and you will not be able to get the raw data. If you want to access data untouched, Assets are one way to do it.