1. What’s the difference between an implicit and an explicit intent?
An explicit intent is where you tell the system which Activity or system component it should use to respond to this intent. Implicit intentsallow you to declare the action you want to perform; the Android system will then check which components are registered to handle that action.
Here, you’re looking for an understanding of when you should use each type of intent, as the vast majority of the time you’ll use explicit intents to start components in your own application, while implicit intents are most commonly used to communicate with components from other third party applications.
2. When should you use a Fragment, rather than an Activity?
This is still a much-debated topic, but the code used to create an Activity is fundamentally more involved than the code used to create a Fragment. The old Activity has to be destroyed, paused or stopped, and a new Activity has to be created. The developer should acknowledge that the best practice is to only use Activities when you need to swap the entire screen, and use fragments everywhere else.
Bonus points if the Android developer mentions any of the following use cases, where you’ll almost always use a Fragment, rather than an Activity:
- When you’re working with UI components or behavior that you’re going to use across multiple Activities.
- When you’re using one of the navigational methods that are closely linked to fragments, such as swipe views.
- When your users would benefit from seeing two different layouts side-by-side.
- When you have data that needs to persist across Activity restarts (i.e you need to use retained fragments).
3. You’re replacing one Fragment with another — how do you ensure that the user can return to the previous Fragment, by pressing the Back button?
This question provides an insight into the app developer’s understanding of the lifecycle of dynamic fragments, as well as Fragment transactions, and the back stack.
If the “Back” button is going to return the user to the previous Fragment, then you’ll need to save each Fragment transaction to the back stack, by calling
addToBackStack() before you
commit() that transaction.
The developer definitely shouldn’t suggest creating a “Back” button specifically to handle navigating between fragments, but bonus points if they mention that you should never try to commit a FragmentTransaction after calling
onSaveInstanceState(), as this can result in an exception.
4. How would you create a multi-threaded Android app without using the Thread class?
If you only need to override the
run() method and no other Thread methods, then you should implement Runnable.
In particular, be on the lookout for an Android developer demonstrating an understanding that you should only extend from a class when you need to modify some of its functionality.
5. What is a ThreadPool? And is it more effective than using several separate Threads?
ThreadPool consists of a task queue and a group of worker threads, which allows it to run multiple parallel instances of a task.
Here, you’re assessing the app developer’s understanding of how multithreading has the potential to improve an app’s performance, but also how it can negatively impact performance when used incorrectly.
Using ThreadPool is more efficient than having multiple operations waiting to run on a single thread, but it also helps you avoid the considerable overhead of creating and destroying a thread every time you require a worker thread.
6. What is the relationship between the lifecycle of an AsyncTask and the lifecycle of an Activity? What problems can this result in, and how can these problems be avoided?
An AsyncTask is not tied to the lifecycle of the Activity that contains it. If the Activity is destroyed and a new instance of the Activity is created, the AsyncTask won’t be destroyed. This can lead to a number of problems, but the major ones an Android developer should be aware of are:
- Once the AsyncTask completes, it’ll try to update the former instance of the Activity, resulting in an IllegalArgumentException.
- Since the AsyncTask maintains a reference to the previous instance of the Activity, that Activity won’t be garbage collected, resulting in a memory leak.
The solution is to avoid using AsyncTasks for long-running background tasks.
7. How would you access data in a ContentProvider?
Start by making sure your Android application has the necessary read access permissions. Then, get access to the ContentResolver object by calling
getContentResolver() on the Context object, and retrieving the data by constructing a query using
ContentResolver.query() method returns a Cursor, so you can retrieve data from each column using Cursor methods.
Accessing data is one of the tasks that’s most likely to block the main thread, so the developer should stress the importance of performing data queries on a separate thread.
8. What is the difference between Serializable and Parcelable?
Serializable is a standard Java interface that’s easy to integrate into your app, as it doesn’t require any methods. Despite being easy to implement, Serializable uses the Java reflection API, which makes it a slow process that creates lots of temporary objects.
Parcelable is optimized for Android, so it’s faster than Serializable. It’s also fully customizable, so you can be explicit about the serialization process, which results in less garbage objects.
While the developer may acknowledge that implementing Parcelable does require more work, the performance benefits mean that they should advise using Parcelable over Serialization, wherever possible.
9. What is an Adapter?
Here, you’re checking that the Android eveloper understands that you need an additional component to connect an AdapterView (such as ListView or GridView), to an external data source. An Adapter acts as this bridge, and is also responsible for converting each data entry into a View that can then be added to the AdapterView.
10. What is an Application Not Responding (ANR) error, and how can you prevent them from occurring in your app?
This question checks whether the developer is aware of the golden rule of threading on Android: never perform lengthy or intensive operations on the main thread.
An ANR dialog appears when your UI has been unresponsive for more than 5 seconds, usually because you’ve blocked the main thread. To avoid encountering ANR errors, you should move as much work off the main thread as possible.
Learn more about common Android errors with our infographic.
11. Outline the process of creating custom Views
This is a complex topic, so you’re only looking for a high-level overview of the steps involved. However, the developer should make it clear that you should always subclass the View that most closely resembles the custom component you want to create — very rarely would you extend the View class.
After extending your class, you need to complete the following steps:
- Create a res/values/attrs.xml file and declare the attributes you want to use with your custom View.
- In your View class, add a constructor method, instantiate the Paint object, and retrieve your custom attributes.
- Override either
- Draw your View by overriding
12. What is a BuildType in Gradle? And what can you use it for?
Build types define properties that Gradle uses when building and packaging your Android app.
This question allows you to check that the developer can differentiate between product flavors, build variants, and build types, as these are very similar concepts that are a common source of confusion:
- A build type defines how a module is built, for example whether ProGuard is run.
- A product flavor defines what is built, such as which resources are included in the build.
- Gradle creates a build variant for every possible combination of your project’s product flavors and build types.
13. What are the major difference between ListView and RecyclerView?
There are many differences between ListView and RecyclerView, but the Android developer should be aware of the following in particular:
- The ViewHolder pattern is entirely optional in ListView, but it’s baked into RecyclerView.
- ListView only supports vertical scrolling, but RecyclerView isn’t limited to vertically scrolling lists.
14. Briefly describe some ways that you can optimize View usage.
There are a number of methods, but the ones that tend to have the most impact are:
- Checking for excessive overdraw: install your app on an Android device, and then enable the “Debug GPU Overview” option.
- Flattening your view hierarchy: inspect your view hierarchy using Android Studio’s ‘Hierarchy Viewer’ tool.
- Measuring how long it takes each View to complete the measure, layout, and draw phases. You can also use Hierarchy Viewer to identify any parts of the rendering pipeline that you need to optimize.
15. What is a Handler typically used for?
You use Handler to communicate between threads, most commonly to pass an action from a background thread to Android’s main thread.
This question allows you to check that the developer understands another fundamental concept of multithreading in Android: you cannot update the UI from any thread other that the main thread.
16. What are the steps involved in creating a bound service through Android Interface Definition Language (AIDL)?
- Define an AIDL interface in an .aidl file.
- Save this file in the src/ directory of the application hosting the Activity and any other application that needs to bind to this service — the latter is particularly important, and is often overlooked.
- Build your application. Android SDK tools will then generate an IBinder interface file in your gen directory.
- Implement this interface, by extending the generated Binder interface and implementing the methods inherited from the .aidl file.
- Extend Service and override
onBind()to return your implementation of the Stub class.
17. What’s the difference between onCreate() and onStart()?
The onCreate() method is called once during the Activity lifecycle, either when the application starts, or when the Activity has been destroyed and then recreated, for example during a configuration change.
The onStart() method is called whenever the Activity becomes visible to the user, typically after
18. When might you use a FrameLayout?
Here, you’re looking for an understanding that you should always use the simplest layout possible for what you want to achieve, as FrameLayouts are designed to contain a single item, making them an efficient choice when you need to display a single View.
If you add multiple Views to a FrameLayout then it’ll stack them one above the other, so FrameLayouts are also useful if you need overlapping Views, for example if you’re implementing an overlay or a HUD element.