avatarSiva Ganesh Kantamani

Summary

The webpage provides an in-depth exploration of advanced Android development topics, including Dagger2 for dependency injection, Proguard for code obfuscation, multi-threading with Loopers and Handlers, Android architecture patterns like MVVM and MVP, and security measures such as protecting shared preferences and implementing certificate pinning.

Abstract

The article serves as a comprehensive guide for Android developers, particularly those preparing for interviews or seeking to deepen their expertise in advanced areas of Android app development. It covers the use of Dagger2 for efficient dependency management, discussing key annotations and concepts such as Modules, Components, and Scopes. The author delves into Proguard and its successor R8 for code optimization and obfuscation, emphasizing the importance of the mapping file for debugging. The threading model in Android is explained with a focus on Loopers, MessageQueues, and Handlers, illustrating how they facilitate asynchronous operations. Architectural patterns are compared, with a distinction made between MVVM and MVP, and the principles of Clean Architecture are highlighted for structuring robust applications. Lastly, the article addresses security concerns by suggesting the use of Jetpack Datastore for secure data storage and outlining the implementation of certificate pinning to prevent man-in-the-middle attacks.

Opinions

  • The author, an experienced Android developer, emphasizes the practical importance of understanding Dagger2 for dependency injection in Android applications.
  • Proguard is recommended for its dual benefits of code obfuscation and APK size reduction, although the author acknowledges the transition towards R8 as a more modern alternative.
  • The article suggests that a thorough understanding of threading in Android, including the use of Loopers and Handlers, is crucial for creating responsive and efficient apps.
  • When discussing architectural patterns, the author seems to favor the MVVM model for its flexibility and maintainability, especially in the context of configuration changes.
  • The author advocates for Clean Architecture as a means to achieve a high level of separation of concerns and reduced dependency between application layers.
  • On the topic of security, the author recommends using Jetpack Datastore over traditional shared preferences for enhanced data protection, indicating a preference for newer, more secure solutions.
  • Certificate pinning is presented as an essential security practice to safeguard against man-in-the-middle attacks during server communication, underscoring the importance of comprehensive security measures in mobile app development.

Android Interview Questions and Answers — Part 2

Dagger2, Proguard, Threads, Architecture and Security

Photo by Headway on Unsplash

Android is one of the leading platforms in mobile development. If you want to reach millions of potential users, defiantly android would be at the top of your list. With this increasing hype, many software engineers choosing android development as their carrier choice.

I’m an android developer for more than five years now, and I’ve been on both sides of the table when it comes to android interviews. So I decided to write a series of articles about android interview Q&A.

Android interviews are a mix of many concepts like android basic to advanced concepts, Kotlin, coroutines, RxJava, Architectures, Design patterns, solid principles, and more. It’s highly impossible to include all of them in a single article. So I’ve started with android basics in part 1 of this series, and in this part, we’re to deal with some complicated concepts like Dagger2, Proguard, Threads, and more.

Without any further delay, let’s get started:

Dependency Injection (Dagger2)

What are the annotations that you used in Dagger2?

Dagger2 is the most popular framework to implement dependency injection in Android. Dagger2 is a compile-time library, this gives us two advantages — no runtime errors and we no longer need to maintain dependency injection manually.

Coming to the question, it depends on your hands-on experience with Dagger2. But there will be few annotations that you should know such as — Module, Provides, Inject, Component, and Singleton. Read the following article to learn about them. Apart from that, you should also learn about advanced annotations like-named, Qualifier, and more.

What is the difference between provides and binds?

The end goal of both annotations is to provide the necessary dependency object. Provides can have as many parameters as required but binds can only have one parameter and it should be equal to its return type

Provides generates factory class for each function whereas binds won’t do it. Imagine how many factory classes and their methods will be created and become problematic with DEX size. Typically by using binds we can reduce 40% of code generation.

What is named annotation?

Named is an advanced annotation in Dagger2. When you’ve more than one provides function with the same return type then dagger throws compile time exception. This is where named annotation comes to light. We can give a different name for each provider function so that the dagger can differentiate them while injecting. Have a look at the code for a clear idea:

What is a Qualifier?

The qualifier is used to distinguish between objects of the same type but with different instances. The qualifier is behind the scenes guy which gives us the power to create annotations like named. To learn more about it read the following article.

What is a scope?

The scope is an annotation class to define the life span of a component. The inner components and dependencies created in it are bound to the life span of that component.

