Tuesday, April 24, 2012

Message and Handlers


Message and Handlers

Handlers are a useful too for doing a task within a class in response to a change in a variable state or to an action. A common use for a handler is to update the UI once a thread is done processing (if you choose to do it this way versus asynctask.)  I often use a handler when I want an activity to do something in response to the completion of a service or to button clicks or to form validation and other things that might generate UI changes. For example, let's say that the app starts up and kicks off a service. When the service completes, it fires an Intent that the activity is listening for which triggers the handler to redirect off a splash screen either to a login screen or a main screen based on what the service returns.

Now how does the activity know what to do? By opening up the intent and getting the bundle. The example below uses a handler to receive a broadcast from a service category download. If the service has processed successfully, the icon will update itself to a success icon, otherwise the error message from the service will be displayed.   The service generates an intent with a bundle, and broadcasts it.  The activity listens for that broadcast and processes it (code below is basically logging the intent and builds a message out of it to pass to the handler.The trigger to update the UI is a message that I create through a utility method.


 private BroadcastReceiver mReceiver = new BroadcastReceiver() 

 { 

      @Override 

      public void onReceive(Context context, Intent intent) 

      { 

           Bundle data= intent.getExtras(); 

           mHaveCategoryError = data.getBoolean(GlobalConstants.EXTRA_ERROR_STATUS, false); 

           mDoRedirect = data.getBoolean(GlobalConstants.EXTRA_DO_REDIRECT, true); 

           String error= data.getString(GlobalConstants.EXTRA_ERROR_MESSAGE); 

           HashMap<String, String> dataList = new HashMap<String, String>(); 

                dataList.put(GlobalConstants.EXTRA_ERROR_MESSAGE, error); 

           Message message = Utils.createMessage(1, dataList); 

           handler.dispatchMessage(message);           

      } 

 }; 

 private Handler handler = new Handler() { 

      @Override 

      public void handleMessage(Message msg) { 

           Bundle b = msg.getData(); 

           String message = b.getString(GlobalConstants.EXTRA_ERROR_MESSAGE); 

           String messageType = b.getString(GlobalConstants.EXTRA_MESSAGE_TYPE); 

           if (messageType!=null && messageType.equals(GlobalConstants.SERVICE_CATEGORIES_DOWNLOAD)){ 

                ImageView iv1 = (ImageView) findViewById(R.id.categorySpinnerView); 

                TextView statusMessageE = (TextView) findViewById(R.id.categoryStatusMessage); 

                Drawable d= getResources().getDrawable(R.drawable.iconsuccess); 

                if (message!=null) { 

                     d= getResources().getDrawable(R.drawable.iconalert48); 

                       statusMessageE.setText(message); 

                } else { 

                     statusMessageE.setText(getResources().getString(R.string.categoriesDownloaded));      

                } 

                 iv1.clearAnimation(); 

                  iv1.setImageDrawable(d); 

           }  

      } 

 } 

 public static Message createMessage(int messageId, HashMap<String, String> dataList) 

   { 

           Message msg = new Message(); 

           msg.what=messageId; 

           Bundle data = new Bundle(); 

           if (dataList == null) 

           { 

                dataList= new HashMap<String, String>(); 

           } 

           Set<Entry<String, String>> entries = dataList.entrySet(); 

           Iterator<Entry<String, String>> it = entries.iterator(); 

           while (it.hasNext()) 

           { 

                Entry<String, String> entry = (Entry<String, String>) it.next(); 

                data.putString(entry.getKey(), entry.getValue()); 

           } 

           msg.setData(data); 

           return msg; 

   }