diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bb17fd6bb..7a79be45ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.16.4 (Aug 29, 2018) +- **New** `EpoxyAsyncUtil` and `AsyncEpoxyController` make it easier to use Epoxy's async behavior out of the box +- **New** Epoxy's background diffing posts messages back to the main thread asynchronously so they are not blocked by waiting for vsync + # 2.16.3 (Aug 24, 2018) - **New** Add `AsyncEpoxyController` for easy access to async support. Change background diffing to post asynchronously to the main thread (https://github.com/airbnb/epoxy/pull/509) diff --git a/epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyAsyncUtil.java b/epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyAsyncUtil.java index 2bf449b421..13bd29b7e9 100644 --- a/epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyAsyncUtil.java +++ b/epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyAsyncUtil.java @@ -2,13 +2,11 @@ import android.os.Build; import android.os.Handler; +import android.os.Handler.Callback; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.support.annotation.MainThread; -import android.support.annotation.Nullable; - -import java.lang.reflect.Constructor; /** * Various helpers for running Epoxy operations off the main thread. @@ -60,18 +58,18 @@ public static Handler createHandler(Looper looper, boolean async) { return new Handler(looper); } + // Standard way of exposing async handler on older api's from the support library + // https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/core + // /src/main/java/androidx/core/os/HandlerCompat.java#51 if (Build.VERSION.SDK_INT >= 28) { return Handler.createAsync(looper); } - - if (Build.VERSION.SDK_INT >= 17) { - Constructor handlerConstructor = asyncHandlerConstructor(); - if (handlerConstructor != null) { - try { - return handlerConstructor.newInstance(looper, null, true); - } catch (Throwable e) { - // Fallback - } + if (Build.VERSION.SDK_INT >= 16) { + try { + //noinspection JavaReflectionMemberAccess + return Handler.class.getDeclaredConstructor(Looper.class, Callback.class, boolean.class) + .newInstance(looper, null, true); + } catch (Throwable ignored) { } } @@ -86,18 +84,4 @@ public static Looper buildBackgroundLooper(String threadName) { handlerThread.start(); return handlerThread.getLooper(); } - - @Nullable - private static Constructor asyncHandlerConstructor() { - try { - //noinspection JavaReflectionMemberAccess - return Handler.class.getConstructor( - Looper.class, - Handler.Callback.class, - Boolean.class - ); - } catch (Throwable e) { - return null; - } - } } diff --git a/epoxy-adapter/src/main/java/com/airbnb/epoxy/MainThreadExecutor.java b/epoxy-adapter/src/main/java/com/airbnb/epoxy/MainThreadExecutor.java index a1eaeec191..0a889dd57e 100644 --- a/epoxy-adapter/src/main/java/com/airbnb/epoxy/MainThreadExecutor.java +++ b/epoxy-adapter/src/main/java/com/airbnb/epoxy/MainThreadExecutor.java @@ -1,15 +1,14 @@ package com.airbnb.epoxy; -import android.os.Looper; - -import static com.airbnb.epoxy.EpoxyAsyncUtil.createHandler; +import static com.airbnb.epoxy.EpoxyAsyncUtil.AYSNC_MAIN_THREAD_HANDLER; +import static com.airbnb.epoxy.EpoxyAsyncUtil.MAIN_THREAD_HANDLER; class MainThreadExecutor extends HandlerExecutor { static final MainThreadExecutor INSTANCE = new MainThreadExecutor(false); static final MainThreadExecutor ASYNC_INSTANCE = new MainThreadExecutor(true); MainThreadExecutor(boolean async) { - super(createHandler(Looper.getMainLooper(), async)); + super(async ? AYSNC_MAIN_THREAD_HANDLER : MAIN_THREAD_HANDLER); } } diff --git a/gradle.properties b/gradle.properties index 8a26e4a0b8..4e86f7911b 100755 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -VERSION_NAME=2.16.3 +VERSION_NAME=2.16.4 GROUP=com.airbnb.android POM_DESCRIPTION=Epoxy is a system for composing complex screens with a ReyclerView in Android. POM_URL=https://github.com/airbnb/epoxy