I need to maintain some duplication into my Android App (in Android Studio) by having some resources in "res/values-iw/" and copy the exact content of that folder to a folder named "res/values-he/". The reason is explained here.
I saw that gradle has a copy function but I have no idea with what task it would be better to wire it (and I guess as doFirst)?
Also, is it possible to not have that copied folder in my original res folder as I don't really need to see it all the time beside the original one, for instance in /build/ folder for build time? That way the copied folder will always be an up-to-date copy of the original "/res/values-iw" folder.
Thanks in advance,
Alex
Instead of copying, you might want to set up symlinks instead. The symlinks should hopefully be preserved in source control, and it's better than having the build system muck around with duplicating source files. For large resources, though, like drawables, consider using aliases which should hopefully prevent duplication that will bloat your APK.
Instead of copying, would alias resources be better? http://developer.android.com/guide/topics/resources/providing-resources.html#AliasResources
They let you create references to a single resource in different contexts instead of copying them around. It should save space in your binary, too, which would be a big plus.
Related
Background
Some files of the app can only be stored in res/raw or assets folders.
Each of those folders work in a very similar way to the other. res/raw folder allows to access files easier, with all the other benefits of resource files, while assets folder allows to access them no matter the file name and structure (including folders and sub folders).
The main idea of loading files is about the same for both of them. You just have a choice of ease-of-use, depends on your needs.
The problem
I remember that a very long time ago, I've found some special behavior of both of those folders:
Each folder within the assets folder had a max number of files. I think it was about 500, but not sure. I've noticed this behavior a very long time ago,
Some said that files in the assets folder have a max size for files (example here). I never saw such a restriction. Not even on Android 2.3 at the time.
Some said (example here), and it's still believed even today (example here), that if you load a file from res/raw, it could take much more memory than if you took it from assets folder.
What I've tried
For #1, I never had to use more files anyway after the project I worked on, and at the time I worked on it, we simply split the files into more folders.
For #2 , as I wrote, I never noticed it anyway. I used much larger files sizes.
For #3, I tried to make a sample project that compares the memory usage between the 2 methods. I didn't notice any difference (memory usage or time to load) between the 2 methods. Especially not a major one. Sadly I have only one device (Nexus 5x), and it has quite a new Android version (8.1). It might be that starting from specific Android version there is no difference between the 2 methods. Another reason for this is that it's harder to measure memory usage on Java, because of the GC, and I've already noticed that on Android 8.x, memory works a bit differently than before (written about it here).
I tried to read about the differences and restrictions of the above, but all I've found are very old articles, so I think things might have changed ever since.
The questions
Actually it's just one question, but I'd like to split it in case the answer is complex:
Are there any major or unique limitations or differences between using res/raw and assets folders?
Does reading a file from the assets folder (by creating an input stream from it) really take less memory than using the res/raw? So much that even one of the most appreciated developers (here) decides to choose it, even nowadays?
Have the above restrictions existed up to specific Android versions, and then they became identical in terms of no restrictions whatsoever (except of course files naming for res/raw, but that's just how it works) ?
If so, from which Android version do they work about the same?
Are there any major or unique limitations or differences between using res/raw and assets folders?
Now, In android we don't have any restriction on max limit size for any file in assets or in raw.
Android Documentation:
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/ aren't given a resource ID, so
you can read them only using AssetManager.
Does reading a file from the assets folder (by creating an input stream from it) really take less memory than using the res/raw? So much that even one of the most appreciated developers (here) decides to choose it, even nowadays?
No, I have not found any differences between memory usage. It is one of biggest mess that android is having right now, Also we don't have any official documentation about their memory limitation.
Have the above restrictions existed up to specific Android versions, and then they became identical in terms of no restrictions whatsoever (except of course files naming for res/raw, but that's just how it works) ?
Before android 2.3 we had memory restriction for asset folder, which is 1 MB. Please refer link.
If so, from which Android version do they work about the same?
From android 2.3, We don't have any memory related restriction, which they launched in December, 2010
I know there are two well-known folders where one can put resources.
The first is the /assets folder, the documentation says:
Contains file that should be compiled into an .apk file as-is. 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.
The second is the /res folder, the documentation says:
Contains application resources, such as drawable files, layout files, and UI string. See Application Resources for more information.
Now i was wondering, there is a third option to create a resource folder "New > Folder > Java Resources Folder"
To me i looks like some part of the Android Plugin in IntelliJ because it has a little Android symbol in front of it .
Any ideas what the use of it could be? I couldn't find any documentation about it.
My first guess would be to use it in situations where you want to supply resources to a JVM Test.
In standard java world
Resources can be embedded directly in "your source tree" and used with Class's method getResource (see java documentation for a more precise description).
In android world
This practice is not recommanded (do not work at all, because such resources are removed from generated APK). You can still declare Java resources folders (see build.gradle :
sourceSets {
main {
resources.srcDirs = ['src/main/java/yourresourcesfolder']
}
}
And the result in the apk :
Conclusion
As resources's folder tree is removed,using java's resource folder become from my point of view, useless (in an android projet). Using android's asset folder is a better choice (also avoid resource's name conflict, but it's an another story :D )
This post is a bit old, but I want to bring an answer that explain one use case for the java resources directory on Android. If this folder exists in the options of a project it's because something can be done with it...
Enters the Service Loader, that helps to connect other services (aka libraries) into your main app, it can be used as a Gateway for your Android library to extend the functionality of a feature, exposing only the interfaces or abstract classes, with the Service Loader providing the implementation instead of your project having direct access to them.
Here is an example of how it's implemented. So, in summary the folder (META-INF/services) and files you have to create in order to use the Service Loader on an Android App, NEED to be inside this Java Resources Folder, otherwise your provider won't be able to see any implementation.
You can see it working in my sample here if you want to check it out: https://github.com/difereto-globant/test-library-feature/tree/1.0.9.
For the application I'm working on I was thinking to define few property files, something like: debug.properties, beta.properties, release.properties. These files mostly will contain urls to their corresponding environments. Depending of some flag I will set, the application will load the corresponding property file and read the values from there.
I was thinking to put these files in assets or raw resource folder, but after changing the extension from .apk to .zip of my application, I noticed that these file are accessible and readable.
If you had prior experience, what are the best practices for configuring different build environments in Android?
Is there a better place where I could put the properties files so they cannot be accessed?
I had the same need in my app and found the same problem you found: It's to easy to open the apk and edit the properties files.
The solution I chose was to put those environment-specific properties in some Java source files.
We have one Android project per environment. Each project is almost empty and refers to an Android Library that actually contains the app's code. Each Android project contains a Java file declaring its environment properties.
This seems counter-intuitive to use Java instead of properties file, but when fighting against piracy, all ways are good. The Java files can be obfuscated if you use Proguard. Even better, you can use Dexguard that can encrypt the strings in the Java source so that it will extremely hard to tamper the source and make the properties point elsewhere.
I have an app on the iPhone and need to port it to android. For this I would like to group screen related files like classes and xml per screen in one "screen group" per screen somehow, ideally also strings and other value files
if I use folders I can only group res files separately and src files separately.
what would be the best way?
Thanks very much!
EDIT:
If that should not be possible, how to best then solve this issue? Do you create a subfolder in the src and another in the res for each screen?
The way you group files for the iphone is not possible for an android project. Android has pre determined folders which hold specific files, if you break this structure, your building process will fail. Its not ideal but that just how it it.
When it comes to source java files, they follow the concept of packages which are basically folders. The 'src' folder is the part where you can create sub folders as you desire. If you are adamant about keeping the files related to a screen in one place, you should create the layouts with java code and not use layout xml files.
But using xml layout files make development much easier and faster. Consider that as the presentation and java files as the logic+data. So group java files as you want and leave xml files in the layout folder with easy to identify names.
android uses certain directory layout for project structures (i.e. convention over configuration). Basically you will want to put your XML layout files in res/layout directory. Please read http://developer.android.com/guide/developing/projects/index.html#ApplicationProjects for further information.
Unfortunately, there's no easy way to do this in Eclipse. You can't create custom directories in your Android app's /res directory, you can only use permitted dir-names. E.g. you can't have a /res/layout-myscreen1 and /res/layout-myscreen2. You also must put your resources in /res, and your code files in packages, so they're at separate places in your project.
You can use Working Sets to group related files together however, but they're quite painful to use IMHO. Check the eclipse docs and tutorials out on them.
I have an app, and stupid me decided to change a resource in the file from being filename.bmp to being a png, and released an upgrade with this, I removed the .bmp from the APK and added the PNG, and placed it on the marketplace.
Now, I have some users who are not able to run the app, it is failing with a file not found on the line referencing the resource name in the VIEW XML description.
Now, it is only some users, not all.. but its still infuriating, when a suer upgrades, are the old APK files removed? IE is the old .BMP file gone? I have been unable to fully replicated the problem on my equipment, but I am working off the theory that the .BMP and the .PNG file are now both in the resource/drawable directory and the XML inflate is just getting confused.
You will need to rename the files BMP and PNG to completely different names. This could cause confusion though.
I would recommend using one file type for all applications. And it may be that some user's are not experiencing the issue is because of screen density. Make sure all of the resources use the same naming convention and are availible for each screen size.
Rename the file to something completely different.
Have you tried cleaning your project?