Android

Hire the Top 3% of Freelance Android Developers

Toptal is a marketplace for top Android developers, engineers, programmers, coders, architects, and consultants. Top companies and start-ups choose Toptal Android freelancers for their mission-critical software projects.

No-Risk Trial, Pay Only If Satisfied.

Clients Rate Toptal Android Developers4.3 / 5.0on average across 955 reviews as of Jun 14, 2023

Hire Freelance Android Developers and Engineers

Jasmin Kurti

Freelance Android Developer

Bosnia and HerzegovinaToptal Member Since June 16, 2016

Jasmin is a responsible developer with a great deal of experience developing innovative and complex Android applications. He's extremely organized, prides himself on his communication, and enjoys the perks of working in teams. Jasmin relishes taking on challenges and in solving them.

Show More

Patrick Keenum

Freelance Android Developer

United StatesToptal Member Since July 6, 2018

Patrick is a senior full-stack engineer with more than 10 years of experience developing beautiful, reliable, and scalable products. He is passionate about bringing ideas from conception to launch, working with clients of all levels of technical acumen, and building products that help companies grow.

Show More

Muhammed Mutahr

Freelance Android Developer

United StatesToptal Member Since June 9, 2018

Muhammad is a senior software engineer with several years of experience in industries ranging from the public education sector (WSU), privately owned healthcare companies (Meridian), and public Fortune 500 companies in the automotive industry (GM & AAM). Throughout his career, he’s designed web apps in HTML/CSS, developed client-side apps using JavaScript frameworks (Angular/Ionic), and used Java and C# to develop robust server-side apps.

Show More

Boris Yordanov

Freelance Android Developer

United StatesToptal Member Since July 15, 2017

Boris is a full-time web developer who works mainly with Vanilla JavaScript and with the most popular JavaScript frameworks like Angular, React, and Meteor. He made his first website when he was 14, and since then, he has made more than 400 WordPress sites during his freelancing career. Nowadays, he designs and builds custom web applications and sites.

Show More

Dan Napierski

Freelance Android Developer

United StatesToptal Member Since April 28, 2016

Dan is a software architect and technology professional focusing on applications of blockchain technologies. He has years of experience providing professional consulting services to clients ranging from startups to global corporations. He specializes in bringing rigorous testing and bulletproof code to tough engineering challenges. He has deep expertise in many aspects of artificial intelligence, blockchain, machine learning, and automation.

Show More

Richard Kolkovich

Freelance Android Developer

United StatesToptal Member Since August 10, 2015

Richard has run the gamut from technical support to co-founder. Over his career, Richard has accumulated both a deep level of technical understanding as well as a broad comprehension of the other requisite elements of building and growing a successful business. His breadth of experience and technical expertise make him uniquely suited to solve business problems with technology.

Show More

Branislav Zlatkovic

Freelance Android Developer

SerbiaToptal Member Since June 10, 2016

Branislav is a software engineer with five years of experience in Android development on various projects for companies like Sony Mobile, Bottle Rocket Studios, and MindGeek. Extensive experience covers a variety of different project set-ups from building apps from start to finish to the development and continuous delivery for large-scale, long-term projects. Being a moderate perfectionist, he's a valuable contributor to any development team.

Show More

Adrian Świętoń

Freelance Android Developer

PolandToptal Member Since March 24, 2016

Adrian is an excellent developer with a wide range of skills and over a decade of experience at his disposal. He has a professional degree in Informatics and has worked on projects at every level, from low-level Assembly coding to multi-platform desktop and mobile apps. Recent projects of note include a flight/race simulator with unconstrained 360° rotation on two axes that supports multiple games and an OpenGL music visualization app.

Show More

Hubert Orlik-Grzesik

Freelance Android Developer

PolandToptal Member Since March 18, 2014

Hubert is an incredibly fast learner; -he was once able to pick up a musical instrument in the morning and play nice tunes by the afternoon. He has the same skill when it comes to working with new technologies and on new projects. He values high-quality code and attention to detail, and he cares deeply about great UX.

Show More

Dmitry Ryazantsev

Freelance Android Developer

MontenegroToptal Member Since April 18, 2016

Dmitry is an Android developer with more than six years of experience who communicates well and always tries to find the best tech that suits the project. He's experienced with Git, Lua (Corona SDK), RxJava, and Dagger. He's worked with a large team to develop the Yandex browser with more than 10 million installations. He's also developed his own projects—a game with 250,000 installations and published several other apps.

Show More

Ivan Dimoski

Freelance Android Developer

SwedenToptal Member Since December 11, 2013

Ivan is a professional with more than 10 years of experience in Android development. His most recent role included sole contribution, team leadership and engineering management for an agile cross-functional team of 17 in Truecaller, delivering amazing features to 250+ million monthly active users. As a passionate people person, he values openness and simplicity as foundations for creating a successful story.

Show More

Sign up now to see more profiles.

Start Hiring
Frequently paired together

Get Additional Expertise

Our clients frequently pair these additional services with our freelance Android Developers.

