How you can decrease application size by 60% (In only 5 minutes)?

Mobile devices always have limited resources. They have a limited amount of battery, limited storage, limited processing power, limited RAM, limited internet connectivity … and the list goes on. This doesn’t matter if you are targeting Android or iOS. This is the universal truth.

In past couple of months, I was developing an android application Anti-Theft Screen Lock. This application capture image using device’s front camera, play alert whenever someone entered the wrong password to unlock the device. If you want to know more here is the play store page, go ahead and read the description:

http://bit.ly/2lLDOML

Here, I am going to tell you about some simple the tweaks and tricks I applied to decrease the application size. These tricks are very simple and easy to apply. These may help you in your current/future applications too.


Smaller is always batter:

As a developer we always care about the application performance, design and user experience the most. But, most of the developer forget (or underestimate) one thing: Application Size. This is one of the key factors if you want to target next billion users with your application.

There are more than 11000 android powered devices available on the market and most of them are having low-end configurations, limited storage capacity (1GB to 8GB of internal storage) and even 2G or 3G connectivity. These devices are having major market share in developing countries like India, Bazil or countries in Africa etc, where you can find your next billion users.

Keeping your application size optimum becomes very important. The less your application uses storage, the more user gets more free space to store their videos and images. Let’s be honest, you don’t want your user to uninstall your application because of “Storage out of space” notification.

1*cjMsR_IEniBq3SXQ3YtJ6g.jpeg

These developing countries are also having the limited 2G/3G connectivity. So, if your application is large in size, it will take the larger time to download the application (And more chances that user won’t download it in the first place). Also, most of the users are having a limited amount of internet data. Every byte user uses to download the application, will affect your user’s wallet.

So, it is clear that in the world of mobile application,

Smaller is always better.


Breakdown your APK using APK Analyser

Android studio provides a handful tool: APK Analyser. APK Analyser will tear down your application and let you know which component in your .apk file is taking the larger amount of space? Let’s have a look in Anti-Theft screen lock apk file without any optimization applied.

1*qwluezWR7KE9-raJVkAc9A.png

From the apk analyzer output, you can see that the application raw size is about 3.1MB. After applying play store compressions, the application size is roughly 2.5 MB.

As you can see from the screenshot, there are main 3 folders that are consuming most of the application size.

  • classes.dex — This is the dex file which contains all the bytecode files of your java code that will run on your DVM or ART.
  • res — This folder includes all the files under your res folder. Most of the time this will contain all the images, icons and raw files, menu files, and layouts.

1*8ITi0D6JrpibvAC9iTG2rA.png

  • resources.arsc — This file holds all the value resources. This file contains all the data you have under your different value folders. This resource contains strings, dimensions, styles, integers, ids etc.

1*B1MMigEQSVfKIJRmujeIag


So, now you know what an APK is made of. Let’s see, how can we decrease the application size by optimising one by one component.

Reduce classes.dex:

As we discussed, this contains all the java code. While you build your application, gradle will combine all of your .class files from all the modules and convert those .class files to .dex files and combine them in single classes.dex file.

If you are curious, how the compilation process works, visit my another blog post : The Jack and Jill: Should you use in your next Android Application?

Single classes.dex file can accommodate, approximately 64K methods. If you exceed this limit, you have to enable multidexing in your project. Which will create another classes1.dex file to include all remaining methods. Thus the number of classes.dex file depends on the number of methods you have.

1*koKowwJQ0aavZ6-Sh1I6AQ.png

As you can see currently “Anti-Theft Screen Lock” contains 4392 classes and 29897 methods. This result is without applying proguard. You have two default proguard file you can apply.

  • proguard-android-optimize.txt
  • proguard-android.txt

As the name suggests “proguard-android-optimize.txt” is the more aggressive progurard configuration. We used this as the default proguard configuration. You can add you custom proguard configurations in proguard-rules.pro file in your /app directory.

By setting minifyEnabled to true, yo are telling proguard to remove all the unused methods, instructions and slim down the classes.dex file.

Here is the result from minify enabled APK,

 1*FPR6BZkWLBYhHs6YO9lLvA.png

As you can see by enabling the proguard in every module of our project we can we are able to reduce the classes.dex file size almost by 50%. Also, you can see method count decreased from 29897 to 15168 (almost 50%). Hurray…!!!🎊🎉

Size decreased from 3.1 MB to 1.98MB. (~50% decrease)


Reduce res:

The second largest component in your apk size is your res folder, which contains all the images, raw files, and XML. You cannot add/remove/modify your XML, as they are containing your layouts. But we can decrease the image files.

  • shrinkResourcesattribute will remove all the resources, those are not used anywhere in the project. Enable this in your build.gradle file by adding below line:
  • resConfigs attribute will remove all the other localized resources while building the application. In our case, “Anti-Theft Screen Lock” only supports the English language. While all the support libraries may have localized folders for other languages. Which we don’t need. So, add following line to allow only English resources to be added in APK file.
  • Android Studio 2.3, and you application minimum version is 18 or above, you should use webp instead of png. webp images are having less size than png files and also it retains the original image quality. More to that webp images are natively supported in Android. So you can load webp images in ImageView same as other raster images. So, you don’t have to change your layouts.

