Does the .apk format handle hardlinks? Or does it simply copy the same file over and over?
I've some a simple test and it seems like hardlinks are not handled, meaning that the size of the generated .apk increases significantly when you have multiple hardlinks to the same file. Is there a way to make the resources point to the same file instead?
The use case is the following: I have several images, which are used in some places in my application and their names contain some information about them. For example I could have an apple.jpg, apple_red.jpg, apple_red_big.jpg, apple_big.jpg, apple_green.jpg etc. My application uses the image that matches the data the most, and thus if the data is about a red, big apple it will use apple_red_big.jpg, while if the application only knows that the data regards apples it will simply use apple.jpg.
At the moment I'm not providing a different file for each resource, so apple_red.jpg is simply an hardlink to apple.jpg. In the future I might decide to add more images and thus apple_red.jpg could have its own image.
Also, since apple.jpg is used as a fallback option, it will pretty much always be a simple hardlink to an other image which happen to be also apple_something.jpg.
How can I avoid duplicating all these images in the final apk?
If you provide the same image under different file names (even if they are just hard links), the aapt will package them up as separate resources. Rather than using the file system to create hard links, the Android way of doing what you want is to provide alias resources. The technique is described here in the docs. Basically, you simply create a bitmap drawable that references another drawable:
file res/drawable/apple.xml:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/apple_something" />
where you store apple_something.png in the res/drawable directory. The alias resource takes up just a tiny bit of additional room in the .apk file.
In code, both R.drawable.apple and R.drawable.apple_something would then retrieve the same image (although they would be different Drawable objects); in xml it would be #drawable/apple and #drawable/apple_something.
Related
Let say i want these shapes in my project, like rectangle, ring and oval:
Which means i should have three xml files for each shape.
So, as far as i know we create separate xml file for each shape. Is this mandatory to create each shape in separate xml file? Is there any way to create all needed shapes in one xml file and call each shape with the help of attribute name, id or something else which will help us to reduce the number of xml files?
To give you an answer : no, you have to have different files.
But there are several different advantages to this : having 3 different files means that they are easier to re-use (in future, you can select to add ONE file to your new project and skip the others) and it's easier to modify (finding ONE file to edit is simpler than having to scroll through ,which could at that point be, 1000 shapes). Even though this is potentially debatable and having one file also has its own advantages, the answer is still : you have to create separate files
It's not possible. You can't reference them from code any more.
I have a lot of images and I want to classify them in the drawable folder in Android Studio for easy access, is it possible?
Not possible. The only way to sort your drawable resources is by renaming them, usually with prefixes (i.e. ic_ for icons).
You can't put them in folders. However, you can control the name of them to find them easier. For example, if I have buttons coded with shapes, etc, I will name these button_name. This way, it all of my buttons are there for me to view. If I have a few minutes in a certain activity, I will do something like results_, and then all of my results images are there. Hopefully they makes sense and helps.
in Delphi, I add image resources to the project (via project > resources and Images), however i need for one java function to give a resource ID in the application's package of the drawable to use. Is it possible to retrieve a resource ID (integer) from my delphi resource file or name ?
If not, how in delphi we can add a custom resource image and retrieve it's resource ID ?
Getting a Resource ID
To retrieve the resource ID of a resource:
id := TAndroidHelper.GetResourceID('my_image', 'drawable');
If you are using an older version of Delphi you may need to use the alternate, older approach:
id := TAndroidHelper.Context.getResources.getIdentifier(StringToJString('my_image'), StringToJString('drawable'), TAndroidHelper.Context.getPackageName);
The shorter, more recent (and convenient) GetResourceID function is merely a wrapper around the earlier longer winded version.
In either case, my_image is the filename (without extension) of the image resource whose ID you need.
The drawable parameter tells the helper that it is a drawable resource ID that you are asking for (as opposed to a string or layout, for example).
Adding Image Resources
To add a custom image resource to your project use the Deployment option of the Project menu in the IDE.
Add your file and set the remote path to a suitable drawable resource folder, e.g.:
res\drawable
res\drawable-xxhdpi
etc
You could put your own scaled versions of the image in each drawable folder for different resolutions. The remote_name must be the same in each case. The specific drawable folder determines the applicable device resolution.
Alternatively you could simply provide one suitably high resolution file. You can place this in either an appropriate high-resolution folder (e.g. drawable-xxxhdpi) or simply in drawable.
Either way, Android will auto-scale the images at runtime for other device resolutions as necessary.
There are lots of Android references on the subject of drawable scaling, alternative versions for different display types etc, including the Android documentation itself of course.
Referencing your comment, there are however no XML files required for adding drawables that are straightforward images.
Additional XML may be necessary for other types of drawable resources, but that will very much depend on the nature of your specific needs.
Bringing It All Together
In the screenshot below the highlighted entry is one that I have added for a PNG image resource. The file is in my project folder so there is no local path (the first column).
The filename is appstore.png and I have configured the deployment to place one copy of that file in the res\drawable' folder of the application when it is deployed (theremote` folder).
This file will rely on auto-scaling for display on different resolutions devices.
To get the resource ID of that resource I then simply write:
id := TAndroidHelper.GetResourceID('appstore', 'drawable');
I'm developing an application which has some assets bundled with it - they are mostly web pages with associated graphics, css etc which I'll display in a custom WebView. I'm trying to work out how to serve up different assets to different devices without massive duplication.
I'd like to replicate the res folder, but for assets. For example:
assets/html/page1.html references assets/html/example_pic.png but I want to serve up a different example_pic.png depending on screen density or screen size.
Ideally I'd like to have something like assets_hdpi/html/example_pic.png and assets_mdpi/html/example_pic.png
Is there an elegant way of achieving this? Can I somehow utilise the /res/ folder management to the same end result by putting the example_pic.png in to /res/drawable_hdpi etc and then somehow pointing the webpage to the drawable?
A possible workaround:
Prepare a 'subpath' named string for the different resolutions you want to address, e.g.:
res/values-hdpi/subpath.xml: <string name="subpath">hdpi</string>
res/values-ldpi/subpath.xml: <string name="subpath">ldpi</string>
Prepare corresponding subpaths in your asset folder, e.g.:
assets/hdpi, assets/ldpi and store your assets there.
Finally, use getResources.getString(R.string.subpath) to get the best asset subpath.
String AssetPath= "file:///android_asset/"+getResources.getString(R.string.subpath)+"/";
myWebView.loadPage(AssetPath+"index.html");
I've got a bunch of small two colour png images and I'd like to effectively change one of the two colours to another one. Say RED => BLUE.
I know I can either loop over each pixel or use Bitmap.setXfermode to do this but it feels like a big waste on such a simple problem. What I want to do is to access the header of the file and change it in the colour table directly. This hints that png:s are indexed http://developer.android.com/guide/topics/resources/drawable-resource.html#Bitmap :
Note: Bitmap files may be automatically optimized with lossless image compression by the aapt tool. For example, a true-color PNG that does not require more than 256 colors may be converted to an 8-bit PNG with a color palette. This will result in an image of equal quality but which requires less memory. So be aware that the image binaries placed in this directory can change during the build. If you plan on reading an image as a bit stream in order to convert it to a bitmap, put your images in the res/raw/ folder instead, where they will not be optimized.
The files I put in the "project" are indexed png images so I know for sure they are in fact indexed and does have a colour table. Will I have to read the files as binary data and manipulate before I make a Bitmap object? I would really prefer if that wasn't the case but there instead is some hidden Bitmap.switchColor (Col1, Col2); which would do just that since I want to be able to switch back or to a third colour.
Please only android related answers and not general ones since I'm only looking for how to do it in android, using android classes.
Thanks in advance