A Hiring Guide

Guide to Hiring a Great Android Developer

True Android experts know more than simply how to code an app. They have a thorough appreciation of the platform's nuances and the different implementation options available. The questions presented in this guide help identify those Android developers with the experience to produce masterful results on the Android platform.

Read Hiring Guide

Android Hiring Resources

Trustpilot
Toptal in the press

... allows corporations to quickly assemble teams that have the right skills for specific projects.

Despite accelerating demand for coders, Toptal prides itself on almost Ivy League-level vetting.

Our clients
Building a cross-platform app to be used worldwide
Thierry Jakicevic
Building a cross-platform app to be used worldwide
Testimonials

Tripcents wouldn't exist without Toptal. Toptal Projects enabled us to rapidly develop our foundation with a product manager, lead developer, and senior designer. In just over 60 days we went from concept to Alpha. The speed, knowledge, expertise, and flexibility is second to none. The Toptal team were as part of tripcents as any in-house team member of tripcents. They contributed and took ownership of the development just like everyone else. We will continue to use Toptal. As a start up, they are our secret weapon.

Brantley Pace, CEO & Co-Founder

Tripcents

I am more than pleased with our experience with Toptal. The professional I got to work with was on the phone with me within a couple of hours. I knew after discussing my project with him that he was the candidate I wanted. I hired him immediately and he wasted no time in getting to my project, even going the extra mile by adding some great design elements that enhanced our overall look.

Paul Fenley, Director

K Dunn & Associates

The developers I was paired with were incredible -- smart, driven, and responsive. It used to be hard to find quality engineers and consultants. Now it isn't.

Ryan Rockefeller, CEO

Radeeus

Toptal understood our project needs immediately. We were matched with an exceptional freelancer from Argentina who, from Day 1, immersed himself in our industry, blended seamlessly with our team, understood our vision, and produced top-notch results. Toptal makes connecting with superior developers and programmers very easy.

Jason Kulik, Co-Founder

ProHatch

As a small company with limited resources we can't afford to make expensive mistakes. Toptal provided us with an experienced programmer who was able to hit the ground running and begin contributing immediately. It has been a great experience and one we'd repeat again in a heartbeat.

Stuart Pocknee , Principal

Site Specific Software Solutions

We used Toptal to hire a developer with extensive Amazon Web Services experience. We interviewed four candidates, one of which turned out to be a great fit for our requirements. The process was quick and effective.

Abner Guzmán Rivera, CTO and Chief Scientist

Photo Kharma

Sergio was an awesome developer to work with. Top notch, responsive, and got the work done efficiently.

Dennis Baldwin, Chief Technologist and Co-Founder

PriceBlink

Working with Marcin is a joy. He is competent, professional, flexible, and extremely quick to understand what is required and how to implement it.

André Fischer, CTO

POSTIFY

We needed a expert engineer who could start on our project immediately. Simanas exceeded our expectations with his work. Not having to interview and chase down an expert developer was an excellent time-saver and made everyone feel more comfortable with our choice to switch platforms to utilize a more robust language. Toptal made the process easy and convenient. Toptal is now the first place we look for expert-level help.

Derek Minor, Senior VP of Web Development

Networld Media Group

Toptal's developers and architects have been both very professional and easy to work with. The solution they produced was fairly priced and top quality, reducing our time to launch. Thanks again, Toptal.

Jeremy Wessels, CEO

Kognosi

We had a great experience with Toptal. They paired us with the perfect developer for our application and made the process very easy. It was also easy to extend beyond the initial time frame, and we were able to keep the same contractor throughout our project. We definitely recommend Toptal for finding high quality talent quickly and seamlessly.

Ryan Morrissey, CTO

Applied Business Technologies, LLC

I'm incredibly impressed with Toptal. Our developer communicates with me every day, and is a very powerful coder. He's a true professional and his work is just excellent. 5 stars for Toptal.

Pietro Casoar, CEO

Ronin Play Pty Ltd

Working with Toptal has been a great experience. Prior to using them, I had spent quite some time interviewing other freelancers and wasn't finding what I needed. After engaging with Toptal, they matched me up with the perfect developer in a matter of days. The developer I'm working with not only delivers quality code, but he also makes suggestions on things that I hadn't thought of. It's clear to me that Amaury knows what he is doing. Highly recommended!

George Cheng, CEO

Bulavard, Inc.

As a Toptal qualified front-end developer, I also run my own consulting practice. When clients come to me for help filling key roles on their team, Toptal is the only place I feel comfortable recommending. Toptal's entire candidate pool is the best of the best. Toptal is the best value for money I've found in nearly half a decade of professional online work.

Ethan Brooks, CTO

Langlotz Patent & Trademark Works, Inc.

In Higgle's early days, we needed the best-in-class developers, at affordable rates, in a timely fashion. Toptal delivered!

Lara Aldag, CEO

Higgle

Toptal makes finding a candidate extremely easy and gives you peace-of-mind that they have the skills to deliver. I would definitely recommend their services to anyone looking for highly-skilled developers.

