100 Questions and Answers to help you land your Dream Android Job (or to hire the right candidate)

I am publishing a book called “100 Questions and Answers to help you land your Dream Android Job (or to hire the right candidate!).

cover Kopie

My purpose with this book, as a person that has been both behind and in front of an interview, is to collect and present on a readable way questions and tips on how you should prepare for an Android interview. This book is valid both for interviewers and candidates. I have noticed too that many of the questions asked at interviews are so repetitive, and if you google something like “android interview questions” the same set is always returned. Whereas they are still valid, if you are aiming at hiring a senior you should consider more advanced questions about architecture, patterns or frameworks. Each question is answered with a comprehensive and clear reply. Some of the questions provide a bonus, which is typically a topic you want to deep into to further analyze the knowledge of a candidate.

Questions are divided into basic, intermediates and advanced ones. Some people will argue that I could have done two divisions rather than three, but I consider important to have this intermediate category. There are many developers that have been digging for a while into Android, but they did not have yet the time of opportunity to work with more advanced topics. The classification is merely subjective and it is based on my previous experience, but it has been proven useful in my experience as a candidate and an interviewer.

I hope you enjoyed this book. Is available from Amazon and Google Play, but soon I will upload it to other channels. If you have any feedback, you can always send me an email. I will answer within 24 hours except during holiday periods.

I have set up the price as low as possible (in fact, it will not cover the time spent writing it). If your situation does not allow to buy it, send me also an email and explain me your situation.

buy4._V192207739_    button-get-it-on-google-play-small1

 

 

Gradle surviving tricks

Gradle did come to stay with us. Although existing before Android Studio came, it was the Google IDE the tool that popularised it. But are we using the most of it?

After meeting some colleagues and other developers at different conferences, I have realised that the community is underusing Gradle and not exploiting all its possibilities. With this article, I want to share a few tricks I have learned that focus on improving productivity and helping to the Continuous Integration process:

Keeping multiple builds with different icons, names and package extensions

Very likely, at your organisation the Continuous Integration process will create different binaries depending on the build type (alpha, beta and release). For your team will be important to keep a copy of the different versions, so for instance you can keep the last beta version and the release version. By default, Android will keep only a package name (which substitutes each previous install) and the same icon. We can easily modify this, to allow all the different builds to co-exist together.