Singleton is the best example of scope in Dagger. If use singleton annotation on any of the components it’ll be created once and stay in the memory throughout the application life span.

Apart from this based on the company and their usage of dagger2 you might also face complicated questions related to Dagger2 in the multi-module.

Proguard

How Proguard works?

Proguard is a way to obfuscate the code to make it difficult to reverse engineer the code and also reduce the APK size via tree shrinking.

Obfuscating the code is a process to modify the code in a way that it’s no longer useful to the hacker. Proguard modifies the code with short names like with alphabets. If you try to decode the APK you would understand it. By using short names instead of full-length class and variable names it’ll reduce the APK size and obfuscate the code simultaneously. To learn more about it read the following article:

What is the mapping file with regard to proguard?

Obfuscating the code is a great way to secure the code. We know that obfuscation means modifying the code, this will make it difficult for developers to decode the crash reports. Fortunately, R8 creates a mapping.txt file each time it runs, which contains the obfuscated class, method, and field names mapped to the original names.

We need to upload this mapping file to the play console or any analytics tool that you use like Sentry to understand the crash or analytics report.

Differences between proguard and dexguard?

  1. ProGuard is a generic optimizer for Java bytecode, whereas DexGuard is a specialized tool for the protection of Android applications.
  2. ProGuard provides minimal obfuscation, whereas DexGuard applies multiple layers of encryption and obfuscation.
  3. ProGuard is an open-source tool, whereas DexGuard is a commercial, enterprise-grade product.

Threads

What is a Looper?

Threads in android work in a way like they start, execute their code block written in run() method and then get destroyed. But in android, the main thread is responsible to run UI, so the question is how does the main thread keep on running.

Here comes Looper in the picture. Looper provides Thread an ability to keep on running in a loop and associates a MessageQueue for the thread on which this Looper object is created. When a Message or Runnable is posted, Looper executes those on its associated thread.

Note that, only one Looper can be created per Thread. It implies one MessageQueue per thread also. But multiple Handler can be created for a single Looper.

Looper.prepare(), Looper.quite(), Looper.loop() are the functions used to start, end and keep on loop the thread respectively.

What is MessageQueue?

Looper provides the ability to run in a loop for threads with its own MessageQueue. MessageQueue is a queue that has tasks called messages which should be processed.

What is a Handler?

The handler provides a way to communicate with Looper. Handler sends Runnable or Message object on Looper, providing a way to execute code on a particular thread from another thread.

Each Handler always has a Looper object associated with it. Whenever we post a Runnable or send a Message on a Handler, it executes on the Thread associated with the Handler’s Looper.

Explain the life cycle of a thread?

There are six states in a thread lifecycle, such as NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, and TERMINATED. Learn more about them in detail in this post.

Architecture

What is the difference between MVVM and MVP?

  • MVVM can map many views to one view model but MVP is a one-to-one mapping between view & presenter.
  • In MVVM the ViewModel has no reference to the view, while in MVP the view knows the presenter.
  • When the orientation changes view-model won’t get destroyed but the presenter does.

Explain about clean architecture?

In android clean architecture is used to reduce the dependency between the layers and improve the separation of concerns principle. It’s a huge concept and it’s not possible to explain everything here. So following are the two links where you can find everything you should know about clean architecture.

Can we share the ViewModel between activities?

No, it’s not possible to share viewmodels between activities, whereas, we can share them among fragments.

Security

How do you secure shared preference from exposure?

One of the latest solutions is to use Jetpack Datastore instead of traditional shared preference. As it’s not stable yet, we can use an encrypted shared preference library or we can manually encode and decode the key-value pairs.

I recommend you to go through the following article to learn in detail how to use the encrypted shared-preference library and manual encoding & decoding the key-value pairs.

What is certificate pinning and how do you implement it in android apps?

Communicating with the servers is a common task in any modern mobile application. Using HTTPS alone isn’t enough to provide secure communication. Many hackers interfere with communications to mislead servers and clients. This is known as a middle man attack. To establish a secure line to the server, we need to implement certificate pinning.

To learn more about certificate pinning and different ways to implement it, read the following article:

Bonus

To learn more about Android advanced development read the following articles:

That is all for now, hope you learned something useful, thanks for reading.

AndroidDev
Programming
Interview
Mobile App Development
Software Development
Recommended from ReadMedium