Michael Gluckman, Data Manager

Mxit

Toptal’s ability to rapidly match our project with the best developers was just superb. The developers have become part of our team, and I’m amazed at the level of professional commitment each of them has demonstrated. For those looking to work remotely with the best engineers, look no further than Toptal.

Laurent Alis, Founder

Livepress

Toptal makes finding qualified engineers a breeze. We needed an experienced ASP.NET MVC architect to guide the development of our start-up app, and Toptal had three great candidates for us in less than a week. After making our selection, the engineer was online immediately and hit the ground running. It was so much faster and easier than having to discover and vet candidates ourselves.

Jeff Kelly, Co-Founder

Concerted Solutions

We needed some short-term work in Scala, and Toptal found us a great developer within 24 hours. This simply would not have been possible via any other platform.

Franco Arda, Co-Founder

WhatAdsWork.com

Toptal offers a no-compromise solution to businesses undergoing rapid development and scale. Every engineer we've contracted through Toptal has quickly integrated into our team and held their work to the highest standard of quality while maintaining blazing development speed.

Greg Kimball, Co-Founder

nifti.com

How to Hire Android Developers through Toptal

1

Talk to One of Our Industry Experts

A Toptal director of engineering will work with you to understand your goals, technical needs, and team dynamics.
2

Work With Hand-Selected Talent

Within days, we'll introduce you to the right Android developer for your project. Average time to match is under 24 hours.
3

The Right Fit, Guaranteed

Work with your new Android developer for a trial period (pay only if satisfied), ensuring they're the right fit before starting the engagement.

Find Experts With Related Skills

Access a vast pool of skilled developers in our talent network and hire the top 3% within just 48 hours.

FAQs

  • How are Toptal Android developers different?

    At Toptal, we thoroughly screen our Android developers to ensure we only match you with talent of the highest caliber. Of the more than 200,000 people who apply to join the Toptal network each year, fewer than 3% make the cut. You'll work with engineering experts (never generalized recruiters or HR reps) to understand your goals, technical needs, and team dynamics. The end result: expert vetted talent from our network, custom matched to fit your business needs.

  • Can I hire Android developers in less than 48 hours through Toptal?

    Depending on availability and how fast you can progress, you could start working with an Android developer within 48 hours of signing up.

  • What is the no-risk trial period for Toptal Android developers?

    We make sure that each engagement between you and your Android developer begins with a trial period of up to two weeks. This means that you have time to confirm the engagement will be successful. If you're completely satisfied with the results, we'll bill you for the time and continue the engagement for as long as you'd like. If you're not completely satisfied, you won't be billed. From there, we can either part ways, or we can provide you with another expert who may be a better fit and with whom we will begin a second, no-risk trial.

Share
Android

How to Hire a Great Android Developer

As with any technology, there’s knowing Android and then there’s really knowing Android. This guide offers a sampling of questions that are key to evaluating the breadth and depth of a candidate’s mastery of the Android mobile framework when looking to hire Android app developers part-time or full-time.

The Challenge

Android has become the dominant smartphone platform on the planet with over 81% market share (more than Apple iOS’ 15% and Microsoft Windows’ 4% combined) and 240 million mobile devices worldwide. Not too shabby. With that comes enormous demand for developer talent, so locating elite Android app developers can be a daunting task.

Finding them requires a highly-effective recruiting process, as described in our post In Search of the Elite Few – Finding and Hiring the Best Software Developers in the Industry. Such a process can then be augmented with questions—such as those presented herein—to identify those sparsely distributed candidates across the globe who are true Android experts.

Android is a smartphone operating system built on top of Linux based on Java and XML. Since the Android OS is not just a language, but a complete, rich and growing software framework, it has a lot to master. As of this writing, Android is in its 7th year, now at version 4.4 (“KitKat”) and has undergone 19 SDK releases.

Google introduced Android as an open source project in 2007 (see AOSP) so it could get a foothold in the emerging smartphone market. Numerous hardware vendors have used Android for their handsets (Samsung, HTC, Sony, Motorola and LG just to name a few), often adding their own custom features and code. This sometimes creates additional headaches for developers when incompatibilities or vendor-specific bugs arise (read: workarounds). Android itself isn’t a perfect mobile app development OS either, of course – with its sometimes lacking documentation and some quirky-behaving code – but it is still certainly a force to be reckoned with.

The Android application development platform offers a plethora of features and support classes:

  • User Interface, animation, graphics, varying screen size support and orientations
  • Touch screen keyboards and gesture recognition
  • Databases, content providers, content resolvers, adapters
  • Location detection, sensors, services
  • Threading options
  • Accelerated computation
  • Inter-app communication
  • Media playback and recording
  • Networking and connectivity
  • Google Play store and in-app billing
  • Localization
  • Debugging tools
  • And much more…

Such complexity can make any developer’s head spin, not to mention that of a hiring manager. So where do we start when interviewing Android programmers?

True Android experts will have a thorough and principled appreciation of the different implementation options available as well as their implications and ramifications.

