Category: android

  • Using Seekbar Inside a ListView

    Few months ago I had to work on a screen in an Android app where we had seekbar controls inside a ListView item. When an item inside the ListView is selected we would show the seekbar inside the item and allow the user to interact with it. As the user moves the seekbar thumb back and forth we update two TextView fields within the ListView item’s layout. I created a ListView using an adapter and in the adapter class I was inflating/reusing item layout that had a Seekbar and two TextView fields. In the onProgressChanged event of the Seekbar I was updating the two TextViews. I noticed that changing seekbar thumb position with touch was extremely sluggish. My initial thought was this sluggishness is due to the fact that we are updating two TextViews and before updating them we are doing some string formatting operations.

    I started my investigation and found that if I don’t update the TextViews then performance improves. But then I thought there must be something else as updating a few text fields should not overload the UI thread. I decided to create a sample project to test my hypothesis. First I added a single Seekbar with two TextViews and was updating them in the Seekbar onProgressChanged  event. Everything was working very smoothly and no sluggishness. Then I built similar UI where I had Seekbars inside a ListView with two TextViews. On Seekbar progress change I was updating the two TextViews. Noticed same sluggishness. That gave me a clue that as soon I put Seekbar inside the ListView the Seekbar performance goes down. Then I thought of a work around which was not to use ListView and instead use a LinearLayout and add each item in the list manually in the code. This solution got rid of sluggishness I was experiencing.

    At this point I had a solution that was working without any issues but I was having hard time accepting that using Seekbars inside a ListView can cause performance issue. I started looking at the adapter class and noticed that I was inflating the list view item layout each time and not reusing them. As per the guidelines we should check if convertView is null only then we should inflate the item layout otherwise reuse the existing view. So I made the modification to the code to reuse the converView if it is not null. And that was it. The sluggishness in Seekbar was gone.

    At this point I had discovered two things, a work around for the ListView performance issue and a mistake that we should not inflate list view item layout each time in adapter’s getView function because it can cause significant performance issues that you will spend hours trying to figure out. ListView is a very efficient way displaying lot of content on a small screen. When a ListView loads it shows as many items as can fit into the screen window and as the user scrolls, it reuses those item view’s and populates them with new data. This way we don’t load views that are not visible to user. This results smooth ListView performance.

    Here is the Github link for my sample project SliderApplication

    https://github.com/niveditau/SliderApplication

  • Android SharedPreferences read/write may slow down the UI rendering

    At work recently I was facing this issue where when we tap on the bottom navigation bar icon it was taking a few seconds to show the tap animation and render the new fragment. The fragment had couple network calls to get the data from the web service. When I started debugging the issue my initial hypothesis was that probably making the network calls, parsing the API response and then rendering the UI was taking a long time. To confirm my hypothesis I updated the logic to make the network call on app launch and store the data in the memory and when fragment loads just load the data from the memory and render the UI. My Fragment was not making any network call at this point because I already had data loaded in the memory. But surprisingly after all these changes I could still see the delay in rendering the fragment UI. I quickly realized that my hypothesis was wrong. At this point I had no idea what can potentially be causing this delay in rendering the fragment UI.

    Then I decided to comment all the functions in the fragment class and run the app. It loaded instantly. Then I started uncommenting the functions one by one. There was a function in the fragment class in which we were reading the data from the SharedPreferences and displaying it. As soon I uncommented that function, the fragment rendering again became sluggish. Then I updated the logic to read the data from SharedPreferences on app launch and keep it in the memory while app is running and read it from there. It improved the fragment UI rendering significantly and QA was happy with it.

    The conclusion of this exercise was  not to read/write SharedPreferences unless absolutely necessary. Every storage operation has a cost. This one did have a hidden cost and took a while to figure out. It can slowdown the UI rendering drastically so use with caution.

  • Setting up an Ubuntu machine for Android Development

    A little while ago I had to setup an Ubuntu machine for Android development. I thought it will be useful for anyone who is trying to do the same.
    Here are the steps that I followed:
    Installing Ubuntu
    • Ubuntu Download link
      http://www.ubuntu.com/download/desktop (top link)
    • Run the iso file from Windows and let it finish the installation.
    • After installation is finished reboot the machine and you should get the option to boot either Windows or Ubuntu.
    Installing JDK/JRE
    Installing Android SDK
    • Android SDK download link
      http://developer.android.com/sdk/index.html
    • Launch the eclipse from the eclipse directory inside the adt-bundle directory.
    • Go to Window > Android SDK Manager. It will launch the Android SDK Manager window. Install all the required tools and API packages.
    • In eclipse I ran into an error that it cannot find adb. I found this useful link
      http://stackoverflow.com/questions/13571145/android-adb-not-found
      that suggests use command “apt-get install ia32-libs” to install IA32 library and that should fix the issue.
    Importing SSH keys

    • Generate a pair of keys by following command
      “ssh-keygen -t rsa -b 4096”
    • In my case keys were generated under Home directory and I used following commands to move them to the location where git looks for it by default
      “mv your_public_key.pub $HOME/.ssh/id_rsa.pub”
      “mv your_private_key $HOME/.ssh/id_rsa”
    • Add the SSH key to github. Go to following link
      https://github.com/settings/ssh
      Click Add SSH Key then give it a name and paste the content from your public key(.pub) in the box and hit Add button at the bottom.
    You should now be able to clone, pull and push from/to github.