Learning Android Development

Assets or Resource Raw folder of Android?

Guide to put your raw asset in the right location

Elye
Elye
Aug 9 · 4 min read
Image for post
Image for post
Picture by geralt on Pixabay

ave you ever need to store your raw asset file (e.g. JSON, Text, mp3, pdf, etc) in your app? Where do you store them?

There are two possible locations: 1) assets, 2) res/raw folder.

Image for post
Image for post

Both of them seems to be the same, as they can read the file and generate InputStream as below

// From assets
assets
.open(assetPathFilename)
// From res/raw
resources
.openRawResource(resourceRawFilename)

But when to put where?

Below is some guidance that might be helpful to decide

1. Flexible filename: assets is better

assets folder

You can name your filename any way that you like here, like having a space (e.g. some file name), or having capital letters (e.g. someFileName).

res/raw folder

Your name here is restricted to below

File-based resource names must contain only lowercase a-z, 0-9, or underscore

Conclusion

Filename in the res/raw is more restrictive than in the assets folder.

2. Store in subdirectory: assets is possible

assets folder

If you like to categories your files into subfolders, you can do it in assets

Image for post
Image for post

res/raw folder

Files can only be in the root folder.

Conclusion

Files in the assets can be arranged in subfolders, but not in res/raw

3. List filenames at runtime: assets is possible

assets folder

If you like to list all your files in the assets folder, you have used list function and provide the folder name (or "" on the root folder).

assets.list(FOLDER_NAME)?.forEach { 
println(it)
}

res/raw folder

This is not possible yet. You have to know the filename during development, and not runtime.

Conclusion

In assets, we can read the filename during runtime, list them, and use them dynamically. In res/raw, we need to code them ready, perhaps in the string resources file.

4. Compile-time checking: res/raw is possible

assets folder

Here, the way you read it into InputStream is

assets.open("filename")

If filename doesn’t exist, then we need to catch it.

res/raw folder

Here, the way you read it into InputStream is

resources.openRawResource(R.raw.filename)

Additional note: we can also get the Resource ID using string as below, but that will basically remove the advnatage of the resource name check at runtime.

// Reflection approach (HACKY WAY)
private fun getFileResId(resName: String): Int {
return try {
val res: Class<*> = R.raw::class.java
val idField = res.getField(resName)
idField.getInt(idField)
} catch (exception: Exception) {
-1
}
}
// getIdentifier appraoch (BETTER WAY)
private fun getFileResId(resName: String): Int {
// return 0 when no resources found
return resources.getIdentifier(resName, "raw", packageName)
}

Conclusion

Putting file in the res/raw folder will provide ensure the correct file-name during compile time check.

5. Alternative for different configuration: res/raw is possible

assets folder

If you want to have different file read for different configuration (the language of the device, Android API, Screen Orientation), you need to manually detect the configuration and read the respective file.

res/raw folder

Like any folders in the res, the res/raw folder can be named to represent its possible alternative resources for retrieval, hence no extra work for developers other than ensuring the file is in the right folder.

A simple example below, show that different files are listed for API 29 and above.

Image for post
Image for post

More possible options can be found in the Android Documentation.

Conclusion

In res/raw, Android provides us the simpler ability to access different files based on the configuration of the device it is installed upon. Manual work required when we have it in the assets folder.

6. Filename accessible from XML: res/raw is possible

assets folder

No simple way we can get an XML file (e.g. AndroidManifest.xml) to point to the file in the assets folder.

res/raw folder

In any XML files (like in Java), we can access the file in res/raw using @raw/filename easily.

Conclusion

If you need to access your file in any XML, put it in the res/raw folder.

TL;DR;

Image for post
Image for post

To get a simple project accessing both, check out here. Credit goes to this StackOverflow.

Mobile App Development Publication

Sharing Mobile App Development and Learning

Elye

Written by

Elye

Passionate about learning, and sharing mobile development and others https://twitter.com/elye_project https://www.facebook.com/elye.proj

Mobile App Development Publication

Sharing iOS, Android and relevant Mobile App Development Technology and Learning

Elye

Written by

Elye

Passionate about learning, and sharing mobile development and others https://twitter.com/elye_project https://www.facebook.com/elye.proj

Mobile App Development Publication

Sharing iOS, Android and relevant Mobile App Development Technology and Learning

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store