What separates the expert Android mobile app developer from the neophyte goes beyond knowledge of how to code an app. When faced with a complex task, true Android experts will have a thorough and principled appreciation of the different implementation options available as well as their implications and ramifications. The questions presented in this guide can help you identify those rare Android gurus who have this understanding and who can significantly improve the productivity and throughput of your project as a result.

User Interface

The User Interface (UI) is the face of your app. An application’s UI is critical as it forms the basis of how users interact with and perceive your app. Android offers numerous classes that developers leverage and customize while also providing a general framework that users come to rely on.

For example, Android provides a general purpose solution for a top navigation system called the ActionBar. It also provides support for a NavigationDrawer that users can slide open and close by tapping an ActionBar menu button or swiping the left edge of the screen. Android provides an abundance of UI classes and widgets to lay out views, create animations, perform custom drawing, display drawables (icons, bitmaps, shapes, etc.), and more.

Much of an Android UI can be specified with XML, but one can also write custom subclasses that extend Android UI classes to create custom views and behaviors. The scope of the UI is quite broad (it even includes media playback, video, audio, phone vibration, for example), so we can’t cover everything here, but we’ll highlight some key areas that solid dedicated Android developers should be well versed in.

Q: What are Activities and Fragments? When and why should you use one over the other?

An Activity is a user interface component that represents the main focus of attention on a screen. In contrast, Fragments, introduced as tablets emerged with larger screens, are reusable components that are attached to and displayed within activities. Multiple fragments can be shown at once within an activity. While it’s possible to develop a UI only using Activities, this is generally a bad idea since their code cannot later be reused within other Activities. Elite developers know this and write fragments (sometimes used within trivial activities) to future proof their app. With this approach, the activity supports its attached fragments, letting the fragments, their layouts and views handle the lion’s share of user interface.

For example, let’s say you want the user to be able to horizontally scroll through a set of pages where each may show a list, photo, photo gallery, dashboard, or form. Here you might use a ViewPager in your Activity whose items are fragments that handle each of those unique user interface functions separately. If the developer had written these pages as Activities, they would have had to refactor them as fragments.

Also note that, while you can use an Activity without a Fragment, the reverse isn’t true.

Q: What are Adapters and when and how are they used?

It’s tough to develop an Android app without using an adapter somewhere because they are so important.

Where do adapters fit in? They bridge the Model and View (e.g. AdapterViews such as ListViews, GridViews, Spinners and ViewPagers) with underlying data. They provide access to data items and are responsible for creating a view for each item in the data set.

Android doesn’t adopt the MVC pattern per se. You define the Model that works for you. Android helps you layout and render views, and you customize Android’s Activities and Fragments that typically act as Controllers.

Novice developers might try to get away with using simple helper adapters like ArrayAdapter, SimpleAdapter and SimpleCursorAdapter when possible, but these are usually too limiting for some of the more complex views typically required by today’s apps. Master developers will write adapters that extend BaseAdapter directly, because it is more powerful and flexible than the subclass helpers mentioned above.

The following snippet shows a custom ContactAdapter that displays contacts in a ListView. (Note: Only the more important methods required are shown.)

// A basic data model for illustrative purposes
class Contact {
    public int id;
    public String name;
    public String phone;
}

public class ContactAdapter extends BaseAdapter implements ListAdapter {
    Context mContext;
    List<Contact> mContacts;

    public ContactAdapter(Context context) {
        mContext = context;
    }
    
    // Call this method to attach data to this adapter, and call when the data changes.
    public void newData(List<Contact> data) {
        mContacts = data;
        // Inform AdapterView that data has change and to redraw if necessary.
        notifyDataSetChanged(); 
    }

    // The crux of the adapter -- bind data to the view layout.
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Contact contact = mContacts.get(position);
        LinearLayout view = (LinearLayout) convertView;
        if (view == null) {
            // "Inflate" our contact.xml view into existence.
            LayoutInflater inflater = (LayoutInflater)
                mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = (LinearLayout) inflater.inflate(R.layout.contact, null);
        }
        // Bind the data to their appropriate TextViews in the layout.
        ((TextView)view.findViewById(R.id.name)).setText(contact.name);
        ((TextView)view.findViewById(R.id.phone)).setText(contact.phone);
        // ... etc. ...
        return view;
    }
}

Performance and Responsiveness

Users are so demanding. Your app must perform and be responsive or people will become frustrated and simply stop using it.

While requirements for an app should clearly define acceptable response times (although shorter is always better), developers should themselves have a general sense for what is reasonable and take measures to optimize performance accordingly. For example, when fetching a lot data from a server, steps should be taken to avoid locking up the user interface (i.e., by loading the data on a background thread).

Seasoned Android developers can be expected to have a variety of performance optimization tricks up their sleeves. The questions that follow aim to evaluate their acumen in this regard.

Q: What are some ways to optimize View usage?

If not careful, the unwitting Android developer can easily get carried away with creating more views in their layouts than necessary. The more views you can remove from your layouts, the more responsive your app becomes. Fewer views means less memory consumed and reduced garbage collection, as well as less work initializing, laying out, drawing, and traversing views.