You can select drawable and mipmap folders from you project, right click and select convert to webp. This will open below configuration dialog.

1*Y51gzPlk1Pcd_0s8lqcc9Q.png

Press ok and it will convert all the png images to webp format one-by-one. If the webp image is having the larger size than png, Android Studio will automatically skip that file.

Let’s see the final result:

1*UiwJkvIhWjrNNj2DU7Z3kA.png

Volla!!! res folder size decrease from 710KB to 597KB.

Size decrease by 105KB. (Decrease by 16%)

You can also convert the images to vector drawable. But for that, you have to make some changes to make it backward compatible. If you want to learn more on vectors see this great post by Chris Banes.


TL;DR:

  • Enable proguard in your project by adding following lines to your release build type.
  • Enable shrinkResources.
  • Strip down all the unused locale resources by adding required resources name in “resConfigs”.
  • all the images to the webp or vector drawables.

Conclusion:

By applying above simple tricks the application size decreases from 3.19 MB to 1.89 MB.

These are the most simple tricks. There are many other tweaks that can reduce your application size. But, you should always apply above simple tricks to your android applications to make sure you reduce the application size as much as you can.

For more tips and tricks you can read this from Android Developers website.

Remember: Smaller is Alway Better. 😉

Glide vs. Picasso

Glide and Picasso are the most used image loading library in the world of android applications. Most of the android application developers have used any of these or both libraries in their career. Both libraries provide number of features, very fast and optimized. They are also well tested on many applications. On the surface, it looks like both are working on the same mechanism. But they both are very different in the way how they download images, caches images and loads them into memory. Today, we are going to look into the core differences between both the libraries and try to figure out which one is the best for application development.

We are comparing Glide v3.7.0 and Picasso v2.5.2 versions for this article. The latest available version might be different depending on when you are reading this article.

Import to the project:

Picasso and Glide, both are on jcenter. You can simply import those into your project with below dependency.

Picasso:

Glide:

support-v4 dependency is not needed for most of the projects as most of them uses support library by default.

Size and Method Count:

While comparing the sizes of the .jar file of both the libraries, Glide is almost 3.5 times larger than Picasso in size.

1rqe23b0xa6fpd6zopjx2aq

Picasso has method count of 849, while Glide has total 2678 method count. 2678 is quite a lot for 65535 methods limit of Android DEX file. You should enable ProGuard if you choose to use Glide.

1se-djihhpw8iwf4gij66aa

Syntax:

Both libraries have almost same syntax if you want to simply load the image from the URL and display them into the image view. Both support the fade animations and center crop. You can also add placeholder image to display while loading the image or while the image loading fails.

Glide:

Picasso:

One thing in which Glide dominates is, it is designed to work with Activity and Fragment’s life cycle too. You can pass the activity or fragment context with Glide.with() and it will brilliantly integrate with activity lifecycle callbacks such as onPause() or onResume().

1*Luh0ueUaCghrAywvkMxE4Q.png

Disk caching:

Both the library supports caching the image in the disk. They download the images from the URL and store those images on the disk by caching. But there are some differences how they store the images in the cache.

Picasso downloads the image and stores the full-size image (in my case the image resolution was 1160*750) in the cache and whenever we ask for the same image, it will return the full-size image and resize them to fit into the ImageView in real time.

On the other hand, Glide works differently. Glide downloads the image from the given URL, resize it to the size of the image view and stores it to the disk cache. So if you are loading the same image in two different sized image views, Glide will store two different copies of the same image in the cache with different resolutions. That will increase the disk cache size, but it has some of its own benefits. We will see that in the next section.

When I tried to adjust ImageView to the different sizes, Picasso cached only single size of the image and that is full-size. While Glide caches separate files for each size of ImageView. On down point of this approach is, although an image has already been loaded once, if you need to load the image in another size ImageView, it needs to be downloaded once again before be resized to the right resolution and then be cached.

Memory:

By default, Glide uses RGB_555 configuration while Picasso loads images in ARGB_8888 configuration to load the bitmap into memory. So for fair comparison, I made some changes in GlideModule to load images in ARGB_8888 format by creating a new class which extended from GlideModule like this:

Below is the graph of memory consumption of loading the image in Glide and Picasso:

1*-TOjFF8NJ6W7bmHZycjDtw.png

By looking into the graph, we can see that Glide is more memory efficient (about 8 MB) than Picasso (about 13 MB). This is pretty much understandable as we discussed in the earlier section, that Picasso loads the full-size image into the memory and relies on GPU to resize that image to fit into the size of the ImageView. While Glide loads an image that is already resized as per the ImageView, that requires significantly less memory than loading the full image like Picasso. This helps to prevent your app from throwing popular OutOfMemoryError.

Time taken to load the Image:

When we try to load an image from the URL, both libraries checks their local caches and if the image is not present in the cache, they will download the image from the URL.

