Engineering Speaks: Cleaning up your messy Android code

Messing up code is relatively simple – quickly add a couple of new features and skip the periodic refactoring and lo! Messy code!

A more structured code helps reduce time in adding newer functionalities and also makes it easier to add new people on to your project. I happened to come across the following tweet that sums up code quality.

This post attempts to help the uninitiated (read:beginner) Android developer write a less cluttered and more functional code. Here are some of my learnings along the way.

Click listeners

A convenient way to react to a click event would be to add a click listener to each view and implement the interface right there.Well, that’s what most of us do in the beginning. But as the app advances and views get complicated, we end up with a lot of click implementations dispersed throughout the code.


mButton.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
      
   }
});

To do way with this messy affair, it is always recommended to have the class implement the click listener.


public class MainActivity extends Activity implements View.OnClickListener {
}

override the onClick method,


@Override
public void onClick(View view) {
   switch (view.getId()){
       case R.id.button:
           break;
   }
}

and set the listener to the view

mButton.setOnClickListener(this);

This way all your click event based code exists in one place and is easily accessible.

Fragment to Activity communication

Modern android applications make extensive use of fragments. These fragments communicate with the parent activity or fragment at user defined events. It is possible to pass the parent object (context) and call a public method of the parent. But this process can be made legible & clean by using interfaces. Define an interface in you fragment and set the listener.

public class MainFragment extends DialogFragment {
   Callback mCallback;
  
   void MainFragment(Callback callback){
       mCallback = callback;//setting the listener
   }
  
   //Defining interface
   public interface Callback {
       void onConfirmation();
   }
}

Implement the callback in the parent activity/fragment and override the methods defined.


public class MainActivity extends Activity implements MainFragment.Callback {

   @Override
   public void onConfirmation() {
       //do something
   }

This way you can define your app behavior easily without having to sift through the code whenever the logic for a particular event changes.

Method Length

There is no fixed rule on the length of a method/function but usually, I try to ensure that one method does “one job”. This ensures a high level of readability and also makes class structuring much simpler. It is difficult to imagine how long a method would stretch at the time of implementation but the key is to go through periodic refactoring. For instance, you could pull out the code from a method if it’s too long or does multiple jobs, and make another one. It is common that a certain piece of code has to be used in multiple parts of the project, in that case, separate your methods to ensure re-usability.

Magic Numbers and Strings

What goes around comes around. No one will know this better than the person who has spent several hours together trying to figure out what went wrong with the code and finally realize that it was the hard coded value. Well, magic numbers/strings is an input value that is hard coded into the code.

Try and avoid using magic numbers or strings as they may seem magical while hacking functionalities but will come back to haunt you. It is always better to define constants in a utility class or at least as a class member.

In the case of strings, localization becomes an issue with hardcoded values. What would have taken only a few hours, could end up taking days!  You must also be vigilant while defining sizes in the layout files as it could lead to a similar mess.

ViewGroup Hierarchy

This is more of an optimization related issue but also serves well in simplifying the views.
It is always advised to use fewer nesting of views. Nesting multiple LinearLayouts could prove to be expensive. You will be able to find more information on optimizing your layout structure here.

Code Conventions

Code conventions are guidelines for specific programming languages that recommend certain programming practices. By using these coding conventions one can ensure that the code is readable and subscribes to a higher standard of maintainability. Oracle’s explanation on why code conventions are necessary is quite apt.

“ 80% of the lifetime cost of a piece of software goes to maintenance.Hardly any software is maintained for its whole life by the original author. Code conventions improve the readability of the software, allowing engineers to understand new code more quickly and thoroughly. If you ship your source code as a product, you need to make sure it is as well packaged and clean as any other product you create.”

You could have a look at the coding conventions for java here.

Hope these tips help you out in simplifying your code base. You can hit me up on any android dev related topics at @anish_hg .

Made with in USA & India
Share On Facebook
Share On Twitter
Share On Linkedin