Poor design becomes quickly apparent, for example, when trying to scroll rapidly through unoptimized layouts, which can appear sluggish and jerky. If particularly bad, the scrolling experience might become unusable, especially on lower-end devices with slower CPUs. Here are some view optimization techniques an experienced Android developer should be expected to be familiar with.

Technique #1: Optimize views in layouts.

Layouts are XML resource files that define views for activities and fragments. Because their design is so important to application performance, Google has written an entire training guide on the subject of Optimizing Layout Hierarchies.

Let’s take the following layout as an example:

This layout consists of four views: a root level horizontal LinearLayout that encapsulates an ImageView and a vertical LinearLayout that contains two TextViews. This results in a three level hierarchy.

This layout can be optimized by flattening its hierarchy to two levels by using a single root RelativeLayout and dropping the second LinearLayout altogether. The ImageView can be positioned to hug the left side of the parent RelativeLayout and the TextViews can hug the ImageView or the right side of the parent. The savings in speed and memory may not seem like much individually, but when applied to numerous ListView elements (for example), it can add up quickly and dramatically affect performance.

Technique #2: Use the <merge> tag in your layout files.

It’s smart to use the <merge> tag if possible when defining a view that is intended to be inflated and added to an existing ViewGroup, such as a GridView or ListView. This avoids creating an unnecessary middleman ViewGroup such as RelativeLayout or LinearLayout just to encapsulate child views. The <merge> tag is simply a placeholder for the parent view that its children will be attached to. In the following example, only the ImageView will be added to the parent, thereby eliminating the need for one of the encapsulating views.

Consider the following layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

The above use of RelativeLayout, though standard practice, can be eliminated by using a <merge> tag as follows, thereby optimizing this layout:

<!-- The merge tag represents the parent view of this layout -->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    
    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</merge>

Now we’re using one less view!

Technique #3: Consider using a ViewHolder pattern, but do so judiciously.

Use of the ViewHolder pattern can improve performance, but it is not a perfect solution. In fact, some would argue that it is really an anti-pattern. In the next question, we discuss the advantages and disadvantages of the ViewHolder approach. These issues should all be carefully weighed and considered before deciding if, where, and when to employ this technique.

Q: What is the ViewHolder pattern and how is it employed? What are some reasons for, and against, using it? What are some alternatives?

One of the first patterns novice Android developers are introduced to is the ViewHolder pattern—which, as previously noted, and as will be further discussed, some might refer to as an anti-pattern.

When we wish to display lists of items in Android UI, we typically use:

  • A concrete AdapterView subclass such as ListView, GridView, etc.
  • An underlying data set, typically an array of POJOs or a Cursor (a set of database rows)
  • An Adapter class responsible for creating and populating Views with specified data elements

The AdapterView attempts to recycle Views that are no longer displayed on-screen. This simple but effective technique allows applications to avoid:

  • Incurring the cost of garbage collection
  • Incurring the cost of layout inflation

An additional cost that can be avoided relates to calling View.findViewById() repeatedly to locate child views within a layout. Calls to View.findViewById() are expensive because sizable chunks of the layout (a hierarchical structure) must be traversed on each call to find a desired child View within a potentially complex layout. There can be noticeable lag when rapidly scrolling through a list with nested layouts, leaving most developers with an ugly problem in search of a solution.

Enter the ViewHolder caching pattern. But first, let’s put this into historical perspective. Before Android 2.2 (Froyo), the performance of the Dalvik VM and its Garbage Collector were dismal, so it was in this context and to help address this issue that the ViewHolder pattern came into being.

However, with the inclusion of a JIT compiler and vast improvements in the Garbage Collector, the cost of not caching View.findViewById() has decreased dramatically (although it’s still worthwhile and not expensive in terms of developer effort). ViewHolder has therefore become a less necessary approach, which is particularly problematic given some of its negative side effects, such as:

Here’s the latest that Google has to say about ViewHolder, in a nutshell. Define a class to cache the results of View.findViewById():

static class ViewHolder {
  		TextView text;
  		TextView timestamp;
  		ImageView icon;
  		ProgressBar progress;
  		int position;
}

And then in getView() of your Adapter class, cache its results:

ViewHolder holder = new ViewHolder();
holder.icon = (ImageView) convertView.findViewById(R.id.listitem_image);
holder.text = (TextView) convertView.findViewById(R.id.listitem_text);
holder.timestamp = (TextView) convertView.findViewById(R.id.listitem_timestamp);
holder.progress = (ProgressBar) convertView.findViewById(R.id.progress_spinner);
convertView.setTag(holder);

Savvy developers recognize that ViewHolder is a struct that is populated via calls to View.findViewById(). The ViewHolder struct is stored in the parent View via View.setTag(). When recycling a View, we can tap the ViewHolder cache:

ViewHolder holder = (ViewHolder) convertView.getTag(); 