We can set up in the buildType a new applicationIdSuffix and a new versionNameSuffix.

 
     buildTypes {
        debug {
            debuggable true
            applicationIdSuffix '.debug'
            versionNameSuffix '-debug'
            signingConfig signingConfigs.debug
        }

For each build that we have created, we must also add under the src folder a new folder with the name of the build type. Any content within this folder will overwrite the original one when the application is being compiled in a particular build type (i.e., if we add a different icon it will be taken from here).

 

Screen Shot 2014-11-30 at 18.12.28 copy

And as we can see, all the different build types will be co-existing together.

screenshot

Using different values depending on the build type.

A very recurrent problem: we want to manually handle different values that correspond with different build types (for example, we will want to call a different URL, or track to a different Google Analytics account, depending if the application is the production one or not). By using the token buildConfigField, this task is very trivial with Gradle (and removes all the risk associated with the manual handling!)

Screen Shot 2014-11-30 at 18.00.38 2

Increasing the version code automatically.

We have already written about automatically increasing the versionCode and an extended version. The idea behind it is that every Jenkins build will take care of increasing the versionCode and therefore notifying the recipients that a new version is available. This is a really cool feature that helps us to keep a real track of all the different APKs that we are generating.

 

Handling duplicates in dex files

Did you ever see an error saying something like Multiple dex files define Lwhatever/package? It really sucks. This means you are adding twice a file that is include in one of your dependencies. If you are working with this projects this sucks twice, since you might have trouble to identify exactly which package is causing this. We can call gradlew dependencies to find in the root project where this is happening, but this is not working with subprojects (and with the current version there is no –recursive or –include-submodules flag).

There is however a small workaround. We can define this in our root build.gradle file:

 
subprojects {
    task listAllDependencies(type: DependencyReportTask) {}
}

which basically executes gradlew dependencies for all the subprojects. This will tell us exactly in a moment where are our dependencies, so you can eliminate them. By calling gradle listAllDependencies you will get something similar to the following paragraph:

 
+--- com.actionbarsherlock:actionbarsherlock:4.4.0
+--- project :libraries:ViewPagerIndicator
|    \--- com.android.support:support-v4:19.1.+ -> 19.1.0
+--- project :libraries:sixtappkit-android
|    +--- com.google.android.gms:play-services:4.3.23
|    |    \--- com.android.support:support-v4:19.0.1 -> 19.1.0
|    +--- com.android.support:support-v4:19.1.0
|    +--- com.actionbarsherlock:actionbarsherlock:4.4.0
|    +--- com.google.maps.android:android-maps-utils:0.3.1
|    |    \--- com.google.android.gms:play-services:4.3+ -> 4.3.23 (*)
|    +--- com.github.chrisbanes.photoview:library:1.2.2
|    +--- org.projectlombok:lombok:1.12.4
|    +--- org.roboguice:roboguice:2.0
|    +--- com.squareup.retrofit:retrofit:1.4.1
|    +--- com.octo.android.robospice:robospice:1.4.11
|    |    \--- com.octo.android.robospice:robospice-cache:1.4.11
|    |         +--- org.apache.commons:commons-lang3:3.2.1
|    |         \--- org.apache.commons:commons-io:1.3.2
|    |              \--- commons-io:commons-io:1.3.2
|    \--- com.octo.android.robospice:robospice-retrofit:1.4.11
|         +--- com.octo.android.robospice:robospice:1.4.11 (*)
|         \--- com.squareup.retrofit:retrofit:1.3.0 -> 1.4.1
+--- com.github.chrisbanes.actionbarpulltorefresh:extra-abs:+ -> 0.9.9
|    +--- com.android.support:support-v4:[18.0,) -> 19.1.0
|    +--- com.actionbarsherlock:actionbarsherlock:[4.4,) -> 4.4.0
|    \--- com.github.chrisbanes.actionbarpulltorefresh:library:0.9.9
|         \--- com.github.castorflex.smoothprogressbar:library:0.4.+ -> 0.4.0
+--- com.crashlytics.android:crashlytics:1.+ -> 1.1.13
+--- de.greenrobot:eventbus:2.2.0
+--- com.jakewharton:disklrucache:2.0.2
+--- com.j256.ormlite:ormlite-android:4.48
|    \--- com.j256.ormlite:ormlite-core:4.48
+--- com.j256.ormlite:ormlite-core:4.48
\--- de.keyboardsurfer.android.widget:crouton:1.8.4

I always have this task for all my projects. Since falling into the multiple dex error is probable, I know I can always use this task rather than checking the last changes in the project.

Your build process will increase and gets more complex as your company or organisation grows, is nothing static at all. Those tricks have helped me increased the productivity, and I have now included them by default in any project I work with.

Comprehensive guide to export your Android application to Blackberry

Since the Playbook OS 2.0 was released, Blackberry provided a set of tools and procedures to export an .APK file into a Blackberry .BAR file. To put something big into small words, it is possible to repackage an .APK file into a .BAR, sign it afterwards and being able to run it on a Blackberry device. The procedure, however, turns a little bit tricky due to several reasons. The support from Blackberry does not cover a high detailed documentation, and it is far from being straightforward. In this article we will try to explain it on an easy way, using the latest tools available at this moment.

Before getting our own .APK, there are some considerations to be done.

  • Blackberry development is also Java based, so basically we will take our compile .dex files and create a virtual instance in a Blackberry machine that will run our Android application
  • Android is an OpenSource framework, but not everything in the Android SDK is OpenSource. Google Play Services, Google Maps, etc… are frameworks that have not been open-sourced from Google. We just download the libraries with a set of APIs to call the functionality, but this does not mean we have access to the code itself. Therefore there is a bunch of things from our applications that will not work in Blackberry!

This brings us to the first topic: if our application is making use of Google Maps or Google Play Services, we will need to get rid of this functionality. Google Play Services provides us typically the Location API, Analytics or the Drive API. If we have been using one of those, we will need to find an alternative (typically downloading external JARs if available, and adapting our application). For the location API, is still possible to call the old LocationManager, which is less comprehensive but it does what it needs to do.

If our application is making use of Google Maps v1, OSmdroid provides an alternative to more or less easily replace our Google Maps. The syntax is quite similar (except the part involving the markers management). For more information, you can check the OSmdroid project repository.

If our application has been using Google Maps v2, things will get more interesting. OSmdroid provides a Wrapper to be used and switch between the different maps engines. However, this wrapper does not follow the same syntax as Google Maps v2. This means you will need to invest some time in developing your application making use of this Framework if you want to make it work. In addition, the wrapper still does not cover much of the Google Maps v2 functionality. This is a decision that involves taking into account the nature of the project, requirements and some time considerations.

If your application does not use any of the private Google libraries, congratulations. You are closer to get the finest .bar file that will compile in Blackberry for the same effort as developing only its Android peer. Let’s begin to explain this.

      1. The first step is to request permission to sign your Blackberry apps. This can be done at the following website. When you are creating the .CSJ files, remember to write down the PINs! Blackberry does not provide any reset mechanism, so you will need to go over this article again if you loose them.
      2. Shortly after you will receive two files (xxxRDKxxx.csj and xxxPDBTxxx.csj at your email). Download them into your hard drive, and then execute the following command:
        blackberry-signer -register -csjpin 
        -storepass

        This command will create a few files that you will need to use to sign up your files. Pay attention to the files author.p12, barsigner.csk and barsigner.db. Is not a bad idea to make a backup of the files inmediately. If you need to restore them in the future, you just can copy them into ~/Library/Research In Motion.

      3. Now we have our keystores and certificates. It is time to package our Blackberry application. Download the Command Line tools from the Blackberry website, uncompress them and save them into a folder of your choice (at this point is always good to remember that taking some time to add this folder to your Path will save you much more time in the future). Look at a file called Blackberry APK Packager, and open it. Something similar to the following screen will appear:Bildschirmfoto 2014-07-15 um 18.24.35
      4. You need to indicate which .APK do you want to import, and where do you want to generate a .BAR file. The Advanced Settings section allows us to set information such as author, debug mode and so on – not very relevant at the moment. If you click in Package the process will begin, and you will see if there is any unsupported package (ATTENTION! Just using classes not supported by Blackberry, such as LatLng, will make your application crash with a ClassNotFoundException). Let’s imagine you have done your homeworks, and the application has been packaged with no problems.
      5. The last step is to sign the application with the certificate, so it can run on your Blackberry device. Proceed with the following command:
        batchbar-signer <input_files> <developer_certificate> 
        <keystore_password> [<csk_password>]

        The keystore password is the one you used when you create the developer certificate, and the keystore password, and the csk password specifies the keyword you defined when you configured your computer to sign apps. The developer certificate is the author.p12 file you created before.

      6. We are a step closer. First, activate the development mode in your device (normally you will find it in “settings – security and privacy – Development Mode”). You will need to write down the IP of your device (with the USB cable connected to your computer), and the development PIN that will be prompted to write. Now, with this last information write the following in your shell:
        blackberry-deploy -installApp -launchApp -device 169.254.0.1 -package /Users/route/apk -password 123456

        Changing obviously the information to your IP, package route and password you selected before.

If everything went well, your application should now be running on your Blackberry device! The process is however far from being simple. If Blackberry stakeholders are really willing to improve the platform features and make it more human-doable, they should probably focus in the signing process instead of releasing music videos. Just one of those things.

 

Displaying JavaDoc in Android Studio

Android Studio does not displayed Javadoc by default when an element is being hovered, which is a burden for productivity. However, this can be easily set up:

Go to Preferences and then Editor. When the window appears, mark the last option:

Screen Shot 2014-05-15 at 1.09.31 PM

Alternatively you can use “Control + J” while hovering a method to display the Javadoc in a floating window.

Increasing the performance of Gradle builds

Lately, I have been immersed into adding a bunch of new projects to our CI server. Although we have been using a distributed system to achieve a parallel build, at some point our builds were requiring a considerable amount of time. Providing some numbers: consider an scenario with 49 different projects (backend, frontend, mobile), in different branches (production, development) constantly building and deploying. There was an average waiting list to build projects of more than 20 minutes, with some projects taking more than 10 minutes to build and deploy. Something against the spirit of CI, really. After doing some research, I increased the performance of my builds in about one third. This is how to achieve it:

So with the problem detected, the next step was to find a solution: how to improve the performance of the builds. The first platform to improve was Android (15 from all our projects are Android based, which is around one third of the total). We are using Gradle build system and Android Studio. While is still great, is an on-going product with constant releases and has not reached its peak of performance yet . First, the important point was to identify the bottlenecks. I used the following script in our build.gradle file to detect which tasks were more problematic:

class TimingsListener implements TaskExecutionListener, BuildListener {
    private Clock clock
    private timings = []

    @Override
    void buildFinished(BuildResult result) {
        println "Task timings:"
        for (timing in timings) {
            if (timing[0] >= 50) {
                printf "%7sms  %s\n", timing
            }
        }
    }

    @Override
    void buildStarted(Gradle gradle) {}

    @Override
    void projectsEvaluated(Gradle gradle) {}

    @Override
    void projectsLoaded(Gradle gradle) {}

    @Override
    void settingsEvaluated(Settings settings) {}

    @Override
    void beforeExecute(Task task) {
        clock = new org.gradle.util.Clock()
    }

    @Override
    void afterExecute(Task task, TaskState state) {
        def miliseconds = clock.timeInMs
        timings.add([miliseconds, task.path])
        task.project.logger.warn "${task.path} took ${miliseconds}ms"
    }
}

gradle.addListener new TimingsListener()

This code is relatively straight forward. For each task being executed by Gradle, will measure the time required, and when the build is finished will print the amount of time each task needed.

In order to perform a right benchmarking, I would use my computer with no extra program rather than the console, and run gradle clean assembleRelease. I run this in one of our ship projects with a quite typical structure for our company: a single project, containing 6 maven libraries and 2 local ones.

My first experiment shown nothing really surprising: I run gradle clean mergeReleaseResources, preDexRelease and dexRelease were the tasks more time consuming. Particularly:

Bildschirmfoto 2014-04-23 um 15.49.43

Pre-dexing is used for speeding up incremental builds. Pre-dexes dependencies of a module, so that they can just be merged together into the final dex file, but won won’t affect the release build (since you should be doing clean builds for release builds anyway). So we could get rid of this process during the release build:

  dexOptions {
    preDexLibraries = false
  }

While doing some research met two options to be used with gradlew:
–parallel executes parallel build for decoupled projects, leading to an increase in performance.
–daemon allows to execute our gradle as a daemon, speeding up the build time.

This options can be called from the console:

./gradlew --parallel --daemon clean assembleRelease

Or can be included in a gradle.properties file:

org.gradle.parallel=true
org.gradle.daemon=true

Combining all the points: I run again the same command and got the following:

Bildschirmfoto 2014-04-23 um 15.57.03

The increase in performance have been also successful in subsequent builds, and it is on average a 30% faster than the non-optimized version.