Android 11推荐使用Handler的构造方法

背景

Android 11(即API 30:Android R)弃用了Handler默认的无参构造方法
Android 11推荐使用Handler的构造方法_第1张图片

  • 参考链接:Android 开发者文档指南-Handler
    Android 11推荐使用Handler的构造方法_第2张图片

源代码(android.os.Handler)

	//API 30,Android 11
    /**
     * Default constructor associates this handler with the {@link Looper} for the
     * current thread.
     *
     * If this thread does not have a looper, this handler won't be able to receive messages
     * so an exception is thrown.
     *
     * @deprecated Implicitly choosing a Looper during Handler construction can lead to bugs
     *   where operations are silently lost (if the Handler is not expecting new tasks and quits),
     *   crashes (if a handler is sometimes created on a thread without a Looper active), or race
     *   conditions, where the thread a handler is associated with is not what the author
     *   anticipated. Instead, use an {@link java.util.concurrent.Executor} or specify the Looper
     *   explicitly, using {@link Looper#getMainLooper}, {link android.view.View#getHandler}, or
     *   similar. If the implicit thread local behavior is required for compatibility, use
     *   {@code new Handler(Looper.myLooper())} to make it clear to readers.
     *
     */
    @Deprecated
    public Handler() {
        this(null, false);
    }
  • 原因:

@deprecated Implicitly choosing a Looper during Handler construction can lead to bugs
隐式的Looper会导致一些错误(场景如下)
where operations are silently lost (if the Handler is not expecting new tasks and quits),
操作丢失
crashes (if a handler is sometimes created on a thread without a Looper active), or race conditions,
程序崩溃和紊乱情况
where the thread a handler is associated with is not what the author anticipated.
非期望的Handler

推荐使用方式

  1. 使用Executor接口或者是明确指定Looper

use an {@link java.util.concurrent.Executor} or specify the
Looper explicitly

  1. 使用Looper静态方法getMainLooper()或View实例方法getHandler()

using {@link Looper#getMainLooper}, {link
android.view.View#getHandler}, or similar.

参考链接:Android开发者文档-Looper

  • 方法源代码
//android.os.Looper
public final class Looper{
	//...
    /**
     * Returns the application's main looper, which lives in the main thread of the application.
     */
    public static Looper getMainLooper() {
        synchronized (Looper.class) {
            return sMainLooper;
        }
    }
}

//android.view.View
@UiThread
public class View implements Drawable.Callback, KeyEvent.Callback,
        AccessibilityEventSource {
    //....
    /**
     * @return A handler associated with the thread running the View. This
     * handler can be used to pump events in the UI events queue.
     */
    public Handler getHandler() {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            return attachInfo.mHandler;
        }
        return null;
    }
}    
  • 例子
//Looper的静态方法getMainLooper()作为Handler构造方法的参数
private Handler looperHandler = new Handler(Looper.getMainLooper());

//view的getHandler()方法必须先存在实例对象,方法直接返回Handler对象
//@param view View的实例对象
Handler viewHandler = view.getHandler();
  1. 使用Looper的静态方法myLooper()

If the implicit thread local behavior is required for compatibility, use {@code new Handler(Looper.myLooper())} to make it clear to readers.

  • 方法源代码:
	//android.os.Looper
    /**
     * Return the Looper object associated with the current thread.  Returns
     * null if the calling thread is not associated with a Looper.
     */
    public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }
  • 例子:
private Handler handler = new Handler(Looper.myLooper());

完整代码片断案例

  private Handler mHandler = new Handler(Looper.getMainLooper()){
        @Override
        public void handleMessage(Message msg){
            Log.v(TAG, "handleMessage(" + msg + ")");
            AsyncResult asyncResult;
            switch (msg.what){
                case Constant.EVENT_DEMO:
                    asyncResult = (AsyncResult) msg.obj;
                    if (asyncResult.exception == null) {
                        doOperation(asyncResult);
                    } else {
                        Log.d(TAG, "doOperation asyncResult.exception = " + asyncResult.exception);
                    }
                    break;
                default:
                    Log.e(TAG, "Unknown msg " + msg.what);
                    break;
            }
        }
    };

你可能感兴趣的:(Android,AOSP,Handler,Android)