Now this technique is great for writing tutorials. However, for example, when you need to add OnClickListeners, change drawables according to state changes, etc, you wind up with your Adapter class doing a huge amount of work that it should not be doing.

What can we do differently? Referencing the ContactAdapter code from a previous question, we’ll modify the inflated View (in this case LinearLayout) to cache child views in a separate concern, the parent View itself:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
   Contact contact = mContacts.get(position);
   ContactView view = (ContactView) convertView;
   if (view == null) {
       // "Inflate" our contact.xml view into existence.
       LayoutInflater inflater = (LayoutInflater)
           mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
       view = (LinearLayout) inflater.inflate(R.layout.contact, null);
        }
   // Bind contact data to appropriate child Views in the layout.
   view.setModel(contact);
   return view;
}

All we need to do now is edit our Contact layout and replace its root element with ContactView (shown below) instead of LinearLayout, say. That’s it! We now have proper separation of concerns, single purpose (less cluttered) classes, and we avoid using View.setTag() and View.getTag() methods without overhead while caching child Views.

public class ContactView extends LinearLayout {
  private Contact model;
  private TextView name;
  private TextView phone;

  @Override
  protected void onFinishInflate() {
  	this.name = (TextView)view.findViewById(R.id.name);
    this.phone = (TextView)view.findViewById(R.id.phone);
  }
  
  public void setModel(Contact model) { 
    this.model = model; 
    bindModel();
  }
  
  private void bindModel() {
    this.name.setText(model.name);
    this.phone.setText(model.phone);
  }
}

Q: What is an ANR? What causes them and how can they be avoided?

ANR refers to Android’s infamous Application Not Responding dialog that apps can trigger when they spend too much time computing on the main thread. The main thread handles the Android UI, so doing more work there slows down responsiveness. An ANR is therefore often a kick-in-the-pants when you aren’t backgrounding longer running tasks.

Examples of tasks that can cause ANR’s include:

  • Uploading/loading data to/from the cloud
  • Saving/loading cached data to/from disk
  • Sorting, filtering and searching data

What these operations have in common is that they can all be slow. They are often resource bound, meaning that they often take time, sometimes much longer than desired or expected.

With that in mind, any work to be performed that is not UI-related, especially the above types of resource-bound tasks, should be done on a background thread. Android has several ways to accomplish background work and has spawned some good 3rd party open source libraries for this as well.

Several threading options exist, each with its own advantages and disadvantages. Asynchronous computation is inherently complex and these classes and interfaces attempt to simplify the effort. Check out Google’s Processes and Threads guide for more detailed info.

Let’s explore some of the more useful threading options in Android:

AsyncTask

AsyncTask is a helper class that lets you spawn a short background operation. It’s most commonly used to display results on the UI thread. This is usually the first class novice developers learn how to use when dealing with asychronicity, since it avoids having to setup and use threads directly.

Unfortunately, AsyncTask has some serious gotchas. It has become somewhat of a crutch when other, more advanced, threading options ought to be used. Google has flip-flopped over the years on the runtime behavior of AsyncTask, from first being run serially (with other AsyncTasks on a single background thread), to being run in parallel, and then back to serial! This means that, if the type of concurrency (i.e., serial vs. parallel) is important to your app, you must check the running SDK version of Android before using an AsyncTask. Developers may be better off using a HandlerThread or Executor as a result.

Thread

The Thread class is Android’s most basic execution environment with its own call stack, arguments, and local variables. Every app has one main thread (for user interface) and other threads in a system thread group. You can either (a) subclass Thread and execute code within its run() method or (b) pass a Runnable to its constructor which then starts its execution by calling its start() method. Once started, the thread can yield to other threads or can sleep. You can’t externally stop a thread though; your only options are to interrupt it, wait for it to complete on its own, or join() it.

HandlerThread

Whereas Threads don’t have Loopers by default, a HandlerThread is a Thread that has a Looper attached. The Looper provides a Handler that allows message passing between threads. A Handler also allows for executing Runnable tasks on its attached thread, either immediately or at a later point in time.

Here is how you might instantiate a HandlerThread on which to post tasks to be executed:

class VotingActivity {
    private Runnable processVotes = new Runnable() {
        public void run() {
        }
    };
    
    public void onCreate (Bundle savedInstanceState) {
        HandlerThread handlerThread = new HandlerThread("Voting Tasks");
        handlerThread.start();
        Handler handler = new Handler(handlerThread.getLooper());
        // Now let's execute a Runnable task ASAP on the new thread we just created:
        handler.post(new Runnable() {
            public void run() {
                // Accept a vote, say.
            }
        });
        // Let's also schedule a task to execute 10 seconds in the future on the new thread:
        handler.postDelayed(processVotes, 10000);
    }
}

And here’s how we might set up a HandlerThread to process messages sequentially:

class DownloadThread extends HandlerThread {
    public static final int START_MSG = 0;
    public static final int STOP_MSG = 1;

    DownloadThread(String name) {
        super(name);
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case START_MSG:
                // Start downloading...
                break;
            case STOP_MSG:
                // Stop downloading...
                break;
            default:
                break;
        }
    }
}