When I tried to download images from the URL, Picasso was quite fast in loading the image from the internet than Glide. Maybe because after downloading the image, Picasso directly pushes the full-size image to the memory; while Glide resizes the image as per the dimension of the ImageView. That needs some time to resize the image. (You can reduce this time by using thumbnail() which we will discuss in later section.)

1*P7b1K_pp494aPLZ2sFI3Sw.gif

But while loading the image from the cache, Glide wins the battle. This is because of an advantage of the way Glide was designed. While the Picasso causes some delay on loading since it needs to be resized the image first in real-time before images are set to an ImageView. Even if you use .noFade()to appear it instantly.

1*0nIGJyOVgut-kCDMbu3kIg.gif

Other features that Glide support but not Picasso:

  • Animated GIF support: Glide supports animated GIF images out of the box. Loading GIF is simple. Just use the same Glide.with(...).load(...)call and if the image you load is an animated GIF. Also, because of Glide integrates with your activity life-cycle, animated GIFs are also paused in onStop() to avoid draining the battery in the background. While as of now, Picasso does not support animated GIF images. So, if you want to display some animated GIF, then Glide is the only option here.
  • Thumbnail support: With Glide, you can load multiple images into the same view at the same time. To first load a thumbnail at 1/10th the size of your view and then load the full image on top, you can use below code:

 This will reduce the time your user has to see image loading spinners without sacrificing quality.

  • Configurations & Customization: One good thing about Glide is, it provides various conflagrations and customization options. So, you can tweak Glide library as per your requirement. You can read more about this at configuration page.

Conclusion:

Neither Glide nor Picasso is perfect. You can use any of this library based on your application requirement. If you want the smaller app and you require very fewer features in the image loading, than Picasso is best. But If you want more customization, animated GIF support, and very better memory management, you should use Glide as your image loader library.

In my opinion, Glide is the winner over here as it handles memory very well and prevents my app from OutOfMemoryError. Also, loads image much faster than Picasso. And yes, the support for animated GIFs is almost killer.

References:

Create Chat Heads Like Facebook Messenger

We all love the chat heads (or chat bubbles) from the popular Facebook Messenger. This provides very handy and easy access to the chat conversation screen no matter on which screen you are. Chat heads are very convenient for multitasking as a user can work and chat at the same time. That means if you are using the calculator app on your phone and if any new message arrives, you can open the conversation and replay the message without switching app. Pretty cool!!!

In this tutorial, we are going to learn how to create simple chat head and allow user to drag them across the screen. So that user can adjust the position of the floating widget in the screen.

So, let’s get started.


Understanding the basics:

  • Chat heads are nothing but a floating view that is drawn over other application. Android system allows applications to draw over other application if the application has android.permission.SYSTEM_ALERT_WINDOW permission. We are going to use the background service to add the floating widget into the view hierarchy of the current screen. So, this floating view is always on top of application windows.
  • To, drag the chat head across the screen we are going to override OnTouchListener() to listen to drag events and change the position of the chat has in the screen.

Implementation:

Step-1: Add android.permission.SYSTEM_ALERT_WINDOW permission to the AndroidManifest.xml file. This permission allows an app to create windows , shown on top of all other apps.

Step-2: Create the layout of the chat head you want to display.

Step-3: Add music control widget to the window and handle dragging:

  • Now create a service called ChatHeadService. Whenever you want to display a chat head, start the service using startService() command. In onCreate() of the service we will add the layout of the chat head at the top-left corner of the window.
  • To drag the chat head along with the user’s touch, we have to override OnTouchListener(). Whenever the user touches the chat head, we will record the initial x and y coordinates, and when the user moves the finger, the application will calculate the new X and Y coordinate and move the chat head.
  • Also, implement click listener to close the chat head by stopping the service when the user clicks on the close icon at the top-right of the chat head.
  • So finally your ChatService.java will look like below:

Step-4: Handle Overdraw permission:

  • Now one final step is remaining. To add display chat head, you need to start the ChatService.java.
  • Before that, we need to check if the application has android.permission.SYSTEM_ALERT_WINDOW permission or not? For android version <= API22, this permission is granted by default. But for the android versions running API>22 ,we need to check for the permission run-time. If the permission is not available, we will open permission management screen to allow the user to grant permission using Settings.ACTION_MANAGE_OVERLAY_PERMISSION intent action. This will open below screen facilitate user to grant android.permission.SYSTEM_ALERT_WINDOW permission.

0-fmkc8d0ganviplho

  • Here is the code snippet for the MainActivity that will display the chat head when the button is clicked by checking the SYSTEM_ALERT_WINDOWpermission.

That’s it. Now build and run the project to see the results. Here is the sample of how our final application should look like.

1-nXWx3gEVPpIRstANlLpzew.gif

Don’t worry if you have any problems while building the project. Full source code is also available on GitHub. Go ahead, download and run it. Still, if you have any queries let me know in comments below or hit me on Twitter . Also, follow me on Github to stay in touch.