≡ Menu

How To Register Listeners and Handle Events in Android App Programming

Handling events appropriately is an important aspect of developing any Android Application.

A listener that is an interface with callback functions is used by Android to do the dispatch of event.

When user triggers an event of one component, OS will check whether there is a user level listener registered for it. If yes, callback function will be called so user program can do action for the event.

According to the number of listeners can be registered for the event, there are two kinds of event, single-listener event and multiple-listener event. For single-listener event, only one listener is allowed, and for multiple-listener event, there can be more than one listener.

Take View for example, as shown in below table, there are 12 listeners:

Event Listener single-listener multiple-listener
Attach state change OnAttachStateChangeListener X
Click OnClickListener X
Create of context menu OnCreateContextMenuListener X
Drag OnDragListener X
Focus change OnFocusChangeListener X
Generic motion OnGenericMotionListener X
Hover OnHoverListener X
Hardware key OnKeyListener X
Layout change OnLayoutChangeListener X
Long click OnLongClickListener X
Status bar visibility change OnSystemUiVisibilityChangeListener X
Touch OnTouchListener X

Two of them (OnAttachStateChangeListener and OnLayoutChangeListener) are used for multiple-listener event, and the rest ten of them are used for single-listener event.

We must register corresponding listener to the target object if we want to act for an event from it. By convention, member function setListenerName is used for the registration of single listener and addListenerName is used for the registration of multiple listeners. For single-listener registration function, if called multiple times, only the last one is effective.

As we explained earlier, there are three types of android app menus for which you can write events and handle it appropriately.

Register a Listener

The listener registration function accepts two kinds of inputs: an interface object, and an object of class that implements the interface. For the later, a named, anonymous class/interface and even the parent activity is applicable. As one view only has one activity, so the last method is not practical for multiple-listener event.

1. Interface Variable

  TextView tv = (TextView) this.findViewById(R.id.hello_world);
  //Interface
  View.OnClickListener m_click_itf = new View.OnClickListener() {
          	@Override
          	public void onClick(View v) {
                   	// TODO Auto-generated method stub
                   	
          	}
  };
  tv.setOnClickListener(m_click_itf);

2. Named Class

  TextView tv = (TextView) this.findViewById(R.id.hello_world);
  //Named Class
  class ClickHandler implements View.OnClickListener {
          	@Override
          	public void onClick(View v) {
                   	// TODO Auto-generated method stub
                   	
          	}
  }
  ClickHandler m_click_lister = new ClickHandler();
  tv.setOnClickListener(m_click_lister);

3. Anonymous Class/Interface

  TextView tv = (TextView) this.findViewById(R.id.hello_world);
  //Anonymous Class
  tv.setOnClickListener(new View.OnClickListener() {
          	@Override
          	public void onClick(View v) {
                   	// TODO Auto-generated method stub
                   	
          	}
  });

4. Activity

public class MainActivity extends Activity implements View.OnClickListener {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
         	super.onCreate(savedInstanceState);
         	setContentView(R.layout.activity_main);
         	TextView tv = (TextView) this.findViewById(R.id.hello_world);
         	tv.setOnClickListener(this);
  }
  @Override
  public void onClick(View v) {
         	// TODO Auto-generated method stub
         	
  }
}

Action for an event

Technically it is an efficient way to assign a common stub listener for a group of objects. There is a View object passed to the callback which is the owner of the event. For the object created by layout XML resource, as ID is unique across the project, it is safe to use ID as a distinguisher.

  @Override
  public void onClick(View v) {
         	// TODO Auto-generated method stub
         	switch (v.getId()) {
                  	case R.id.hello_world:
                           	//act for the click
         	}
  }

Sometimes, it may be a good idea to assign the IDs from 0 to n for programmatically created components, and use the ID as an index for more efficient data processing. But if there are two groups declare an overlapped id range, it would be better use separate listener for different groups, so that ID will be unique inside group.

Why multi-listener?

There are at least two agents in android system, the SDK and the user. If both of them want to know the status of an event, it must be defined as a multi-listener event. Take OnLayoutChangeListener for example. LayoutTransition.java in animate package need the layout changed event to do the animate properly, while user maybe also intent to do some operations at the same time. So, the OnLayoutChangeListener can be registered for multiple times.

Mechanism of the listener

We also take View.onClickListener for example. When user program call the setOnClickListener, the interface is stored in a ListenerInfo object.

The View class filters the click event from pointer event dispatch: dispatchPointerEvent -> dispatchTouchEvent -> onTouchEvent -> performClick. In the performClick, user registered callback will be called.

public void setOnClickListener(OnClickListener l) {
    if (!isClickable()) {
    	setClickable(true);
    }
    getListenerInfo().mOnClickListener = l;
}
public boolean performClick() {
    sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
    ListenerInfo li = mListenerInfo;
    if (li != null && li.mOnClickListener != null) {
        playSoundEffect(SoundEffectConstants.CLICK);
        li.mOnClickListener.onClick(this);
    	return true;
    }
    return false;
}
Add your comment

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

Comments on this entry are closed.

  • Bob January 23, 2014, 10:30 am

    Thanks. Very timely and useful article