And then we could spawn and use this thread as follows:

class MainActivity extends Activity {
    public void onCreate (Bundle savedInstanceState) {
        // Set up our DownloadThread for receiving messages.
        DownloadThread downloadThread = new DownloadThread("Image Downloader");
        downloadThread.start();
        Handler downloadHandler = new Handler(downloadThread.getLooper());
    }
    
    public void startDownloading() {
        downloadHandler.sendEmptyMessage(DownloadThread.START_MSG);
    }
    
    public void stopDownloading() {
        downloadHandler.sendEmptyMessage(DownloadThread.STOP_MSG);
    }
}

ExecutorService and ThreadPoolExecutor

ThreadPoolExecutor implements the ExecutorService interface that executes submitted tasks on one of several pooled threads. Thread pooling usually improves performance when executing many tasks due to the reduced overhead of per-task invocation. If you need to execute numerous tasks asynchronously, you can spawn workers fairly easily with this mechanism. Google notes that ThreadPoolExecutor is somewhat of a configurable kitchen sink, and developers are encouraged to use preconfigured versions such as newCachedThreadPool(), newFixedThreadPool() and newSingleThreadExecutor().

Q: What are Loaders? When and why are they used?

In the incessant quest to offload work from the main thread, Android introduced Loaders (see LoaderManager and Loader classes). Loaders simplify asynchronous loading of data in activities and fragments that usually feed adapters. They monitor their data source and deliver new results when content changes. So, instead of blocking and waiting for data to arrive (from your cloud or disk, for example), use a Loader. See Google’s Loaders Guide for more details.

Q: What is RxJava and why is it so cool?

Not every Android developer knows about this gem, so it scores major brownie points in our book when they do. It’s a big innovation and perhaps the most exciting part of our post. RxJava is Netflix’s open source port of Microsoft’s Reactive Extensions library. Reactive programming is a programming paradigm concerned with data flow and change. Reactive programming has been around for a while, but RxJava hasn’t. RxJava is super useful for writing synchronous/asynchronous, event-based observable sequences. It was designed for efficiently querying and consuming data (in motion).

RxJava is not an Android-specific library, but can make a huge impact on Android apps, depending on how it’s used. It’s useful with concurrent and/or asynchronous apps that require low latency. For example, a prime use case for it would be to load data asynchronously without having to think too much about threads, handlers, or executors. You might use RxJava to load data for adapters; e.g., subscribe to data of interest on the UI thread, schedule the work to be performed on a background thread, then observe the results back on the UI thread for display.

RxJava allows you to chain data and events, and create sequences that select, filter, transpose, compose, and combine data before a final observer is notified with results. We can’t possibly cover RxJava here in the depth it deserves, but we wanted to mention it because elite developers should be aware of it. You can read more about it here.

Q: How would you cache numerous large images from the net?

If you are developing an image gallery app like Instagram or Pinterest, caching many (large) images from your server becomes critical. In the quest for optimal performance, you want to present images rapidly, so caching them to avoid reloading them from the network is essential. Since you can’t cache too many large multi-megabyte images in RAM (since Android memory is volatile and is a limited resource), you really have no alternative but to cache images on disk (flash).

Rather than writing your own cache class(es), you could instead leverage and wrap DiskLruCache. It’s an indispensable open source solution that experienced Android developers should be aware of. It can be used to cache any kind of data to a file system directory, bounded by a size that you specify.

Beyond Android Proper

While Google’s Android team employs many great engineers, it can’t supply or anticipate every solution imaginable for new problems developers face. That’s where 3rd party open source, and even other Google teams, come in.

Savvy Android developers will therefore be familiar with a number of the more valuable libraries that have emerged in recent years. Theses can be used to retrofit new Android features to older handsets, augment existing features, or introduce new functionality.

Those that extend new Android features to older handsets, however, are becoming less crucial as users have been upgrading to newer Android versions and devices. But that said, Android developers do have a large fragmentation of Android devices, versions and brands to contend with, unlike iOS.

Q: What are some of the more useful Android open source libraries and how can you leverage them?

