Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1483,6 +1483,7 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/Platfor
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/SingleViewPresentation.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java
FILE: ../../../flutter/shell/platform/android/io/flutter/util/HandlerCompat.java
FILE: ../../../flutter/shell/platform/android/io/flutter/util/PathUtils.java
FILE: ../../../flutter/shell/platform/android/io/flutter/util/Preconditions.java
FILE: ../../../flutter/shell/platform/android/io/flutter/util/Predicate.java
Expand Down
1 change: 1 addition & 0 deletions shell/platform/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ android_java_sources = [
"io/flutter/plugin/platform/PlatformViewsController.java",
"io/flutter/plugin/platform/SingleViewPresentation.java",
"io/flutter/plugin/platform/VirtualDisplayController.java",
"io/flutter/util/HandlerCompat.java",
"io/flutter/util/PathUtils.java",
"io/flutter/util/Preconditions.java",
"io/flutter/util/Predicate.java",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import io.flutter.util.HandlerCompat;

/** A BinaryMessenger.TaskQueue that posts to the platform thread (aka main thread). */
public class PlatformTaskQueue implements DartMessenger.DartMessengerTaskQueue {
@NonNull private final Handler handler = new Handler(Looper.getMainLooper());
// Use an async handler because the default is subject to vsync synchronization and can result
// in delays when dispatching tasks.
@NonNull private final Handler handler = HandlerCompat.createAsyncHandler(Looper.getMainLooper());

@Override
public void dispatch(@NonNull Runnable runnable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import io.flutter.FlutterInjector;
import io.flutter.Log;
import io.flutter.embedding.engine.FlutterJNI;
import io.flutter.util.HandlerCompat;
import io.flutter.util.PathUtils;
import io.flutter.util.TraceSection;
import io.flutter.view.VsyncWaiter;
Expand Down Expand Up @@ -385,7 +386,7 @@ public void ensureInitializationCompleteAsync(
Log.e(TAG, "Flutter initialization failed.", e);
throw new RuntimeException(e);
}
new Handler(Looper.getMainLooper())
HandlerCompat.createAsyncHandler(Looper.getMainLooper())
.post(
() -> {
ensureInitializationComplete(applicationContext.getApplicationContext(), args);
Expand Down
35 changes: 35 additions & 0 deletions shell/platform/android/io/flutter/util/HandlerCompat.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.util;

import android.os.Build;
import android.os.Handler;
import android.os.Looper;

/** Compatability wrapper over {@link Handler}. */
public final class HandlerCompat {
/**
* Create a new Handler whose posted messages and runnables are not subject to synchronization
* barriers such as display vsync.
*
* <p>Messages sent to an async handler are guaranteed to be ordered with respect to one another,
* but not necessarily with respect to messages from other Handlers. Compatibility behavior:
*
* <ul>
* <li>SDK 28 and above, this method matches platform behavior.
* <li>Otherwise, returns a synchronous handler instance.
* </ul>
*
* @param looper the Looper that the new Handler should be bound to
* @return a new async Handler instance
* @see Handler#createAsync(Looper)
*/
public static Handler createAsyncHandler(Looper looper) {
if (Build.VERSION.SDK_INT >= 28) {
return Handler.createAsync(looper);
}
return new Handler(looper);
}
}
29 changes: 29 additions & 0 deletions shell/platform/android/test/io/flutter/util/HandlerCompatTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.util;

import static org.junit.Assert.assertTrue;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

@RunWith(RobolectricTestRunner.class)
public class HandlerCompatTest {
@Test
@Config(sdk = 28)
public void createAsync_createsAnAsyncHandler() {
Handler handler = Handler.createAsync(Looper.getMainLooper());

Message message = Message.obtain();
handler.sendMessageAtTime(message, 0);

assertTrue(message.isAsynchronous());
}
}
1 change: 1 addition & 0 deletions tools/android_lint/project.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<src file="../../../flutter/shell/platform/android/io/flutter/util/Predicate.java" />
<src file="../../../flutter/shell/platform/android/io/flutter/util/TraceSection.java" />
<src file="../../../flutter/shell/platform/android/io/flutter/util/PathUtils.java" />
<src file="../../../flutter/shell/platform/android/io/flutter/util/HandlerCompat.java" />
<src file="../../../flutter/shell/platform/android/io/flutter/embedding/android/KeyboardMap.java" />
<src file="../../../flutter/shell/platform/android/io/flutter/embedding/android/KeyboardManager.java" />
<src file="../../../flutter/shell/platform/android/io/flutter/embedding/android/AndroidTouchProcessor.java" />
Expand Down