Fast copy subfolder from assets in Android? - android

I have seen many example in SO how to move files from assets. All of them copy files one by one, not as part of a sub folder, i.e. here.
Is it possible to move a sub folder to a target location? If I have more thousand small files then it seems faster, than treating each file independently.

Related

Android assets are too slow

I have Android app with Assets. They contains 20,000+ files, most of them are simple text or png files separated into different folders and subfolders.
Maximal size of 1 single file is 500kb, 90% of them are around 2kb.
Sample structure
Data
... subfolders with 20k+ files
StartData
.... FolderA
........ 5 files *.txt
.... FolderB
........ 5 files *.txt
.... a.xml
.... b.xml
The problem is load time of app. During app loading, I need to open around 20 files from StartData directory and read settings from them. They are in 2 xml files and based on info in xml I open additional data from two subfolders FolderA / FoldeB.
The speed is, however, very poor and app starts at least 3-4x times longer than without assets.
In former version I have zip in raw directory, that was deocmpressed upon first run to documents directory. First run was very slow, but other were fast. The problem with this solution was the install spedd, since deocmpresing took up to 5 minutes on older phones and it cannot die during that process. If so, app was damaged and data only partially decompressed, so I dropped this solution.
With my former approach, if unzipping finished correctly, cold app start was about 5s. Now, with assets, it takes up to 20s. Any solution?
I have disabled assets compression (I have only *.txt, *.png and *.xml files) in gradle
aaptOptions{
ignoreAssetsPattern ''
noCompress 'txt', 'png', 'xml'
cruncherEnabled = false
}
but the improvement is only small.
Also, I am using NDK (JNI) and AssetManager to load my assets in C++. Solution for assets opening in C++ is taken from this: http://www.50ply.com/blog/2013/01/19/loading-compressed-android-assets-with-file-pointer/
I am not surprised that discovering offsets to thousands of files in the assets folder is slow, and that the file system is better for such task. I would say that maybe the data structure should be rewritten. For example, you could put this information in a database.
I am sceptical about the funopen() trick. I mean, it works reliably, but I am concerned about the overhead. Much more efficient approaches to deal with non-compressed assets are through AAsset_getBuffer() or AAsset_openFileDescriptor(). Check an example of using file descriptor. Note that in the end, there will be one file descriptor for all thousands of your 'files'.
By the way, I don't think that Java performance with these direct access methods is worse than C. You could use zlib to read your assets from the APK file (which is in ZIP format itself), but I doubt you will do it faster than the AssetManager.

Difference between assets and res/raw [duplicate]

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.

Do working drafts of image files belong in the android project folder?

I was having a tough time finding an answer to this on google:
I have a few files that do not belong in the apk, such as Inkscape (svg) files that I rasterize, and Gimp (xcf) files that I use to export png files. I want to keep things organized in the most compact and logical way, but I do not want my working drafts to become part of the apk file.
Is the correct way to keep another folder for each project (outside of the project folder) for these working drafts of media files? Maybe I'm over-thinking this.. I just want to use best practices, and my current method (using an extra folder for every project) feels cumbersome.
Is there a way to ignore a folder within the actual android/eclipse project folder? I would love to know what other people are doing to stay organized.
Just place the files within your project in a folder that
isnt a source folder (src and gen)
isnt your assets or res folder
& They wont be included with your build (apk)

Android images in /assets or res/raw

If I wanted to put a bunch of images in a folder structure, e.g.. I’m building a beach app and each beach is displayed via my beach detail activity depending on the beach selected from my beach list. I then want to display five images from that particular beach. Each beach will have a folder with a name that corresponds to the _id of the beach and then five images in that folder, image1.jpg, image2.jpg… image5.jpg. should I put the folders and images in the /res/raw folder or the /assets folder for the best/easiest way to go.
Cheers,
Mike.
Assets will allow you to create subdirectories (group files in directories) note that they have no name restrictions however you can only access it via Assets Manager which contains list() for listing files under a given directory and open() for obtaining a file's InputStream.
resources instead, allow you to access the files in the folders but you cannot create subfolders, moreover you must place the files in the right place so bitmaps go in /res/drawable, layout xmls in /res/layout and so on. Resouces are easy to access for other parts of your code since they have an identifier.
Since you want to use the res/raw folder that means you cannot create a subfolder in it and that your images won't be compressed, so putting them without compress and considering they will be a lot of images then you app will be a bit heavy.
Here is two links that you might find helpfull: WiseAndroid and Providing Resources - Dev Guide
When adding images to your application you should place them in "res/drawable". That folder is for images that are not specific to any dpi level. For best results you should have three sizes of each image and place them in their respective dpi folders like "res/drawable-hdpi" for hi res images. This is a good section of the docs to read for resources and device compatibility.

Difference between /res and /assets directories

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.

Categories

Resources