There are numerous open source libraries and add-ons available, from Google and elsewhere, that seasoned Android developers will commonly leverage. Some of the more useful ones include:

  • ActionBarSherlock — ActionBarSherlock is an extension of Android’s support library designed to facilitate the use of the action bar design pattern across all versions of Android with a single API. It allows you to easily develop an application with an action bar for every version of Android from 2.x and up.
  • DiskLruCache — As mentioned above, DiskLruCache is a powerful, yet simple, least-recently-used (LRU) caching implementation for storing data on disk, with bounded pool size.
  • EspressoAnnounced by Google in October 2013 and still in developer preview, Espresso is a new UI testing framework whose goal is to make it easy for developers to write reliable UI tests. Most importantly, Espresso removes the need to think about the complexity of multi-threaded testing. Espresso is already being used by a number of Google applications (Drive, Maps, Google+, and more).
  • Guava — Google’s Guava project contains several core libraries actively used by Google internally: collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, and somewhat of a mishmash of very useful classes. See Guava’s wiki for more information. Its purpose is to make Java “more pleasant,” improve defensive programming, add optimizations and improve efficiency. It fills out and improves upon common classes like Collections, Math, Reflection, strings, Ranges, Hashing, I/O and more.
  • NineOldAndroids — NineOldAndroids makes the dramatically new and improved Android Honeycomb (3.0) animation API available to older versions back to 1.0 and forward compatible to the latest release of Android. Animation prior to Honeycomb was pretty darn limited. The new API offers much more power and flexibility to animate objects and actually reposition views with rotation, translation, alpha and scale primitives, for example. The library provides a wrapper that works across all Android versions.
  • Protocol Buffers — Google’s Protocol Buffers is a language-neutral, platform-neutral, extensible mechanism for serializing structured data, that provides a viable alternative to JSON or XML. It’s an efficient way to transport object data, for instance in its original binary format without needing to (un)marshal. Data transported is “smaller, faster, simpler”—in Google’s words.
  • RxJava — As mentioned above, RxJava is a Reactive Extension that lets you create asynchronous, event-based code using observable sequences, which can be invaluable in many circumstances.
  • Volley — Volley is a relatively recent Google library introduced at Google I/O May 2013 that makes networking for Android apps faster and easier. Oddly, Google hasn’t yet published its own tutorial or documentation other than the source, making some developers skeptical or wary of it, but several have written tutorials such as this and this. Highlights include a view that automatically loads images, HTTP request queuing with prioritization, and automatic Android-version-specific selection of the best HTTP library.

Debugging and Tuning

Experienced developers rely on great tools to help them build great software, especially for testing and optimization purposes. Android was a bit slow at first to offer them, but its tool chest has finally filled out. Android offers runtime detection of problems, attached classes that can help detect problems. There are also external tools like DDMS to view memory usage, find leaks, view thread usage, observe view hierarchies and more.

Q: What is the Don’t Keep Activities developer option and why is it useful?

Google offers a wide array of runtime debugging options for devices that can be activated under Settings > Developer options. One of the more useful ones is Don’t keep activities which immediately destroys an activity when the user leaves it. It’s useful for testing activity save and restore (i.e., the onSaveInstanceState(Bundle) and onCreate(android.os.Bundle) code path), which would otherwise be difficult to trigger. It can also uncover other symmetry problems with your activity’s life cycle, such as properly opening and closing resources between onResume() and onPause() callbacks, for instance.

Q: What is StrictMode and why is it useful?

In the never-ending quest to improve app responsiveness and keep the UI running smoothly, StrictMode is a valuable Android tool to help detect accidental disk and network access on the main thread (or any thread for that matter).

In the development version of your app (never leave StrictMode enabled in a released app!), you tell Android what problems you’re interested in finding and define the “penalties” to be applied (i.e., what to do) if they’re detected. While not every problem that it finds necessarily needs to be fixed, nor can you be certain that it will find every problem, it provides a highly useful window into your app’s imperfections (if any).

Here’s how you might enable StrictMode in your Application’s onCreate method:

public void onCreate() {
    // Only enable when developing your app!
    if (DEVELOPER_MODE) {
        // Tell Android what thread issues you want to detect and what to do when found.
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
            .detectDiskReads()
            .detectDiskWrites()
            .detectNetwork()    // or use .detectAll() for all detectable problems
            .penaltyLog()
            .build());
        // Tell Android what VM issues you want to detect and what to do when found.
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
            .detectLeakedSqlLiteObjects()
            .detectLeakedClosableObjects()
            .penaltyLog()       // Log the problem
            .penaltyDeath()     // Then kill the app
            .build());
    }
    super.onCreate();
}

Q: What is the “lint” tool? What does it do and how would you use it?

Lint is an Android tool that scans your project and generates a detailed report containing errors and warnings in your code and resource files that you might consider fixing. It’s not perfect, and sometimes it report false positives (that top developers know to take with a grain of salt), but it’s still a useful tool. For example, it can:

  • Detect unused files and resources to reduce app bloat
  • Tell you where you should be recycling TypedArrays after use
  • Identify where you might be overdrawing backgrounds of overlaying views
  • … plus many other issues

You can enable your IDE to alert you to these issues in source files as you edit, but it’s often a good idea to run lint on the command line anyway to generate a complete report periodically, or as a biproduct of your automated build. For more info, see Improving your code with lint.

Wrap Up

We’ve only just scratched the surface of Android app development, highlighting some of the more important aspects and nuances of the platform, as well as tools to leverage.

Given Android’s complexity, it can take a mobile application developer years to become truly proficient. Android offers enormous potential given its massive market penetration today and its rich framework. Finding Android Jedi masters is a challenge given their demand and the time it takes to become one. We hope you find the questions presented in this post to be helpful toward that goal as you search for elite, cream-of-the-crop developers.

Top Android Developers are in High Demand.

Start Hiring