291

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?

peter-b
  • 4,073
  • 6
  • 31
  • 43
Cris
  • 12,124
  • 27
  • 92
  • 159

8 Answers8

307

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.]

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • 2
    `res` stands for resources, then what does `assets` stands for ?? – Vivek Warde Jun 13 '14 at 05:34
  • 44
    @vwvwvwvwvwvwvwvwvw - Um...it doesn't "stand for" anything; it simply means "assets" (as in the plural of the English word **asset**: _a useful or valuable thing_). – Ted Hopp Jun 13 '14 at 17:12
  • 1
    Is it possible to write to the files in the `raw/` directory? – Prince May 13 '15 at 07:38
  • 7
    @Prince - No. Everything in the `/res` and '/assets' directories is read-only, since they are packaged up in the .apk file. – Ted Hopp May 13 '15 at 15:08
  • can we put apk file in assets folder and when user click on that ui install that apk? – Vivek Mishra Sep 01 '16 at 06:50
  • @VivekMishra - Quite possibly. You can install apk files programmatically, as described in [this thread](http://stackoverflow.com/questions/4604239/install-application-programmatically-on-android). The solutions there are for an apk file stored in the device's file system. You can try the same approach using a URI for a file stored in your app's assets folder; see [this thread](http://stackoverflow.com/questions/4820816/how-to-get-uri-from-an-asset-file) for how to build such a URI. At worst, you would have to copy the apk from the assets folder to the file system and use the first method. – Ted Hopp Sep 01 '16 at 15:43
  • how about performance wise? Using for example image from assets vs using from res into recyclerview ? – Yaroslav Dukal Nov 28 '17 at 02:30
  • @MaksimKniazev - For that use case, my guess is that loading images from assets is going to be less efficient than loading them from res. RecyclerView likes to work with Drawable objects, and you don't get those by loading images from assets; you'd have to wrap the resulting Bitmap with a BitmapDrawable in code. In general, I think (although I could be mistaken about this) that loading from res and loading from assets use the same underlying loading mechanism, so any performance differences are going to be second-order at best. – Ted Hopp Nov 28 '17 at 02:45
72

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.

starball
  • 20,030
  • 7
  • 43
  • 238
DRiFTy
  • 11,269
  • 11
  • 61
  • 77
42

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.

Armand
  • 23,463
  • 20
  • 90
  • 119
AntonyMCs
  • 699
  • 6
  • 7
  • 5
    I think this actually confuses the issue -- both textures and ogg files are big globs of data you feed to a userland API (openGL/MediaPlayer)... why would they discriminate here? –  Sep 27 '15 at 18:45
14

Following are some key points :

  1. 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
  2. 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).
  3. 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.
  4. 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)
  5. 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.
  6. 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.
  7. 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

  1. 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.
  2. 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.
Shubhang Malviya
  • 1,525
  • 11
  • 17
  • 1
    According to the accepted answer, point 4 is no longer true, for projects using the Gradle build system; assets from libraries are bundled into the application project's asset collection. – Venryx Feb 28 '17 at 11:31
4

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.

L.Butz
  • 2,466
  • 25
  • 44
1

Use assets like a filesystem to dump any kind of files. And use res to store what it is made for, layouts, images, values.

Bajji
  • 2,243
  • 2
  • 22
  • 35
0

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.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
dturvene
  • 2,284
  • 1
  • 20
  • 18
  • 1
    Point 2, of InputStreams and BitmapFactory support, is true for both resources and assets (see here: http://stackoverflow.com/a/8501428/2441655). Point 3 no longer applies. (see accepted answer) – Venryx Feb 28 '17 at 11:34
  • Point one is also questionable, as, in assets, we cannot provide same filename as well. The benefit of res/raw is more to ensure the filename is always correct. – Elye Aug 09 '20 at 12:06
-6

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.

KCRaju
  • 544
  • 3
  • 7
  • 21
  • 6
    This is incorrect. If you put data in `res/raw`, you can get at the raw data using [`openRawResource(resourceName)`](http://developer.android.com/reference/android/content/res/Resources.html#openRawResource%28int%29). – Ted Hopp Jul 21 '13 at 01:45
  • I have opengles texture and shader files in a library. I *MUST* use res/raw to store them. I use InputStream and BitmapFactory to read them. I'll add this as an independent comment. – dturvene Apr 03 '14 at 17:01
  • 2
    Seems copied from Xamarin Microsoft docs. Give your source when copying text. https://learn.microsoft.com/en-us/xamarin/android/app-fundamentals/resources-in-android/android-assets?tabs=vswin – Sjoerd Pottuit Oct 02 '18 at 11:00