Using Android Handler

What is the best way to use a handler. Any benefits. All the examples I came across seem to give an inline version.

Using Handler.Callback tools in the class and method for implementing the interface.

or

Using the Embedded Code Version

 private Handler mHandler = new Handler(){ ....}; 
+7
source share
4 answers

The generic term or these built-in class definitions are Anonymous classes.

You can read more about discussing these issues in Java / Android: anonymous local classes and named classes

Essentially, the main differences are readability, coding speed, reuse, and scope.

From a resource point of view, creating an anonymous class can cause overhead in the garbage collector, as described in Avoid creating unnecessary objects . I’m not sure about the details of creating an anonymous class, but it’s logical that implementing the interface in the class is more efficient.

@WilliamTMallard provided an example of what NOT to do. In his example, a long and syntactically complex handler should be implemented in the class, and not in the anonymous handler, because it is more difficult to read and edit when it is defined in a string.

+5
source

http://developer.android.com/reference/android/os/Handler.html

 package : android.os public class Handler extends Object 

The handler allows you to send and process the Message and Runnable objects associated with the MessageQueue stream. Each Handler instance is associated with one thread and this thread's message queue. When you create a new handler, it is attached to the thread / message queue of the thread that creates it - from this point it will deliver messages and executable files to the message queue and execute them as they exit the queue message.

There are two main uses for a handler:

  • for scheduling messages and executables to be executed as some point in the future; and
  • to set an action to be performed on a thread other than your own.

Exmaple 1

use the handler on the application splash page.

 if (!isFirstIn) { mHandler.sendEmptyMessageDelayed(GO_HOME, SPLASH_DELAY_MILLIS); } else { mHandler.sendEmptyMessageDelayed(GO_GUIDE, SPLASH_DELAY_MILLIS); } /************************************************************************************** *1. Handler */ private Handler mHandler = new Handler() { public void handleMessage(Message msg) { if(isAuto){ switch (msg.what) { case GO_HOME: goHome(); break; case GO_GUIDE: goGuide(); break; } } super.handleMessage(msg); } }; private void goHome() { Intent intent = new Intent(SplashActivity.this, MainAct.class); SplashActivity.this.startActivity(intent); SplashActivity.this.finish(); } private void goGuide() { Intent intent = new Intent(SplashActivity.this, GuideActivity.class); SplashActivity.this.startActivity(intent); SplashActivity.this.finish(); } 

Example 2

use the handler request service in the child thread if the request may take some time.

 new Thread(new Runnable(){ @Override public void run() { String versionPath = Parameters.getCheckVersionPath(); String result = RequestHelper.doGet(versionPath, null); Message msg = new Message(); Bundle data = new Bundle(); data.putString("result",result); msg.setData(data); handler1.sendMessage(msg); } }).start(); handler1 = new Handler(){ @Override public void handleMessage(Message msg) { String result = msg.getData().getString("result"); JSONObject obj; try { obj = new JSONObject(result); Map<String, String> versionInfo = Helper.getSoftwareVersion(obj); if (versionInfo != null) { newVersion = versionInfo.get("version"); updateUrl = versionInfo.get("url"); } } catch (JSONException e) { Log.w("net work error!", e); } } }; 

Example 3

use Handler and Timer to update progress bar.

 logobar = (ImageView) findViewById(R.id.splash_bar);//progress bar. logobarClipe = (ClipDrawable) logobar.getBackground(); timer = new Timer(); timer.schedule(new TimerTask() { public void run() { updateLogoBarHandler.sendEmptyMessage(0); }}, 0, rate); /************************************************************************************** *2. Handler */ //update progress bar. private Handler updateLogoBarHandler = new Handler() { public void handleMessage(Message msg) { if(logobarClipe.getLevel() < 10000){ //1.update image. logobarClipe.setLevel(logobarClipe.getLevel() + rate*2); //2.update text. float percent = logobarClipe.getLevel() /100; String percentTxtVerbose = String.valueOf(percent); String percentTxt = percentTxtVerbose.substring(0, percentTxtVerbose.indexOf('.')) + "%"; bartxt.setText(percentTxt); }else{ timer.cancel(); } super.handleMessage(msg); } }; 
+2
source

This really is not the answer to the above question, because I do not know what the “best way” is, and it probably depends on what you are doing. However, I will explain what I do and why.

I am writing an application that serves as a remote control. There are several actions that will interact with the controlled device, and different things must happen based on the result of the command and the activity with which it arrives. Two things that I didn't like about handlers: A) that they ultimately are a kind of “kitchen sink” design that implements functionality from different sources, and B) that they separate the action (sending a command in my case) from processing the result this action. However, using an anonymous (correct term? I'm such a noob.) Handler as a parameter allows me to maintain the logic together. Here's the pseudo code for my approach:

  command = "Wake up!"; mDeviceInterface.write(command, new Handler() { @Override public void handleMessage(Message msg) { switch(msg.what) { case DeviceInterface.MESSAGE_TIMEOUT: // Process the timeout. announce("Device not responding."); break; case DeviceInterface.MESSAGE_READ: // Process the response. byte[] readBuf = (byte[]) msg.obj; if (readBuf[0] == 0x05) { // Success, update device status. } else { announce("Error!"); break; } } } }); 

(Always remember, it's probably worth what you paid for it.;))

0
source

There is a danger of using anonymous classes in Android. As described in this blog post -

In Java, non-static inner and anonymous classes contain an implicit reference to their outer class.

And here there is the possibility of a leak.

So, the short answer will be: to implement interface methods or use static inner classes (which do not contain a reference to an outer class).

For example, a leak-proof handler might look like this:

 private static class ChangeTextHandler extends Handler { private final WeakReference activity; public ChangeTextHandler(MainActivity activity) { this.activity = new WeakReference<>(activity); } @Override public void handleMessage(Message msg) { MainActivity activity = this.activity.get(); if (activity == null) { Log.e(TAG, "Activity is null ChangeTextHandler.handleMessage()!"); return; } final String text = (String) msg.getData().get(BUNDLE_KEY); if (!TextUtils.isEmpty(text)) { switch (msg.what) { // do something } } } } 

I made a blog post about using handlers , so it’s also worth checking out :)

0
source

All Articles