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

 

 

Event-driven programming for Android (Part I)

(This is the first article in a three-part series)

Although Android includes some event-driven features in its development, it is far away from being a pure event-driven architecture. Is this something good or bad? As in every issue with software development the answer is not easy: it depends.

First, let’s establish a definition for event-driven development. This is a programming paradigm where the flow of execution is determined by events triggered by actions (such user interaction, messaging from other threads, etc). In this sense, Android is partially event-driven: we all can think of the onClick listeners or the Activity lifecycle, which are events able to trigger actions in an application. Why I said it is not a pure event-driven system? By default, each event is bound to a particular controller, and it is difficult to operate besides it (for example, the onClick events are defined for a view, having a limited scope).

Wait, you are talking about a new programming paradigm. Adopting frameworks or methodologies has always a cost, could this bring any advantage? I say yes, and to show it I want to present some limitations with traditional Android development.

In many scenarios will be easy to end up with a structure as the following diagram is showing:

androidstatusquo

 

Activities can communicate with Fragments, Fragments can send messages to another Fragments and Services. There is a tight coupling of components, and applying changes can be expensive(*). This leads frequently to boilerplate code, interfaces that implement functions that need to callback and propagate through different layers… you probably know where I want to go. As the amount of code increases, the maintainability and good software engineering practices are decreasing.

How event-driven programming applies here? Let’s represent another system proposal:

androidevent

Conceptually, the represented system have an event bus. There are different entities subscribed to the Event Bus, and posting events or listening to events – being respectively a producer or a consumer. Any subscriber can perform an action without knowing the logic. Think about it. Think about particular possibilities: a Fragment could render again and update its screen without knowing the logic behind any operation, just knowing that an event took place. Think about the possibilities of decoupling code and having a clean, compartmentalized architecture.

Is this paradigm supported in Android? Well, partially. As mentioned, the SDK offers natively a reduced set of event handling techniques, but we we want to go further. There are some names I want to mention here:

  • EventBus, from greenrobot. This library has been optimized for Android, and has some advanced features like delivery threads and subscriber priorities.
  • Otto, from Square. Originally a fork from Guava, it has evolved and being refined to the Android platform.

Having tried both I prefer EventBus over Otto. Greenrobot claims that EventBus is significantly better at performing than its pair, and provides an extra amount of features.

Screen Shot 2015-01-25 at 9.57.52 PM

Screen Shot 2015-01-25 at 10.00.04 PM

 

The next article will explore how to implement basic functions in EventBus

(*) I deliberately like to use the word “expensive” when referring to “lot of time”. Thinking in economical terms is frequently more effective.

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.

How to store the Credentials securely in Android

Most of the applications in the Market store credentials (let it be username/password or a hash) in the application to avoid prompting the user continuously asking him for the authentication. While being a good pattern to make the application usage more fluent, it is not exempt of security risks.

Android provides different options to store data from an application. From all those, the SharedPreferences seems to be the most adequate to store credentials: it stores primitive types in an XML file, which is in principle saved in the application package folder and hidden to the user in most cases. A device that has been rooted, however, can access this folder and retrieve the SharedPreferences files, exposing the credentials if we have chosen to store them this way.

This problem also affects integrity of another applications, and allows operations such as game cheating. Srinivas proves in his blog how is possible to edit the score in Stick Cricket and submit a modified one to the server.

A rooted device always makes security harder, but we can ensure that our authentication is securely stored by combining a few techniques. Encryption is the first thing that comes in mind, but if we want to encrypt we might need to use a key, that also needs to be stored somewhere else. NDK comes here into the scene: we can store using native code the key or sequence we will use to encrypt our data. Let’s see it step by step.

First, we will write two functions to encrypt and decrypt our data. We will use AES for our purpose:

    private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(clear);
        return encrypted;
    }

    private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] decrypted = cipher.doFinal(encrypted);
        return decrypted;
    }

The functions are very straight-forward. Now we can use them like follows:

ByteArrayOutputStream baos = new ByteArrayOutputStream();  
bm.compress(Bitmap.CompressFormat.PNG, 100, baos); 
byte[] b = baos.toByteArray();  

byte[] keyStart = "encryption key".getBytes();
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(keyStart);
kgen.init(128, sr); 
SecretKey skey = kgen.generateKey();
byte[] key = skey.getEncoded();    

// encrypt
byte[] encryptedData = encrypt(key,b);
// decrypt
byte[] decryptedData = decrypt(key,encryptedData);

If we use this functionality to encrypt our data, at this point it will be encrypted but an attacker could still decompile our APK, check the key used to encrypt the data and steal our credentials. With NDK we can store this key in an .so file, making it very hard for the attacker (.so files can hardly be decompiled, and disassembling those files is far from being a comfortable option). To store and retrieve our key, we need to write the following code in our application:

static {
        System.loadLibrary("library-name");
    }

public native String getSecretKey();

And save in a file using NDK the following function:

Java_com_example_exampleApp_ExampleClass_getSecretKey( JNIEnv* env,
                                                  jobject thiz )
{
    return (*env)->NewStringUTF(env, "mySecretKey".");
}

Now we can easily retrieve our key and use it to encrypt our data.

byte[] keyStart = getSecretKey().getBytes();

Security is never granted and never absolute, so the solution is to always take smart design decisions and use all the available tools to prevent unauthorised usage of our applications or systems. By applying this technique you can ensure a high level of security for your application credentials!

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.