I have an app that is localized in 24 languages.
When I build the app with English-only resources, the app is 1.6MB.
When I build the app with all languages resources, the app is 2.5MB.
Language-dependent resources are a couple of HTML files, and strings.xml.
Since the app is running a background service, it is annoying to get it killed due to memory pressure. It seems to be more frequent when it is 2.5MB than when it is only 1.6MB.
Therefore I want to decrease the app size by avoiding to ship all languages in the APK when only one is really needed.
I'm considering making an APK with almost English only and the possibility for the user to download language files from the app at runtime.
Are there frameworks for doing this in Android, or maybe at least patterns or best practices?
Any suggestion is warmly welcome.
You wouldn't see memory issues due to the size of your APK. This would only effect the ability to install the app on a device if the user doesn't have enough space to install it. I think you probably have a different memory issue that you are incorrectly blaming for your memory issues (did a little deeper to see if you can correct the issue).
You can use Proguard to eliminate resources from your final APK, but I don't think this is a wise approach. Link: http://developer.android.com/tools/help/proguard.html
I also think it is not a good idea to create separate APKs for each language (and in fact, this is against the terms of service for the Play Market).
Bottom line, check your app again, and fix your memory issues - you are likely going down the wrong path trying to blame your problems on your localized resources.
Related
After I installed MultiDex I noticed,first ever launch of the app takes extra 4-5 seconds. However after a few researches, I noticed that the app size inside the phone settings(app manager) went from 7 MB to 19 MB and if I clear data, app goes back to 7 MB. But every time that I launch the app for the first time, app size increases to more than double.
Now my question is, what happens that makes the app size increase so much?
So far I have found a few topics on slackoverflow about MultiDex but none talks about what really happen with the code, and what kind of data MultiDex saves/caches.
Multi-Dexing is enabled in your gradle and extended in your Application class.
This is used when you use over 64,000 methods.
https://developer.android.com/studio/build/multidex
I would say probably 90% of the time if you are hitting multi dex needs, you have likely not properly managed your dependencies. I'm NOT saying every time. However, typically the issue is people bring in entire Google dependencies instead of just the ones you need. For example the Google Play Services. If you include this, it will instantly force you into multi-dexing. However, this does come with a performance hit. You now have multiple dex files to load. There is some pre-dexing of course for things that will not change such as 3rd party dependencies to help your speed a bit on building and deploying. However, having multiple lookup tables comes with it's speed consequences. For example, if you included.
com.google.android.gms
has about 44,000 methods alone in it, You should specify which one you want like
com.google.android.gms:play-services-location:16.0.0
for example.
So before you go down the road of using Multi-Dex, ensure you have properly cleaned up your unused dependencies, and that you are properly managing your transitive dependency tree. Also don't forget to use ProGuard or the new D8 minification process as that may also help you, although may require you to run in Debug as well if you have that heavy of dependencies.
If you have done all that and you still need to use Multi-Dex (and I have run into this at larger companies that force tons of bloat libraries on you) then you go for it.
Now as for what is happening, well Dex stands for Dalvik Executable. It is the process of packaging the code into Dalvik bytes for execution. This is limited to 65,536 methods. They say 64k in the documentation, but everywhere I've read shows 65k+. Many of Google's libraries already contain 17k methods which puts you 1/4 of the way there right out the gate.
I believe the issue has something to do with the header allocation of 2 bytes per method signature and the lookup table. they are limited on number of unique IDs they can create. So it requires you to create multiple dex files with multiple lookup tables for the method signatures. So the short answer is, it makes multiple Dalvik Executable files to ensure unique method signatures are properly found and executed on the Dalvic Virtual Machine.
Other important things to note, is that prior to Android API 21, the Virtual Machine only supports 1 dex file. Therefore you need to do multi-dex install on your application onCreate to get the rest brought in properly. However, if you are using proguard, your additional dex files could have been removed so you may need to address a MultDexProguard file as well.
Now, it's important to realize that Android completely redid their Virtual Machine and no longer relies on Dex for their modern OS virtual machines. So then the next question is "should you still use it"?
Well if you are still needing to support pre-Lollipop, then you are better off leaving your multi-dex in place. Otherwise if you are Lollipop and up. Android uses ART (Android Runtime) and does not have this limitation. Honestly the population that has pre-Lollipop is so small that it is not worth supporting in my personal opinion, but it depends on your product and your needs.
Hope that helps shed some light on things here.
Happy Coding
A single .dex file can have 65,536 methods(references) so if the number of references exceeds 65,536, you go with multidex.
Maybe as your app is storing more than one .dex file it is allocating more space for new .dex files.
Breakdown your APK using APK Analyser to see what is causing the app size to increase
use the following link refer
https://developer.android.com/studio/build/apk-analyzer
if you want to decrease the size of the app this article is helpful
https://medium.com/exploring-code/how-you-can-decrease-application-size-by-60-in-only-5-minutes-47eff3e7874e
Recently I have read about the Dalvik 65K method limit. I have understood that the method invocation list can only invoke first 65536 method references.
To tackle this, we have a number of solutions. One of which being multidexing where we split the .dex files to number of classes [classes.dex, classes1.dex ...] by using Android's support library.
What I have failed to understand is: What drawback does an Android application suffer due to this multidexing and why should we put lots of effort in minimising the number of referenced methods?
Basically in my understanding, to reduce the method count, I have to reduce modularisation, which makes my code a bit less readable, leaving apart the number of hours burned in stripping down the code of third-party libraries. Is reducing the method count worth it?
You are overthinking about multidex, instead you should observe and identify if there is any performance issue with your app by profiling your application.
Multidexing hardly increases any size of code, major size and performance issues are with animation/image/audio/video resources, they are the ones who increase size and reduce performance.
Including many third party libraries will eventually pass 64k limit and almost all applications today are multidexed, Users demand multifeatured apps today, that requires integration with many third party libraries.
Only when you are doing animation/game programming, where speed matters the most, more method calls might be harmful, but this has nothing to do with multidexing, even poorly written small non multidexing app will perform bad on any device.
Startup time will affect with multidexing, but it can certainly be improved by changing your app logic to delay loading of other costly library and resources.
Is reducing the method count worth it??
NO
Ideally you should use more methods and modularize your code, because testing and changing mobile apps is huge challenge after it is published. Debugging and removing bugs are more costly then multidex size and its impact on performance. Due to tiny screens, different brands, different UI, users get more angry on apps on phone compared to computers. Keeping up to users demand will become easier if code is divided into multiple individual tested libraries.
The main drawback is a larger dex/apk size. Dex files have pools of constants that are shared among all the classes in that dex file. When classes are split across multiple dex files, these shared constants have to be duplicated in each dex file they are used in.
Multidexing itself is non-performing term, if application is multidex it means there is burden over android internal process which executes application.
Every android application runs inside a single process(task), when its multidexed, it means the process is divided into parts which going to create performance issues with small android processor, no matter how you write code.
I am agree with aakash kava that almost all applications are multidexed because now a days android processors are very good in performance and android RAM is excellent, But it does't ,mean we should ignore multidexing.
Generally spoken the disadvantages of multidex are: Increased APK size, possibly slower app startup and increased memory footprint.
The reason for that is that some data (e.g. StringData) can not be shared and therefore need to be partially stored in multiple DEX files at the same time. StringData consists of string literals loaded from code as well as class, method and field names and commonly account for up to 20% of the total DEX file.
But the actual disadvantages (beside APK size) highly depend on the Android version you are running the app on.
Google optimized the Android Runtime (ART) to remove these drawbacks. Android O (API 26) introduced the VDEX container to store pre-validated DEX files. With Android P Google further optimized the precompiler (codename CompactDex) and added an shared data section to the VDEX container to deduplicate the data used in multiple DEX files. So there are little to none disadvantage when running multidex apps on Android P runtime.
Sources: What's new in Android Runtime (Google I/O '18)
Please Let me know Pro-guard in android applications is Essential or not before releasing in app store.
in some sources are mentioned using pro-guard in android applications, may create problem in application.
Link Source
Benefit
Reduced APK size
Improve performance
Obfuscation
Drawback
Potential misconfiguration
Additional testing required
Stack traces are difficult to read with obfuscated method names
The major drawback is that your app might crash when misconfigured.
The most important benefit of Proguard in my opinion is the obfuscation.
The gain in performance should be very limited.
The reduction of APK size is also minor in most cases: the size of the Dalvik code in an APK is usually way inferior to the size of images and other assets.
Bottom line: Proguard is essential for your app if you want to make reverse engineering more difficult (i.e. prevent other programmers from stealing and reusing parts of your code that you consider valuable).
I'd say it depends on how important those benefits are to you. I was specifically asked to reduce the size of my APK, so I had to turn it on. This meant I had to take all the tests again and to tinker with the proguard configuration to get the optimal size, but in the end the customer was a lot more satisfied, so it was worth it.
Yes, I saw that the similar question had been asked some years a go, but was unanswered, so I just had to give it another shot.
I am quite annoyed with the fact that the .apk file for the simple Android app I am building has 4MB in size.
When I analyse the .apk, i see that it contains not only unused classes (which can be stripped with ProGuard), but also all the graphic resources from HoloEverywhere.
I mean, even the drawables for the themes I am not using at all are in the apk.
This behaviour looks very illogical, or it just might be that I am doing something very wrong.
Finally, my question is: Is there a way to make the .APK contain only the needed data?
I mean, even the drawables for the themes I am not using at all are in the apk.
From the standpoint of the build tools, they have no good way of knowing that you are not using those drawables.
This behaviour looks very illogical
You are welcome to build a tool that can reliably detect unused resources and removes them from an APK. Call it ResGuard or something. Even the commercial DexGuard doesn't do this.
Is there a way to make the .APK contain only the needed data?
Delete the stuff that you are not using. You're the only one who knows what that is, and since HoloEverywhere appears to be no longer maintained, it's not like you will have updates to worry about.
Long-term, I understand that there's a plan to have Gradle for Android allow you to filter out resources as part of referencing an AAR. I'm not aware that this is in place just yet, and you'd still need to know what resources should be filtered this way. This would allow you to avoid modifying the original project, though.
When android app is installed, does it keep only the resources required by the device current configuration (resolution, language etc) and remove all other redundant resources?
(What will be the point of keeping high resolution images when it won't use it ever?)
Whatever files you have in your APK will be persistent. it will not get deleted by any chance.
As far as I know, the idea is to make use of a single APK to be compatible with the different types of Android devices available. It is not a good practice to design different apk for different Devices.
But yes, some of your resources will never be used by the device and this is how it works.
if required you can create multiple apks for a single app itself.
And it is well explained here,
http://developer.android.com/guide/google/play/publishing/multiple-apks.html
Well, it is all compiled in one apk file, so no choice. It will keep all the resources.