I am getting duplicate files in my source code:
This happens quite often with Android Studio and it happens will all types of files, not just gradle files. It typically happens when I checkout a new branch or swith branches.
What is causing this and how can I prevent it?
As a note, this question was originally posted with image files, thus the image answers. However, this is not limited to image files and I understand why there are multiple image files for different screen densities. I have updated to reflect that there are other files being duplicated.
Do you have a Mac, and is your project stored in your "Documents" directory?
Filenames that include " 2" are generated by iCloud when it can't reconcile two versions of a file. E.g. if you have two computers, and both of them share their "Documents" directories via iCloud, and a file were to be changed simultaneously on both computers, iCloud would wind up creating e.g. a build 2.gradle file.
I found this was happening to me, even though I'm only using one computer to do my work. I suspect that Android Studio may be interacting with iCloud directly, not realizing that it's working on files that are already backed up on iCloud. (See Android Studio generating hundreds of duplicate " 2" files).
I seem to have fixed it by moving my project directory out of Documents. At any rate, I haven't had a problem since I did that.
(Credit to Mike M. for noticing the similarity between our problems.)
Since different devices support different screen densities, all non-vector image drawables should have an image asset for each type of density. So, from a development standpoint, you're using the same Drawable but the app will use the correct image size based on the screen density of the device the app is installed in. I suggest you take a look at this article for more information.
It's ok. Follow the every folder. Folder name is different according to possible phone size Different phone size is different, that’s why they support different size images.
Related
Is there a way to share common backup/system files with multiple Android Emulators?
I have a lot of emulator copies for testing purposes (same base emulator just has slightly different file contents (example different apps installed). Each emulator has the same base files like userdata-qemu.img for example its a 6GB+ file that seems to just be use in the case where I restore an emulators state. It is super wasteful resource wise to have one of these files in every emulator instance since they are all duplicates ( I plan to have hundreds of unique/but almost identical emulators and I need to run multiple at the same time. The related file that is different and unique to each emulator is useredata-qemu.img.qcow2. I tried moving the common file like useredata-qemu.img to its own shared directory and then telling the emulator with command line options where the file is (-data or -data-dir for example) but that doesnt seem to work. Does anyone know a way to achieve this or something like this?
I've been working with Android for quite some time, yet I have never seen any good explanations for this issue.
I'm working on an app with a number of artwork and sound files. Many of these files are temporary, are base files that future work will evolve from, or are large versions that will be split into multiple files later. I want to keep them under version control with this project, and I'd like to keep everything in the same place on my hard drive.
But I don't want these "work" files to end up in my apk. They are often huge and have nothing to do with the final product.
For most of my life (ie, before Android), I would simply have a subdirectory within my project called art_work_files. And this directory would be subdivided into all the various tasks. And git is fine with this, especially for SVG files (it even properly notes differences and changes).
But when I put these files in my Android Studio project, I get concerned that the AS will think these are somehow important and keep references to them--possibly even adding them to jar or apk files.
Yes, I realize that the final versions of the art needs to go in the res/drawing/ directories (and similar for sound and other resources). And I'm happy to do this final copy.
Am I over-thinking this, or is there a better way to organize and still keep Android Studio happy?
Since no one has answered this question in 7 months, I'll submit my solution.
I have created a directory under the main directectory (same level as java and res) called assets. Git recognizes this directory and will notice any files that are added, removed, or changed. I'm fine with using git to handle binaries btw.
For each type of asset, I make another subdirectory. Here's what it looks like:
app ->
libs
src ->
main ->
assets ->
font
ogg
png
svg
java
res
...
This seems to work fine and keeps everyone happy. I'm still curious how other people do this; I welcome your comments and answers.
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
With older versions of Android Studio, all of the drawable bucket folders were created by default (i.e. drawable-mdpi, drawable-hdpi, etc.). In newer versions of Android Studio, it only provides drawable and drawable-v21. Why is that?
Is there a reason that Android (in its infinite wisdom) no longer gives you the separate bucket folders?
Just to note, I know you can just add them manually, but I want to make sure there isn't some new best practice reason to not use those folders anymore.
Thank you to everyone who tried to help. You helped me reach the final answer, but no one solution was quite right. #user3137702 was probably the closest, as it IS related to the whole move to vectors/SVGs. I couldn't find a definitive answer, like something directly from Google (although I imagine it is out there), but from what I've gathered from a bunch of articles, there is probably a reason they are doing this.
For starters, it looks like this started in Android Studio 1.4. I am in 1.5 right now. It seems that Android is moving in the direction of no longer needing you to create your own density folders (i.e. mdpi, hdpi, etc.) for drawables (mipmaps is different, so please don't confuse that with what I am talking about). As of Android Studio 1.4, it will take the SVGs you put in the regular drawable folder (as in not the v21 folder), convert them to PNGs, and place them in auto-generated density folders for you during the build sequence (so Gradle does this for you, essentially) for all versions older than API 21. For 21 and up, SVG is supported different, which is a whole other topic. But this essentially makes SVG support backwards compatible all the way to API 1!!!
HOWEVER, there is a BIG catch. This SVG conversion is not always as successful as you might hope. It only supports a subset of SVG files, so depending on how you save it (i.e. what settings are applied when saving), it may not render properly. Even commonly used settings, such as gradient and pattern fills, local IRI references, and transformations are NOT supported (yet). If you are working with SVG files that you didn't generate, you will likely have problems importing them. If you or someone you work with directly generates them, you may have to experiment with how you save the files, and you should test builds often on older versions of Android to make sure it turned out as expected.
To import SVGs into Android Studio 1.4+, follow these simple steps:
Right-click on the res/drawable folder
Select "New"
Select "Vector Asset"
At this point, you can select a "Material Icon", which works
really well, and there are a bunch of beautiful "free" icons you can
select from. For indie developers, without icon design support,
this is nice!
OR - you can select "Local SVG File"
Then choose an SVG from either option with the "choose" option. WARNING: This is where it could possibly go wrong, if the SVG you import isn't saved properly.
Hit "Next"
Verify it is saving in the right place, and then Click "Finish"
At this point, it is reference-able with: android:icon="#drawable/ic_imagename" (using your image name instead of ic_imagename, of course)
#CommonsWare's response was very helpful in leading to the right solution, but from what I saw, generating several variations of new projects from different template and version support settings, there wasn't any way to actually have the old density folders get auto-generated. There is definitely more going on here than just a different template-version selection. But as he said, depending on what template/version you select, you may end up with a different set of those two drawable folder types. But specific to my question, Android Studio does seem to be putting an emphasis on this new approach of not creating your own individual drawable density folders at all.
It's pretty cool, imo, but it still needs some work. In practical terms, I will likely still need to add the drawable density folders to support all the images I work with, until this mechanism gets a little more supportive of all types of SVG renderings.
And one more tidbit - Because this is all handled through Gradle (the actual generation of the density folders) you can add build settings through the flavor mechanism to limit which density folders you want to generate. So if, for example, you feel mdpi images have reached the end of their usefulness for your particular user base and would like to leave that size/density out of your app to shave a couple MB off the app size, you can set that in the Gradle build flavor.
I have one requirement to compress APK size based on type of device(LDPI, MDPI, HDPI.., etc). My client is demanding to give multiple APK's. According to his statement Small devices having low configuration so the apk size should be less, and MDPI is bit better than LDPI so the size may going to increase. So he is demanding to give the build accordingly. So that user will download the app with in less time and saves the internal/ External memory.
For that I tried lot of ways to compress the APK, but I failed at every aspect:
*9- Patch : My project does not contains all the images are 9-Patches, in fact 90% of images are non-9patch's.
*Pro-guard: I tried to reduce the file size using Proguard, but as far as I know proguard is for protecting the my code, and apk size is not much compressed.
* And I tried out not working out for me.
Right now I am following the bellow process, I know this is very bad procedure:
Generating the APK for LDPI devices I kept all resource files in res/ldpi folder only, I am following with same procedure for MDPI, HDPI, XHDPI Etc.,
By using current process, I'm wasting lot of time and it is very bad process also I guess.
To solve the above problem can you please help me out.
Use Gradle for Android and its support for APK density splits. Gradle for Android can then generate APK files for each density, plus an optional "fat APK" containing all densities. You can either use Android Studio as your IDE, or set up a build.gradle file that can build an existing project in the Eclipse/Ant classic directory structure.
However, your client needs to understand that not all distribution channels support distributing different APK files by screen density. The Play Store does. I do not know about other channels (e.g., Amazon AppStore for Android). And the user probably has no idea what the density of their device is, so relying upon the user to choose one of several versions to download from a Web site is unlikely to be reliable.
Inform your client that for all devices apk size will remain same. Make him/her understand that On play store you do not upload different apk's for different types of devices.