Merge branch 'v4_webview' of github.com:flutter/plugins into v4_webview_android_navigation_delegate
diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/GeneratedAndroidWebView.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/GeneratedAndroidWebView.java
index af096bf..15c80cc 100644
--- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/GeneratedAndroidWebView.java
+++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/GeneratedAndroidWebView.java
@@ -1,7 +1,7 @@
 // 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.
-// Autogenerated from Pigeon (v4.0.2), do not edit directly.
+// Autogenerated from Pigeon (v4.2.3), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 
 package io.flutter.plugins.webviewflutter;
@@ -17,6 +17,7 @@
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -342,22 +343,22 @@
 
     void error(Throwable error);
   }
-
-  private static class JavaObjectHostApiCodec extends StandardMessageCodec {
-    public static final JavaObjectHostApiCodec INSTANCE = new JavaObjectHostApiCodec();
-
-    private JavaObjectHostApiCodec() {}
-  }
-
-  /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
+  /**
+   * Handles methods calls to the native Java Object class.
+   *
+   * <p>Also handles calls to remove the reference to an instance with `dispose`.
+   *
+   * <p>See https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html.
+   *
+   * <p>Generated interface from Pigeon that represents a handler of messages from Flutter.
+   */
   public interface JavaObjectHostApi {
     void dispose(@NonNull Long identifier);
 
     /** The codec used by JavaObjectHostApi. */
     static MessageCodec<Object> getCodec() {
-      return JavaObjectHostApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
-
     /**
      * Sets up an instance of `JavaObjectHostApi` to handle messages through the `binaryMessenger`.
      */
@@ -372,6 +373,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number identifierArg = (Number) args.get(0);
                   if (identifierArg == null) {
                     throw new NullPointerException("identifierArg unexpectedly null.");
@@ -389,14 +391,13 @@
       }
     }
   }
-
-  private static class JavaObjectFlutterApiCodec extends StandardMessageCodec {
-    public static final JavaObjectFlutterApiCodec INSTANCE = new JavaObjectFlutterApiCodec();
-
-    private JavaObjectFlutterApiCodec() {}
-  }
-
-  /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */
+  /**
+   * Handles callbacks methods for the native Java Object class.
+   *
+   * <p>See https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html.
+   *
+   * <p>Generated class from Pigeon that represents Flutter messages that can be called from Java.
+   */
   public static class JavaObjectFlutterApi {
     private final BinaryMessenger binaryMessenger;
 
@@ -407,9 +408,9 @@
     public interface Reply<T> {
       void reply(T reply);
     }
-
+    /** The codec used by JavaObjectFlutterApi. */
     static MessageCodec<Object> getCodec() {
-      return JavaObjectFlutterApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
 
     public void dispose(@NonNull Long identifierArg, Reply<Void> callback) {
@@ -417,19 +418,12 @@
           new BasicMessageChannel<>(
               binaryMessenger, "dev.flutter.pigeon.JavaObjectFlutterApi.dispose", getCodec());
       channel.send(
-          new ArrayList<Object>(Arrays.asList(identifierArg)),
+          new ArrayList<Object>(Collections.singletonList(identifierArg)),
           channelReply -> {
             callback.reply(null);
           });
     }
   }
-
-  private static class CookieManagerHostApiCodec extends StandardMessageCodec {
-    public static final CookieManagerHostApiCodec INSTANCE = new CookieManagerHostApiCodec();
-
-    private CookieManagerHostApiCodec() {}
-  }
-
   /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
   public interface CookieManagerHostApi {
     void clearCookies(Result<Boolean> result);
@@ -438,9 +432,8 @@
 
     /** The codec used by CookieManagerHostApi. */
     static MessageCodec<Object> getCodec() {
-      return CookieManagerHostApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
-
     /**
      * Sets up an instance of `CookieManagerHostApi` to handle messages through the
      * `binaryMessenger`.
@@ -490,6 +483,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   String urlArg = (String) args.get(0);
                   if (urlArg == null) {
                     throw new NullPointerException("urlArg unexpectedly null.");
@@ -518,7 +512,7 @@
     private WebViewHostApiCodec() {}
 
     @Override
-    protected Object readValueOfType(byte type, ByteBuffer buffer) {
+    protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
       switch (type) {
         case (byte) 128:
           return WebViewPoint.fromMap((Map<String, Object>) readValue(buffer));
@@ -529,7 +523,7 @@
     }
 
     @Override
-    protected void writeValue(ByteArrayOutputStream stream, Object value) {
+    protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
       if (value instanceof WebViewPoint) {
         stream.write(128);
         writeValue(stream, ((WebViewPoint) value).toMap());
@@ -617,7 +611,6 @@
     static MessageCodec<Object> getCodec() {
       return WebViewHostApiCodec.INSTANCE;
     }
-
     /** Sets up an instance of `WebViewHostApi` to handle messages through the `binaryMessenger`. */
     static void setup(BinaryMessenger binaryMessenger, WebViewHostApi api) {
       {
@@ -630,6 +623,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -661,6 +655,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -698,6 +693,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -737,6 +733,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -773,6 +770,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -807,6 +805,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -833,6 +832,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -859,6 +859,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -885,6 +886,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -910,6 +912,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -935,6 +938,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -960,6 +964,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -993,6 +998,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1037,6 +1043,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1063,6 +1070,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1099,6 +1107,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1135,6 +1144,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1161,6 +1171,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1187,6 +1198,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1216,6 +1228,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Boolean enabledArg = (Boolean) args.get(0);
                   if (enabledArg == null) {
                     throw new NullPointerException("enabledArg unexpectedly null.");
@@ -1241,6 +1254,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1276,6 +1290,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1312,6 +1327,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1348,6 +1364,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1378,6 +1395,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1408,6 +1426,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1431,13 +1450,6 @@
       }
     }
   }
-
-  private static class WebSettingsHostApiCodec extends StandardMessageCodec {
-    public static final WebSettingsHostApiCodec INSTANCE = new WebSettingsHostApiCodec();
-
-    private WebSettingsHostApiCodec() {}
-  }
-
   /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
   public interface WebSettingsHostApi {
     void create(@NonNull Long instanceId, @NonNull Long webViewInstanceId);
@@ -1468,9 +1480,8 @@
 
     /** The codec used by WebSettingsHostApi. */
     static MessageCodec<Object> getCodec() {
-      return WebSettingsHostApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
-
     /**
      * Sets up an instance of `WebSettingsHostApi` to handle messages through the `binaryMessenger`.
      */
@@ -1485,6 +1496,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1518,6 +1530,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1550,6 +1563,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1582,6 +1596,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1614,6 +1629,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1646,6 +1662,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1676,6 +1693,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1708,6 +1726,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1740,6 +1759,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1772,6 +1792,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1804,6 +1825,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1836,6 +1858,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1868,6 +1891,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1890,23 +1914,14 @@
       }
     }
   }
-
-  private static class JavaScriptChannelHostApiCodec extends StandardMessageCodec {
-    public static final JavaScriptChannelHostApiCodec INSTANCE =
-        new JavaScriptChannelHostApiCodec();
-
-    private JavaScriptChannelHostApiCodec() {}
-  }
-
   /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
   public interface JavaScriptChannelHostApi {
     void create(@NonNull Long instanceId, @NonNull String channelName);
 
     /** The codec used by JavaScriptChannelHostApi. */
     static MessageCodec<Object> getCodec() {
-      return JavaScriptChannelHostApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
-
     /**
      * Sets up an instance of `JavaScriptChannelHostApi` to handle messages through the
      * `binaryMessenger`.
@@ -1922,6 +1937,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -1944,14 +1960,6 @@
       }
     }
   }
-
-  private static class JavaScriptChannelFlutterApiCodec extends StandardMessageCodec {
-    public static final JavaScriptChannelFlutterApiCodec INSTANCE =
-        new JavaScriptChannelFlutterApiCodec();
-
-    private JavaScriptChannelFlutterApiCodec() {}
-  }
-
   /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */
   public static class JavaScriptChannelFlutterApi {
     private final BinaryMessenger binaryMessenger;
@@ -1963,9 +1971,9 @@
     public interface Reply<T> {
       void reply(T reply);
     }
-
+    /** The codec used by JavaScriptChannelFlutterApi. */
     static MessageCodec<Object> getCodec() {
-      return JavaScriptChannelFlutterApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
 
     public void postMessage(
@@ -1982,22 +1990,17 @@
           });
     }
   }
-
-  private static class WebViewClientHostApiCodec extends StandardMessageCodec {
-    public static final WebViewClientHostApiCodec INSTANCE = new WebViewClientHostApiCodec();
-
-    private WebViewClientHostApiCodec() {}
-  }
-
   /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
   public interface WebViewClientHostApi {
-    void create(@NonNull Long instanceId, @NonNull Boolean shouldOverrideUrlLoading);
+    void create(@NonNull Long instanceId);
+
+    void setSynchronousReturnValueForShouldOverrideUrlLoading(
+        @NonNull Long instanceId, @NonNull Boolean value);
 
     /** The codec used by WebViewClientHostApi. */
     static MessageCodec<Object> getCodec() {
-      return WebViewClientHostApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
-
     /**
      * Sets up an instance of `WebViewClientHostApi` to handle messages through the
      * `binaryMessenger`.
@@ -2013,18 +2016,45 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
                   }
-                  Boolean shouldOverrideUrlLoadingArg = (Boolean) args.get(1);
-                  if (shouldOverrideUrlLoadingArg == null) {
-                    throw new NullPointerException(
-                        "shouldOverrideUrlLoadingArg unexpectedly null.");
+                  api.create((instanceIdArg == null) ? null : instanceIdArg.longValue());
+                  wrapped.put("result", null);
+                } catch (Error | RuntimeException exception) {
+                  wrapped.put("error", wrapError(exception));
+                }
+                reply.reply(wrapped);
+              });
+        } else {
+          channel.setMessageHandler(null);
+        }
+      }
+      {
+        BasicMessageChannel<Object> channel =
+            new BasicMessageChannel<>(
+                binaryMessenger,
+                "dev.flutter.pigeon.WebViewClientHostApi.setSynchronousReturnValueForShouldOverrideUrlLoading",
+                getCodec());
+        if (api != null) {
+          channel.setMessageHandler(
+              (message, reply) -> {
+                Map<String, Object> wrapped = new HashMap<>();
+                try {
+                  ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
+                  Number instanceIdArg = (Number) args.get(0);
+                  if (instanceIdArg == null) {
+                    throw new NullPointerException("instanceIdArg unexpectedly null.");
                   }
-                  api.create(
-                      (instanceIdArg == null) ? null : instanceIdArg.longValue(),
-                      shouldOverrideUrlLoadingArg);
+                  Boolean valueArg = (Boolean) args.get(1);
+                  if (valueArg == null) {
+                    throw new NullPointerException("valueArg unexpectedly null.");
+                  }
+                  api.setSynchronousReturnValueForShouldOverrideUrlLoading(
+                      (instanceIdArg == null) ? null : instanceIdArg.longValue(), valueArg);
                   wrapped.put("result", null);
                 } catch (Error | RuntimeException exception) {
                   wrapped.put("error", wrapError(exception));
@@ -2044,7 +2074,7 @@
     private WebViewClientFlutterApiCodec() {}
 
     @Override
-    protected Object readValueOfType(byte type, ByteBuffer buffer) {
+    protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
       switch (type) {
         case (byte) 128:
           return WebResourceErrorData.fromMap((Map<String, Object>) readValue(buffer));
@@ -2058,7 +2088,7 @@
     }
 
     @Override
-    protected void writeValue(ByteArrayOutputStream stream, Object value) {
+    protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
       if (value instanceof WebResourceErrorData) {
         stream.write(128);
         writeValue(stream, ((WebResourceErrorData) value).toMap());
@@ -2082,7 +2112,7 @@
     public interface Reply<T> {
       void reply(T reply);
     }
-
+    /** The codec used by WebViewClientFlutterApi. */
     static MessageCodec<Object> getCodec() {
       return WebViewClientFlutterApiCodec.INSTANCE;
     }
@@ -2197,22 +2227,14 @@
           });
     }
   }
-
-  private static class DownloadListenerHostApiCodec extends StandardMessageCodec {
-    public static final DownloadListenerHostApiCodec INSTANCE = new DownloadListenerHostApiCodec();
-
-    private DownloadListenerHostApiCodec() {}
-  }
-
   /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
   public interface DownloadListenerHostApi {
     void create(@NonNull Long instanceId);
 
     /** The codec used by DownloadListenerHostApi. */
     static MessageCodec<Object> getCodec() {
-      return DownloadListenerHostApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
-
     /**
      * Sets up an instance of `DownloadListenerHostApi` to handle messages through the
      * `binaryMessenger`.
@@ -2228,6 +2250,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -2245,14 +2268,6 @@
       }
     }
   }
-
-  private static class DownloadListenerFlutterApiCodec extends StandardMessageCodec {
-    public static final DownloadListenerFlutterApiCodec INSTANCE =
-        new DownloadListenerFlutterApiCodec();
-
-    private DownloadListenerFlutterApiCodec() {}
-  }
-
   /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */
   public static class DownloadListenerFlutterApi {
     private final BinaryMessenger binaryMessenger;
@@ -2264,9 +2279,9 @@
     public interface Reply<T> {
       void reply(T reply);
     }
-
+    /** The codec used by DownloadListenerFlutterApi. */
     static MessageCodec<Object> getCodec() {
-      return DownloadListenerFlutterApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
 
     public void onDownloadStart(
@@ -2296,22 +2311,14 @@
           });
     }
   }
-
-  private static class WebChromeClientHostApiCodec extends StandardMessageCodec {
-    public static final WebChromeClientHostApiCodec INSTANCE = new WebChromeClientHostApiCodec();
-
-    private WebChromeClientHostApiCodec() {}
-  }
-
   /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
   public interface WebChromeClientHostApi {
     void create(@NonNull Long instanceId);
 
     /** The codec used by WebChromeClientHostApi. */
     static MessageCodec<Object> getCodec() {
-      return WebChromeClientHostApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
-
     /**
      * Sets up an instance of `WebChromeClientHostApi` to handle messages through the
      * `binaryMessenger`.
@@ -2327,6 +2334,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -2344,14 +2352,6 @@
       }
     }
   }
-
-  private static class FlutterAssetManagerHostApiCodec extends StandardMessageCodec {
-    public static final FlutterAssetManagerHostApiCodec INSTANCE =
-        new FlutterAssetManagerHostApiCodec();
-
-    private FlutterAssetManagerHostApiCodec() {}
-  }
-
   /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
   public interface FlutterAssetManagerHostApi {
     @NonNull
@@ -2362,9 +2362,8 @@
 
     /** The codec used by FlutterAssetManagerHostApi. */
     static MessageCodec<Object> getCodec() {
-      return FlutterAssetManagerHostApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
-
     /**
      * Sets up an instance of `FlutterAssetManagerHostApi` to handle messages through the
      * `binaryMessenger`.
@@ -2380,6 +2379,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   String pathArg = (String) args.get(0);
                   if (pathArg == null) {
                     throw new NullPointerException("pathArg unexpectedly null.");
@@ -2407,6 +2407,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   String nameArg = (String) args.get(0);
                   if (nameArg == null) {
                     throw new NullPointerException("nameArg unexpectedly null.");
@@ -2424,14 +2425,6 @@
       }
     }
   }
-
-  private static class WebChromeClientFlutterApiCodec extends StandardMessageCodec {
-    public static final WebChromeClientFlutterApiCodec INSTANCE =
-        new WebChromeClientFlutterApiCodec();
-
-    private WebChromeClientFlutterApiCodec() {}
-  }
-
   /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */
   public static class WebChromeClientFlutterApi {
     private final BinaryMessenger binaryMessenger;
@@ -2443,9 +2436,9 @@
     public interface Reply<T> {
       void reply(T reply);
     }
-
+    /** The codec used by WebChromeClientFlutterApi. */
     static MessageCodec<Object> getCodec() {
-      return WebChromeClientFlutterApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
 
     public void onProgressChanged(
@@ -2465,13 +2458,6 @@
           });
     }
   }
-
-  private static class WebStorageHostApiCodec extends StandardMessageCodec {
-    public static final WebStorageHostApiCodec INSTANCE = new WebStorageHostApiCodec();
-
-    private WebStorageHostApiCodec() {}
-  }
-
   /** Generated interface from Pigeon that represents a handler of messages from Flutter. */
   public interface WebStorageHostApi {
     void create(@NonNull Long instanceId);
@@ -2480,9 +2466,8 @@
 
     /** The codec used by WebStorageHostApi. */
     static MessageCodec<Object> getCodec() {
-      return WebStorageHostApiCodec.INSTANCE;
+      return new StandardMessageCodec();
     }
-
     /**
      * Sets up an instance of `WebStorageHostApi` to handle messages through the `binaryMessenger`.
      */
@@ -2497,6 +2482,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -2522,6 +2508,7 @@
                 Map<String, Object> wrapped = new HashMap<>();
                 try {
                   ArrayList<Object> args = (ArrayList<Object>) message;
+                  assert args != null;
                   Number instanceIdArg = (Number) args.get(0);
                   if (instanceIdArg == null) {
                     throw new NullPointerException("instanceIdArg unexpectedly null.");
@@ -2540,7 +2527,8 @@
     }
   }
 
-  private static Map<String, Object> wrapError(Throwable exception) {
+  @NonNull
+  private static Map<String, Object> wrapError(@NonNull Throwable exception) {
     Map<String, Object> errorMap = new HashMap<>();
     errorMap.put("message", exception.toString());
     errorMap.put("code", exception.getClass().getSimpleName());
diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientHostApiImpl.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientHostApiImpl.java
index fd08cfa..09a34f2 100644
--- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientHostApiImpl.java
+++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientHostApiImpl.java
@@ -17,6 +17,7 @@
 import androidx.annotation.RequiresApi;
 import androidx.webkit.WebResourceErrorCompat;
 import androidx.webkit.WebViewClientCompat;
+import java.util.Objects;
 
 /**
  * Host api implementation for {@link WebViewClient}.
@@ -32,17 +33,14 @@
   @RequiresApi(Build.VERSION_CODES.N)
   public static class WebViewClientImpl extends WebViewClient {
     private final WebViewClientFlutterApiImpl flutterApi;
-    private final boolean shouldOverrideUrlLoading;
+    private boolean returnValueForShouldOverrideUrlLoading = false;
 
     /**
      * Creates a {@link WebViewClient} that passes arguments of callbacks methods to Dart.
      *
      * @param flutterApi handles sending messages to Dart
-     * @param shouldOverrideUrlLoading whether loading a url should be overridden
      */
-    public WebViewClientImpl(
-        @NonNull WebViewClientFlutterApiImpl flutterApi, boolean shouldOverrideUrlLoading) {
-      this.shouldOverrideUrlLoading = shouldOverrideUrlLoading;
+    public WebViewClientImpl(@NonNull WebViewClientFlutterApiImpl flutterApi) {
       this.flutterApi = flutterApi;
     }
 
@@ -71,13 +69,13 @@
     @Override
     public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
       flutterApi.requestLoading(this, view, request, reply -> {});
-      return shouldOverrideUrlLoading;
+      return returnValueForShouldOverrideUrlLoading;
     }
 
     @Override
     public boolean shouldOverrideUrlLoading(WebView view, String url) {
       flutterApi.urlLoading(this, view, url, reply -> {});
-      return shouldOverrideUrlLoading;
+      return returnValueForShouldOverrideUrlLoading;
     }
 
     @Override
@@ -86,6 +84,11 @@
       // handled even though they were handled. We don't want to propagate those as they're not
       // truly lost.
     }
+
+    /** Sets return value for {@link #shouldOverrideUrlLoading}. */
+    public void setReturnValueForShouldOverrideUrlLoading(boolean value) {
+      returnValueForShouldOverrideUrlLoading = value;
+    }
   }
 
   /**
@@ -94,11 +97,9 @@
    */
   public static class WebViewClientCompatImpl extends WebViewClientCompat {
     private final WebViewClientFlutterApiImpl flutterApi;
-    private final boolean shouldOverrideUrlLoading;
+    private boolean returnValueForShouldOverrideUrlLoading = false;
 
-    public WebViewClientCompatImpl(
-        @NonNull WebViewClientFlutterApiImpl flutterApi, boolean shouldOverrideUrlLoading) {
-      this.shouldOverrideUrlLoading = shouldOverrideUrlLoading;
+    public WebViewClientCompatImpl(@NonNull WebViewClientFlutterApiImpl flutterApi) {
       this.flutterApi = flutterApi;
     }
 
@@ -136,13 +137,13 @@
     public boolean shouldOverrideUrlLoading(
         @NonNull WebView view, @NonNull WebResourceRequest request) {
       flutterApi.requestLoading(this, view, request, reply -> {});
-      return shouldOverrideUrlLoading;
+      return returnValueForShouldOverrideUrlLoading;
     }
 
     @Override
     public boolean shouldOverrideUrlLoading(WebView view, String url) {
       flutterApi.urlLoading(this, view, url, reply -> {});
-      return shouldOverrideUrlLoading;
+      return returnValueForShouldOverrideUrlLoading;
     }
 
     @Override
@@ -151,6 +152,11 @@
       // handled even though they were handled. We don't want to propagate those as they're not
       // truly lost.
     }
+
+    /** Sets return value for {@link #shouldOverrideUrlLoading}. */
+    public void setReturnValueForShouldOverrideUrlLoading(boolean value) {
+      returnValueForShouldOverrideUrlLoading = value;
+    }
   }
 
   /** Handles creating {@link WebViewClient}s for a {@link WebViewClientHostApiImpl}. */
@@ -161,8 +167,7 @@
      * @param flutterApi handles sending messages to Dart
      * @return the created {@link WebViewClient}
      */
-    public WebViewClient createWebViewClient(
-        WebViewClientFlutterApiImpl flutterApi, boolean shouldOverrideUrlLoading) {
+    public WebViewClient createWebViewClient(WebViewClientFlutterApiImpl flutterApi) {
       // WebViewClientCompat is used to get
       // shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
       // invoked by the webview on older Android devices, without it pages that use iframes will
@@ -172,9 +177,9 @@
       // to bug https://bugs.chromium.org/p/chromium/issues/detail?id=925887. Also, see
       // https://github.com/flutter/flutter/issues/29446.
       if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-        return new WebViewClientImpl(flutterApi, shouldOverrideUrlLoading);
+        return new WebViewClientImpl(flutterApi);
       } else {
-        return new WebViewClientCompatImpl(flutterApi, shouldOverrideUrlLoading);
+        return new WebViewClientCompatImpl(flutterApi);
       }
     }
   }
@@ -196,9 +201,24 @@
   }
 
   @Override
-  public void create(Long instanceId, Boolean shouldOverrideUrlLoading) {
-    final WebViewClient webViewClient =
-        webViewClientCreator.createWebViewClient(flutterApi, shouldOverrideUrlLoading);
+  public void create(@NonNull Long instanceId) {
+    final WebViewClient webViewClient = webViewClientCreator.createWebViewClient(flutterApi);
     instanceManager.addDartCreatedInstance(webViewClient, instanceId);
   }
+
+  @Override
+  public void setSynchronousReturnValueForShouldOverrideUrlLoading(
+      @NonNull Long instanceId, @NonNull Boolean value) {
+    final WebViewClient webViewClient =
+        Objects.requireNonNull(instanceManager.getInstance(instanceId));
+    if (webViewClient instanceof WebViewClientCompatImpl) {
+      ((WebViewClientCompatImpl) webViewClient).setReturnValueForShouldOverrideUrlLoading(value);
+    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
+        && webViewClient instanceof WebViewClientImpl) {
+      ((WebViewClientImpl) webViewClient).setReturnValueForShouldOverrideUrlLoading(value);
+    } else {
+      throw new IllegalStateException(
+          "This WebViewClient doesn't support setting the returnValueForShouldOverrideUrlLoading.");
+    }
+  }
 }
diff --git a/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewClientTest.java b/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewClientTest.java
index 87b39d4..3267291 100644
--- a/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewClientTest.java
+++ b/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewClientTest.java
@@ -33,6 +33,8 @@
 
   @Mock public WebView mockWebView;
 
+  @Mock public WebViewClientCompatImpl mockWebViewClient;
+
   InstanceManager instanceManager;
   WebViewClientHostApiImpl hostApiImpl;
   WebViewClientCompatImpl webViewClient;
@@ -46,18 +48,15 @@
     final WebViewClientCreator webViewClientCreator =
         new WebViewClientCreator() {
           @Override
-          public WebViewClient createWebViewClient(
-              WebViewClientFlutterApiImpl flutterApi, boolean shouldOverrideUrlLoading) {
-            webViewClient =
-                (WebViewClientCompatImpl)
-                    super.createWebViewClient(flutterApi, shouldOverrideUrlLoading);
+          public WebViewClient createWebViewClient(WebViewClientFlutterApiImpl flutterApi) {
+            webViewClient = (WebViewClientCompatImpl) super.createWebViewClient(flutterApi);
             return webViewClient;
           }
         };
 
     hostApiImpl =
         new WebViewClientHostApiImpl(instanceManager, webViewClientCreator, mockFlutterApi);
-    hostApiImpl.create(1L, true);
+    hostApiImpl.create(1L);
   }
 
   @After
@@ -107,4 +106,23 @@
         WebViewClientFlutterApiImpl.createWebResourceRequestData(mockRequest);
     assertEquals(data.getRequestHeaders(), new HashMap<String, String>());
   }
+
+  @Test
+  public void setReturnValueForShouldOverrideUrlLoading() {
+    final WebViewClientHostApiImpl webViewClientHostApi =
+        new WebViewClientHostApiImpl(
+            instanceManager,
+            new WebViewClientCreator() {
+              @Override
+              public WebViewClient createWebViewClient(WebViewClientFlutterApiImpl flutterApi) {
+                return mockWebViewClient;
+              }
+            },
+            mockFlutterApi);
+
+    instanceManager.addDartCreatedInstance(mockWebViewClient, 0);
+    webViewClientHostApi.setSynchronousReturnValueForShouldOverrideUrlLoading(0L, false);
+
+    verify(mockWebViewClient).setReturnValueForShouldOverrideUrlLoading(false);
+  }
 }
diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.dart
index fa5b516..d2f0333 100644
--- a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.dart
+++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.dart
@@ -634,7 +634,6 @@
 class WebViewClient extends JavaObject {
   /// Constructs a [WebViewClient].
   WebViewClient({
-    this.shouldOverrideUrlLoading = true,
     this.onPageStarted,
     this.onPageFinished,
     this.onReceivedRequestError,
@@ -651,7 +650,6 @@
   /// This should only be used by subclasses created by this library or to
   /// create copies.
   WebViewClient.detached({
-    this.shouldOverrideUrlLoading = true,
     this.onPageStarted,
     this.onPageFinished,
     this.onReceivedRequestError,
@@ -744,20 +742,6 @@
   @visibleForTesting
   static WebViewClientHostApiImpl api = WebViewClientHostApiImpl();
 
-  /// Whether loading a url should be overridden.
-  ///
-  /// In Java, `shouldOverrideUrlLoading()` and `shouldOverrideRequestLoading()`
-  /// callbacks must synchronously return a boolean. This sets the default
-  /// return value.
-  ///
-  /// Setting [shouldOverrideUrlLoading] to true causes the current [WebView] to
-  /// abort loading the URL, while returning false causes the [WebView] to
-  /// continue loading the URL as usual. [requestLoading] or [urlLoading] will
-  /// still be called either way.
-  ///
-  /// Defaults to true.
-  final bool shouldOverrideUrlLoading;
-
   /// Notify the host application that a page has started loading.
   ///
   /// This method is called once for each main frame load so a page with iframes
@@ -801,31 +785,40 @@
     String failingUrl,
   )? onReceivedError;
 
-  // TODO(bparrishMines): Update documentation once synchronous url handling is supported.
-  /// When a URL is about to be loaded in the current [WebView].
+  /// When the current [WebView] wants to load a URL.
   ///
-  /// If a [WebViewClient] is not provided, by default [WebView] will ask
-  /// Activity Manager to choose the proper handler for the URL. If a
-  /// [WebViewClient] is provided, setting [shouldOverrideUrlLoading] to true
-  /// causes the current [WebView] to abort loading the URL, while returning
-  /// false causes the [WebView] to continue loading the URL as usual.
+  /// The value set by [setSynchronousReturnValueForShouldOverrideUrlLoading]
+  /// indicates whether the [WebView] loaded the request.
   final void Function(WebView webView, WebResourceRequest request)?
       requestLoading;
 
-  // TODO(bparrishMines): Update documentation once synchronous url handling is supported.
-  /// When a URL is about to be loaded in the current [WebView].
+  /// When the current [WebView] wants to load a URL.
   ///
-  /// If a [WebViewClient] is not provided, by default [WebView] will ask
-  /// Activity Manager to choose the proper handler for the URL. If a
-  /// [WebViewClient] is provided, setting [shouldOverrideUrlLoading] to true
-  /// causes the current [WebView] to abort loading the URL, while returning
-  /// false causes the [WebView] to continue loading the URL as usual.
+  /// The value set by [setSynchronousReturnValueForShouldOverrideUrlLoading]
+  /// indicates whether the [WebView] loaded the URL.
   final void Function(WebView webView, String url)? urlLoading;
 
+  /// Sets the required synchronous return value for the Java method,
+  /// `WebViewClient.shouldOverrideUrlLoading(...)`.
+  ///
+  /// The Java method, `WebViewClient.shouldOverrideUrlLoading(...)`, requires
+  /// a boolean to be returned and this method sets the returned value for all
+  /// calls to the Java method.
+  ///
+  /// Setting this to true causes the current [WebView] to abort loading any URL
+  /// received by [requestLoading] or [urlLoading], while setting this to false
+  /// causes the [WebView] to continue loading a URL as usual.
+  ///
+  /// Defaults to false.
+  Future<void> setSynchronousReturnValueForShouldOverrideUrlLoading(
+    bool value,
+  ) {
+    return api.setShouldOverrideUrlLoadingReturnValueFromInstance(this, value);
+  }
+
   @override
   WebViewClient copy() {
     return WebViewClient.detached(
-      shouldOverrideUrlLoading: shouldOverrideUrlLoading,
       onPageStarted: onPageStarted,
       onPageFinished: onPageFinished,
       onReceivedRequestError: onReceivedRequestError,
diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.pigeon.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.pigeon.dart
index 49385e5..5bdab16 100644
--- a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.pigeon.dart
+++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.pigeon.dart
@@ -1,7 +1,7 @@
 // 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.
-// Autogenerated from Pigeon (v4.0.2), do not edit directly.
+// Autogenerated from Pigeon (v4.2.3), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
 import 'dart:async';
@@ -102,20 +102,20 @@
   }
 }
 
-class _JavaObjectHostApiCodec extends StandardMessageCodec {
-  const _JavaObjectHostApiCodec();
-}
-
+/// Handles methods calls to the native Java Object class.
+///
+/// Also handles calls to remove the reference to an instance with `dispose`.
+///
+/// See https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html.
 class JavaObjectHostApi {
   /// Constructor for [JavaObjectHostApi].  The [binaryMessenger] named argument is
   /// available for dependency injection.  If it is left null, the default
   /// BinaryMessenger will be used which routes to the host platform.
   JavaObjectHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
-  static const MessageCodec<Object?> codec = _JavaObjectHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   Future<void> dispose(int arg_identifier) async {
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
@@ -142,12 +142,11 @@
   }
 }
 
-class _JavaObjectFlutterApiCodec extends StandardMessageCodec {
-  const _JavaObjectFlutterApiCodec();
-}
-
+/// Handles callbacks methods for the native Java Object class.
+///
+/// See https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html.
 abstract class JavaObjectFlutterApi {
-  static const MessageCodec<Object?> codec = _JavaObjectFlutterApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void dispose(int identifier);
   static void setup(JavaObjectFlutterApi? api,
@@ -174,20 +173,15 @@
   }
 }
 
-class _CookieManagerHostApiCodec extends StandardMessageCodec {
-  const _CookieManagerHostApiCodec();
-}
-
 class CookieManagerHostApi {
   /// Constructor for [CookieManagerHostApi].  The [binaryMessenger] named argument is
   /// available for dependency injection.  If it is left null, the default
   /// BinaryMessenger will be used which routes to the host platform.
   CookieManagerHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
-  static const MessageCodec<Object?> codec = _CookieManagerHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   Future<bool> clearCookies() async {
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
@@ -273,7 +267,6 @@
   /// BinaryMessenger will be used which routes to the host platform.
   WebViewHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
   static const MessageCodec<Object?> codec = _WebViewHostApiCodec();
@@ -963,20 +956,15 @@
   }
 }
 
-class _WebSettingsHostApiCodec extends StandardMessageCodec {
-  const _WebSettingsHostApiCodec();
-}
-
 class WebSettingsHostApi {
   /// Constructor for [WebSettingsHostApi].  The [binaryMessenger] named argument is
   /// available for dependency injection.  If it is left null, the default
   /// BinaryMessenger will be used which routes to the host platform.
   WebSettingsHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
-  static const MessageCodec<Object?> codec = _WebSettingsHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   Future<void> create(int arg_instanceId, int arg_webViewInstanceId) async {
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
@@ -1304,20 +1292,15 @@
   }
 }
 
-class _JavaScriptChannelHostApiCodec extends StandardMessageCodec {
-  const _JavaScriptChannelHostApiCodec();
-}
-
 class JavaScriptChannelHostApi {
   /// Constructor for [JavaScriptChannelHostApi].  The [binaryMessenger] named argument is
   /// available for dependency injection.  If it is left null, the default
   /// BinaryMessenger will be used which routes to the host platform.
   JavaScriptChannelHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
-  static const MessageCodec<Object?> codec = _JavaScriptChannelHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   Future<void> create(int arg_instanceId, String arg_channelName) async {
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
@@ -1345,13 +1328,8 @@
   }
 }
 
-class _JavaScriptChannelFlutterApiCodec extends StandardMessageCodec {
-  const _JavaScriptChannelFlutterApiCodec();
-}
-
 abstract class JavaScriptChannelFlutterApi {
-  static const MessageCodec<Object?> codec =
-      _JavaScriptChannelFlutterApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void postMessage(int instanceId, String message);
   static void setup(JavaScriptChannelFlutterApi? api,
@@ -1381,29 +1359,48 @@
   }
 }
 
-class _WebViewClientHostApiCodec extends StandardMessageCodec {
-  const _WebViewClientHostApiCodec();
-}
-
 class WebViewClientHostApi {
   /// Constructor for [WebViewClientHostApi].  The [binaryMessenger] named argument is
   /// available for dependency injection.  If it is left null, the default
   /// BinaryMessenger will be used which routes to the host platform.
   WebViewClientHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
-  static const MessageCodec<Object?> codec = _WebViewClientHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
-  Future<void> create(
-      int arg_instanceId, bool arg_shouldOverrideUrlLoading) async {
+  Future<void> create(int arg_instanceId) async {
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
         'dev.flutter.pigeon.WebViewClientHostApi.create', codec,
         binaryMessenger: _binaryMessenger);
+    final Map<Object?, Object?>? replyMap =
+        await channel.send(<Object?>[arg_instanceId]) as Map<Object?, Object?>?;
+    if (replyMap == null) {
+      throw PlatformException(
+        code: 'channel-error',
+        message: 'Unable to establish connection on channel.',
+      );
+    } else if (replyMap['error'] != null) {
+      final Map<Object?, Object?> error =
+          (replyMap['error'] as Map<Object?, Object?>?)!;
+      throw PlatformException(
+        code: (error['code'] as String?)!,
+        message: error['message'] as String?,
+        details: error['details'],
+      );
+    } else {
+      return;
+    }
+  }
+
+  Future<void> setSynchronousReturnValueForShouldOverrideUrlLoading(
+      int arg_instanceId, bool arg_value) async {
+    final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+        'dev.flutter.pigeon.WebViewClientHostApi.setSynchronousReturnValueForShouldOverrideUrlLoading',
+        codec,
+        binaryMessenger: _binaryMessenger);
     final Map<Object?, Object?>? replyMap = await channel
-            .send(<Object?>[arg_instanceId, arg_shouldOverrideUrlLoading])
-        as Map<Object?, Object?>?;
+        .send(<Object?>[arg_instanceId, arg_value]) as Map<Object?, Object?>?;
     if (replyMap == null) {
       throw PlatformException(
         code: 'channel-error',
@@ -1636,20 +1633,15 @@
   }
 }
 
-class _DownloadListenerHostApiCodec extends StandardMessageCodec {
-  const _DownloadListenerHostApiCodec();
-}
-
 class DownloadListenerHostApi {
   /// Constructor for [DownloadListenerHostApi].  The [binaryMessenger] named argument is
   /// available for dependency injection.  If it is left null, the default
   /// BinaryMessenger will be used which routes to the host platform.
   DownloadListenerHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
-  static const MessageCodec<Object?> codec = _DownloadListenerHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   Future<void> create(int arg_instanceId) async {
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
@@ -1676,12 +1668,8 @@
   }
 }
 
-class _DownloadListenerFlutterApiCodec extends StandardMessageCodec {
-  const _DownloadListenerFlutterApiCodec();
-}
-
 abstract class DownloadListenerFlutterApi {
-  static const MessageCodec<Object?> codec = _DownloadListenerFlutterApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void onDownloadStart(int instanceId, String url, String userAgent,
       String contentDisposition, String mimetype, int contentLength);
@@ -1726,20 +1714,15 @@
   }
 }
 
-class _WebChromeClientHostApiCodec extends StandardMessageCodec {
-  const _WebChromeClientHostApiCodec();
-}
-
 class WebChromeClientHostApi {
   /// Constructor for [WebChromeClientHostApi].  The [binaryMessenger] named argument is
   /// available for dependency injection.  If it is left null, the default
   /// BinaryMessenger will be used which routes to the host platform.
   WebChromeClientHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
-  static const MessageCodec<Object?> codec = _WebChromeClientHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   Future<void> create(int arg_instanceId) async {
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
@@ -1766,20 +1749,15 @@
   }
 }
 
-class _FlutterAssetManagerHostApiCodec extends StandardMessageCodec {
-  const _FlutterAssetManagerHostApiCodec();
-}
-
 class FlutterAssetManagerHostApi {
   /// Constructor for [FlutterAssetManagerHostApi].  The [binaryMessenger] named argument is
   /// available for dependency injection.  If it is left null, the default
   /// BinaryMessenger will be used which routes to the host platform.
   FlutterAssetManagerHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
-  static const MessageCodec<Object?> codec = _FlutterAssetManagerHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   Future<List<String?>> list(String arg_path) async {
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
@@ -1841,12 +1819,8 @@
   }
 }
 
-class _WebChromeClientFlutterApiCodec extends StandardMessageCodec {
-  const _WebChromeClientFlutterApiCodec();
-}
-
 abstract class WebChromeClientFlutterApi {
-  static const MessageCodec<Object?> codec = _WebChromeClientFlutterApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void onProgressChanged(int instanceId, int webViewInstanceId, int progress);
   static void setup(WebChromeClientFlutterApi? api,
@@ -1881,20 +1855,15 @@
   }
 }
 
-class _WebStorageHostApiCodec extends StandardMessageCodec {
-  const _WebStorageHostApiCodec();
-}
-
 class WebStorageHostApi {
   /// Constructor for [WebStorageHostApi].  The [binaryMessenger] named argument is
   /// available for dependency injection.  If it is left null, the default
   /// BinaryMessenger will be used which routes to the host platform.
   WebStorageHostApi({BinaryMessenger? binaryMessenger})
       : _binaryMessenger = binaryMessenger;
-
   final BinaryMessenger? _binaryMessenger;
 
-  static const MessageCodec<Object?> codec = _WebStorageHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   Future<void> create(int arg_instanceId) async {
     final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_api_impls.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_api_impls.dart
index 5becdb3..8aa5f7d 100644
--- a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_api_impls.dart
+++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_api_impls.dart
@@ -537,9 +537,20 @@
   Future<void> createFromInstance(WebViewClient instance) async {
     if (instanceManager.getIdentifier(instance) == null) {
       final int identifier = instanceManager.addDartCreatedInstance(instance);
-      return create(identifier, instance.shouldOverrideUrlLoading);
+      return create(identifier);
     }
   }
+
+  /// Helper method to convert instances ids to objects.
+  Future<void> setShouldOverrideUrlLoadingReturnValueFromInstance(
+    WebViewClient instance,
+    bool value,
+  ) {
+    return setSynchronousReturnValueForShouldOverrideUrlLoading(
+      instanceManager.getIdentifier(instance)!,
+      value,
+    );
+  }
 }
 
 /// Flutter api implementation for [WebViewClient].
diff --git a/packages/webview_flutter/webview_flutter_android/lib/webview_android_widget.dart b/packages/webview_flutter/webview_flutter_android/lib/webview_android_widget.dart
index 8070a11..4cb99b5 100644
--- a/packages/webview_flutter/webview_flutter_android/lib/webview_android_widget.dart
+++ b/packages/webview_flutter/webview_flutter_android/lib/webview_android_widget.dart
@@ -122,6 +122,7 @@
     _setCreationParams(creationParams);
     webView.setDownloadListener(downloadListener);
     webView.setWebChromeClient(webChromeClient);
+    webView.setWebViewClient(webViewClient);
 
     final String? initialUrl = creationParams.initialUrl;
     if (initialUrl != null) {
@@ -132,7 +133,58 @@
   final Map<String, WebViewAndroidJavaScriptChannel> _javaScriptChannels =
       <String, WebViewAndroidJavaScriptChannel>{};
 
-  late android_webview.WebViewClient _webViewClient;
+  late final android_webview.WebViewClient _webViewClient = withWeakRefenceTo(
+      this, (WeakReference<WebViewAndroidPlatformController> weakReference) {
+    return webViewProxy.createWebViewClient(
+      onPageStarted: (_, String url) {
+        weakReference.target?.callbacksHandler.onPageStarted(url);
+      },
+      onPageFinished: (_, String url) {
+        weakReference.target?.callbacksHandler.onPageFinished(url);
+      },
+      onReceivedError: (
+        _,
+        int errorCode,
+        String description,
+        String failingUrl,
+      ) {
+        weakReference.target?.callbacksHandler
+            .onWebResourceError(WebResourceError(
+          errorCode: errorCode,
+          description: description,
+          failingUrl: failingUrl,
+          errorType: _errorCodeToErrorType(errorCode),
+        ));
+      },
+      onReceivedRequestError: (
+        _,
+        android_webview.WebResourceRequest request,
+        android_webview.WebResourceError error,
+      ) {
+        if (request.isForMainFrame) {
+          weakReference.target?.callbacksHandler
+              .onWebResourceError(WebResourceError(
+            errorCode: error.errorCode,
+            description: error.description,
+            failingUrl: request.url,
+            errorType: _errorCodeToErrorType(error.errorCode),
+          ));
+        }
+      },
+      urlLoading: (_, String url) {
+        weakReference.target?._handleNavigationRequest(
+          url: url,
+          isForMainFrame: true,
+        );
+      },
+      requestLoading: (_, android_webview.WebResourceRequest request) {
+        weakReference.target?._handleNavigationRequest(
+          url: request.url,
+          isForMainFrame: request.isForMainFrame,
+        );
+      },
+    );
+  });
 
   bool _hasNavigationDelegate = false;
   bool _hasProgressTracking = false;
@@ -416,58 +468,9 @@
 
   Future<void> _setHasNavigationDelegate(bool hasNavigationDelegate) {
     _hasNavigationDelegate = hasNavigationDelegate;
-
-    final WeakReference<WebViewAndroidPlatformController> weakThis =
-        WeakReference<WebViewAndroidPlatformController>(this);
-    _webViewClient = android_webview.WebViewClient(
-      shouldOverrideUrlLoading: hasNavigationDelegate,
-      onPageStarted: (_, String url) {
-        weakThis.target?.callbacksHandler.onPageStarted(url);
-      },
-      onPageFinished: (_, String url) {
-        weakThis.target?.callbacksHandler.onPageFinished(url);
-      },
-      onReceivedError: (
-        _,
-        int errorCode,
-        String description,
-        String failingUrl,
-      ) {
-        weakThis.target?.callbacksHandler.onWebResourceError(WebResourceError(
-          errorCode: errorCode,
-          description: description,
-          failingUrl: failingUrl,
-          errorType: _errorCodeToErrorType(errorCode),
-        ));
-      },
-      onReceivedRequestError: (
-        _,
-        android_webview.WebResourceRequest request,
-        android_webview.WebResourceError error,
-      ) {
-        if (request.isForMainFrame) {
-          weakThis.target?.callbacksHandler.onWebResourceError(WebResourceError(
-            errorCode: error.errorCode,
-            description: error.description,
-            failingUrl: request.url,
-            errorType: _errorCodeToErrorType(error.errorCode),
-          ));
-        }
-      },
-      urlLoading: (_, String url) {
-        weakThis.target?._handleNavigationRequest(
-          url: url,
-          isForMainFrame: true,
-        );
-      },
-      requestLoading: (_, android_webview.WebResourceRequest request) {
-        weakThis.target?._handleNavigationRequest(
-          url: request.url,
-          isForMainFrame: request.isForMainFrame,
-        );
-      },
+    return _webViewClient.setSynchronousReturnValueForShouldOverrideUrlLoading(
+      hasNavigationDelegate,
     );
-    return webView.setWebViewClient(_webViewClient);
   }
 
   Future<void> _setJavaScriptMode(JavascriptMode mode) {
@@ -600,6 +603,38 @@
     return android_webview.WebView(useHybridComposition: useHybridComposition);
   }
 
+  /// Constructs a [android_webview.WebViewClient].
+  android_webview.WebViewClient createWebViewClient({
+    void Function(android_webview.WebView webView, String url)? onPageStarted,
+    void Function(android_webview.WebView webView, String url)? onPageFinished,
+    void Function(
+      android_webview.WebView webView,
+      android_webview.WebResourceRequest request,
+      android_webview.WebResourceError error,
+    )?
+        onReceivedRequestError,
+    void Function(
+      android_webview.WebView webView,
+      int errorCode,
+      String description,
+      String failingUrl,
+    )?
+        onReceivedError,
+    void Function(android_webview.WebView webView,
+            android_webview.WebResourceRequest request)?
+        requestLoading,
+    void Function(android_webview.WebView webView, String url)? urlLoading,
+  }) {
+    return android_webview.WebViewClient(
+      onPageStarted: onPageStarted,
+      onPageFinished: onPageFinished,
+      onReceivedRequestError: onReceivedRequestError,
+      onReceivedError: onReceivedError,
+      requestLoading: requestLoading,
+      urlLoading: urlLoading,
+    );
+  }
+
   /// Enables debugging of web contents (HTML / CSS / JavaScript) loaded into any WebViews of this application.
   ///
   /// This flag can be enabled in order to facilitate debugging of web layouts
diff --git a/packages/webview_flutter/webview_flutter_android/pigeons/android_webview.dart b/packages/webview_flutter/webview_flutter_android/pigeons/android_webview.dart
index 26f773d..d3adac8 100644
--- a/packages/webview_flutter/webview_flutter_android/pigeons/android_webview.dart
+++ b/packages/webview_flutter/webview_flutter_android/pigeons/android_webview.dart
@@ -204,7 +204,12 @@
 
 @HostApi(dartHostTestHandler: 'TestWebViewClientHostApi')
 abstract class WebViewClientHostApi {
-  void create(int instanceId, bool shouldOverrideUrlLoading);
+  void create(int instanceId);
+
+  void setSynchronousReturnValueForShouldOverrideUrlLoading(
+    int instanceId,
+    bool value,
+  );
 }
 
 @FlutterApi()
diff --git a/packages/webview_flutter/webview_flutter_android/pubspec.yaml b/packages/webview_flutter/webview_flutter_android/pubspec.yaml
index 94a8e5e..8384b7c 100644
--- a/packages/webview_flutter/webview_flutter_android/pubspec.yaml
+++ b/packages/webview_flutter/webview_flutter_android/pubspec.yaml
@@ -29,5 +29,5 @@
     sdk: flutter
   flutter_test:
     sdk: flutter
-  mockito: ^5.2.0
-  pigeon: ^4.0.2
+  mockito: ^5.3.2
+  pigeon: ^4.2.3
diff --git a/packages/webview_flutter/webview_flutter_android/test/android_webview_test.dart b/packages/webview_flutter/webview_flutter_android/test/android_webview_test.dart
index d10f4e7..4e972fe 100644
--- a/packages/webview_flutter/webview_flutter_android/test/android_webview_test.dart
+++ b/packages/webview_flutter/webview_flutter_android/test/android_webview_test.dart
@@ -269,7 +269,6 @@
 
         final WebViewClient mockWebViewClient = MockWebViewClient();
         when(mockWebViewClient.copy()).thenReturn(MockWebViewClient());
-        when(mockWebViewClient.shouldOverrideUrlLoading).thenReturn(false);
         instanceManager.addDartCreatedInstance(mockWebViewClient);
         webView.setWebViewClient(mockWebViewClient);
 
diff --git a/packages/webview_flutter/webview_flutter_android/test/android_webview_test.mocks.dart b/packages/webview_flutter/webview_flutter_android/test/android_webview_test.mocks.dart
index 6ffda42..81cdc9e 100644
--- a/packages/webview_flutter/webview_flutter_android/test/android_webview_test.mocks.dart
+++ b/packages/webview_flutter/webview_flutter_android/test/android_webview_test.mocks.dart
@@ -1,4 +1,4 @@
-// Mocks generated by Mockito 5.3.1 from annotations
+// Mocks generated by Mockito 5.3.2 from annotations
 // in webview_flutter_android/test/android_webview_test.dart.
 // Do not manually edit this file.
 
@@ -549,16 +549,24 @@
   }
 
   @override
-  void create(
+  void create(int? instanceId) => super.noSuchMethod(
+        Invocation.method(
+          #create,
+          [instanceId],
+        ),
+        returnValueForMissingStub: null,
+      );
+  @override
+  void setSynchronousReturnValueForShouldOverrideUrlLoading(
     int? instanceId,
-    bool? shouldOverrideUrlLoading,
+    bool? value,
   ) =>
       super.noSuchMethod(
         Invocation.method(
-          #create,
+          #setSynchronousReturnValueForShouldOverrideUrlLoading,
           [
             instanceId,
-            shouldOverrideUrlLoading,
+            value,
           ],
         ),
         returnValueForMissingStub: null,
@@ -1280,10 +1288,16 @@
   }
 
   @override
-  bool get shouldOverrideUrlLoading => (super.noSuchMethod(
-        Invocation.getter(#shouldOverrideUrlLoading),
-        returnValue: false,
-      ) as bool);
+  _i5.Future<void> setSynchronousReturnValueForShouldOverrideUrlLoading(
+          bool? value) =>
+      (super.noSuchMethod(
+        Invocation.method(
+          #setSynchronousReturnValueForShouldOverrideUrlLoading,
+          [value],
+        ),
+        returnValue: _i5.Future<void>.value(),
+        returnValueForMissingStub: _i5.Future<void>.value(),
+      ) as _i5.Future<void>);
   @override
   _i2.WebViewClient copy() => (super.noSuchMethod(
         Invocation.method(
diff --git a/packages/webview_flutter/webview_flutter_android/test/test_android_webview.pigeon.dart b/packages/webview_flutter/webview_flutter_android/test/test_android_webview.pigeon.dart
index 91a7bf1..bcfb453 100644
--- a/packages/webview_flutter/webview_flutter_android/test/test_android_webview.pigeon.dart
+++ b/packages/webview_flutter/webview_flutter_android/test/test_android_webview.pigeon.dart
@@ -1,7 +1,7 @@
 // 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.
-// Autogenerated from Pigeon (v4.0.2), do not edit directly.
+// Autogenerated from Pigeon (v4.2.3), do not edit directly.
 // See also: https://pub.dev/packages/pigeon
 // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import
 // ignore_for_file: avoid_relative_lib_imports
@@ -13,12 +13,13 @@
 
 import 'package:webview_flutter_android/src/android_webview.pigeon.dart';
 
-class _TestJavaObjectHostApiCodec extends StandardMessageCodec {
-  const _TestJavaObjectHostApiCodec();
-}
-
+/// Handles methods calls to the native Java Object class.
+///
+/// Also handles calls to remove the reference to an instance with `dispose`.
+///
+/// See https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html.
 abstract class TestJavaObjectHostApi {
-  static const MessageCodec<Object?> codec = _TestJavaObjectHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void dispose(int identifier);
   static void setup(TestJavaObjectHostApi? api,
@@ -664,12 +665,8 @@
   }
 }
 
-class _TestWebSettingsHostApiCodec extends StandardMessageCodec {
-  const _TestWebSettingsHostApiCodec();
-}
-
 abstract class TestWebSettingsHostApi {
-  static const MessageCodec<Object?> codec = _TestWebSettingsHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void create(int instanceId, int webViewInstanceId);
   void setDomStorageEnabled(int instanceId, bool flag);
@@ -979,13 +976,8 @@
   }
 }
 
-class _TestJavaScriptChannelHostApiCodec extends StandardMessageCodec {
-  const _TestJavaScriptChannelHostApiCodec();
-}
-
 abstract class TestJavaScriptChannelHostApi {
-  static const MessageCodec<Object?> codec =
-      _TestJavaScriptChannelHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void create(int instanceId, String channelName);
   static void setup(TestJavaScriptChannelHostApi? api,
@@ -1015,14 +1007,12 @@
   }
 }
 
-class _TestWebViewClientHostApiCodec extends StandardMessageCodec {
-  const _TestWebViewClientHostApiCodec();
-}
-
 abstract class TestWebViewClientHostApi {
-  static const MessageCodec<Object?> codec = _TestWebViewClientHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
-  void create(int instanceId, bool shouldOverrideUrlLoading);
+  void create(int instanceId);
+  void setSynchronousReturnValueForShouldOverrideUrlLoading(
+      int instanceId, bool value);
   static void setup(TestWebViewClientHostApi? api,
       {BinaryMessenger? binaryMessenger}) {
     {
@@ -1039,10 +1029,31 @@
           final int? arg_instanceId = (args[0] as int?);
           assert(arg_instanceId != null,
               'Argument for dev.flutter.pigeon.WebViewClientHostApi.create was null, expected non-null int.');
-          final bool? arg_shouldOverrideUrlLoading = (args[1] as bool?);
-          assert(arg_shouldOverrideUrlLoading != null,
-              'Argument for dev.flutter.pigeon.WebViewClientHostApi.create was null, expected non-null bool.');
-          api.create(arg_instanceId!, arg_shouldOverrideUrlLoading!);
+          api.create(arg_instanceId!);
+          return <Object?, Object?>{};
+        });
+      }
+    }
+    {
+      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+          'dev.flutter.pigeon.WebViewClientHostApi.setSynchronousReturnValueForShouldOverrideUrlLoading',
+          codec,
+          binaryMessenger: binaryMessenger);
+      if (api == null) {
+        channel.setMockMessageHandler(null);
+      } else {
+        channel.setMockMessageHandler((Object? message) async {
+          assert(message != null,
+              'Argument for dev.flutter.pigeon.WebViewClientHostApi.setSynchronousReturnValueForShouldOverrideUrlLoading was null.');
+          final List<Object?> args = (message as List<Object?>?)!;
+          final int? arg_instanceId = (args[0] as int?);
+          assert(arg_instanceId != null,
+              'Argument for dev.flutter.pigeon.WebViewClientHostApi.setSynchronousReturnValueForShouldOverrideUrlLoading was null, expected non-null int.');
+          final bool? arg_value = (args[1] as bool?);
+          assert(arg_value != null,
+              'Argument for dev.flutter.pigeon.WebViewClientHostApi.setSynchronousReturnValueForShouldOverrideUrlLoading was null, expected non-null bool.');
+          api.setSynchronousReturnValueForShouldOverrideUrlLoading(
+              arg_instanceId!, arg_value!);
           return <Object?, Object?>{};
         });
       }
@@ -1050,13 +1061,8 @@
   }
 }
 
-class _TestDownloadListenerHostApiCodec extends StandardMessageCodec {
-  const _TestDownloadListenerHostApiCodec();
-}
-
 abstract class TestDownloadListenerHostApi {
-  static const MessageCodec<Object?> codec =
-      _TestDownloadListenerHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void create(int instanceId);
   static void setup(TestDownloadListenerHostApi? api,
@@ -1083,12 +1089,8 @@
   }
 }
 
-class _TestWebChromeClientHostApiCodec extends StandardMessageCodec {
-  const _TestWebChromeClientHostApiCodec();
-}
-
 abstract class TestWebChromeClientHostApi {
-  static const MessageCodec<Object?> codec = _TestWebChromeClientHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void create(int instanceId);
   static void setup(TestWebChromeClientHostApi? api,
@@ -1115,12 +1117,8 @@
   }
 }
 
-class _TestAssetManagerHostApiCodec extends StandardMessageCodec {
-  const _TestAssetManagerHostApiCodec();
-}
-
 abstract class TestAssetManagerHostApi {
-  static const MessageCodec<Object?> codec = _TestAssetManagerHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   List<String?> list(String path);
   String getAssetFilePathByName(String name);
@@ -1168,12 +1166,8 @@
   }
 }
 
-class _TestWebStorageHostApiCodec extends StandardMessageCodec {
-  const _TestWebStorageHostApiCodec();
-}
-
 abstract class TestWebStorageHostApi {
-  static const MessageCodec<Object?> codec = _TestWebStorageHostApiCodec();
+  static const MessageCodec<Object?> codec = StandardMessageCodec();
 
   void create(int instanceId);
   void deleteAllData(int instanceId);
diff --git a/packages/webview_flutter/webview_flutter_android/test/v4/android_webview_cookie_manager_test.mocks.dart b/packages/webview_flutter/webview_flutter_android/test/v4/android_webview_cookie_manager_test.mocks.dart
index a7279d5..df673fc 100644
--- a/packages/webview_flutter/webview_flutter_android/test/v4/android_webview_cookie_manager_test.mocks.dart
+++ b/packages/webview_flutter/webview_flutter_android/test/v4/android_webview_cookie_manager_test.mocks.dart
@@ -1,4 +1,4 @@
-// Mocks generated by Mockito 5.3.1 from annotations
+// Mocks generated by Mockito 5.3.2 from annotations
 // in webview_flutter_android/test/v4/android_webview_cookie_manager_test.dart.
 // Do not manually edit this file.
 
diff --git a/packages/webview_flutter/webview_flutter_android/test/webview_android_cookie_manager_test.mocks.dart b/packages/webview_flutter/webview_flutter_android/test/webview_android_cookie_manager_test.mocks.dart
index dea6d80..725e63a 100644
--- a/packages/webview_flutter/webview_flutter_android/test/webview_android_cookie_manager_test.mocks.dart
+++ b/packages/webview_flutter/webview_flutter_android/test/webview_android_cookie_manager_test.mocks.dart
@@ -1,4 +1,4 @@
-// Mocks generated by Mockito 5.3.1 from annotations
+// Mocks generated by Mockito 5.3.2 from annotations
 // in webview_flutter_android/test/webview_android_cookie_manager_test.dart.
 // Do not manually edit this file.
 
diff --git a/packages/webview_flutter/webview_flutter_android/test/webview_android_widget_test.dart b/packages/webview_flutter/webview_flutter_android/test/webview_android_widget_test.dart
index 5eea6db..4d85510 100644
--- a/packages/webview_flutter/webview_flutter_android/test/webview_android_widget_test.dart
+++ b/packages/webview_flutter/webview_flutter_android/test/webview_android_widget_test.dart
@@ -44,7 +44,7 @@
     late MockWebViewProxy mockWebViewProxy;
 
     late MockWebViewPlatformCallbacksHandler mockCallbacksHandler;
-    late android_webview.WebViewClient webViewClient;
+    late MockWebViewClient mockWebViewClient;
     late android_webview.DownloadListener downloadListener;
     late android_webview.WebChromeClient webChromeClient;
 
@@ -57,12 +57,21 @@
       mockWebView = MockWebView();
       mockWebSettings = MockWebSettings();
       mockWebStorage = MockWebStorage();
+      mockWebViewClient = MockWebViewClient();
       when(mockWebView.settings).thenReturn(mockWebSettings);
 
       mockWebViewProxy = MockWebViewProxy();
       when(mockWebViewProxy.createWebView(
         useHybridComposition: anyNamed('useHybridComposition'),
       )).thenReturn(mockWebView);
+      when(mockWebViewProxy.createWebViewClient(
+        onPageStarted: anyNamed('onPageStarted'),
+        onPageFinished: anyNamed('onPageFinished'),
+        onReceivedError: anyNamed('onReceivedError'),
+        onReceivedRequestError: anyNamed('onReceivedRequestError'),
+        requestLoading: anyNamed('requestLoading'),
+        urlLoading: anyNamed('urlLoading'),
+      )).thenReturn(mockWebViewClient);
 
       mockCallbacksHandler = MockWebViewPlatformCallbacksHandler();
       mockJavascriptChannelRegistry = MockJavascriptChannelRegistry();
@@ -96,7 +105,7 @@
         },
       ));
 
-      webViewClient = testController.webViewClient;
+      mockWebViewClient = testController.webViewClient as MockWebViewClient;
       downloadListener = testController.downloadListener;
       webChromeClient = testController.webChromeClient;
     }
@@ -113,9 +122,9 @@
       verify(mockWebSettings.setBuiltInZoomControls(true));
 
       verifyInOrder(<Future<void>>[
-        mockWebView.setWebViewClient(webViewClient),
         mockWebView.setDownloadListener(downloadListener),
         mockWebView.setWebChromeClient(webChromeClient),
+        mockWebView.setWebViewClient(mockWebViewClient),
       ]);
     });
 
@@ -224,6 +233,16 @@
         });
 
         testWidgets('hasNavigationDelegate', (WidgetTester tester) async {
+          final MockWebViewClient mockWebViewClient = MockWebViewClient();
+          when(mockWebViewProxy.createWebViewClient(
+            onPageStarted: anyNamed('onPageStarted'),
+            onPageFinished: anyNamed('onPageFinished'),
+            onReceivedError: anyNamed('onReceivedError'),
+            onReceivedRequestError: anyNamed('onReceivedRequestError'),
+            requestLoading: anyNamed('requestLoading'),
+            urlLoading: anyNamed('urlLoading'),
+          )).thenReturn(mockWebViewClient);
+
           await buildWidget(
             tester,
             creationParams: CreationParams(
@@ -234,7 +253,10 @@
             ),
           );
 
-          expect(testController.webViewClient.shouldOverrideUrlLoading, isTrue);
+          verify(
+            mockWebViewClient
+                .setSynchronousReturnValueForShouldOverrideUrlLoading(true),
+          );
         });
 
         testWidgets('debuggingEnabled true', (WidgetTester tester) async {
@@ -691,20 +713,53 @@
     group('WebViewPlatformCallbacksHandler', () {
       testWidgets('onPageStarted', (WidgetTester tester) async {
         await buildWidget(tester);
-        webViewClient.onPageStarted!(mockWebView, 'https://google.com');
+        final void Function(android_webview.WebView, String) onPageStarted =
+            verify(mockWebViewProxy.createWebViewClient(
+          onPageStarted: captureAnyNamed('onPageStarted'),
+          onPageFinished: anyNamed('onPageFinished'),
+          onReceivedError: anyNamed('onReceivedError'),
+          onReceivedRequestError: anyNamed('onReceivedRequestError'),
+          requestLoading: anyNamed('requestLoading'),
+          urlLoading: anyNamed('urlLoading'),
+        )).captured.single as Function(android_webview.WebView, String);
+
+        onPageStarted(mockWebView, 'https://google.com');
         verify(mockCallbacksHandler.onPageStarted('https://google.com'));
       });
 
       testWidgets('onPageFinished', (WidgetTester tester) async {
         await buildWidget(tester);
-        webViewClient.onPageFinished!(mockWebView, 'https://google.com');
+
+        final void Function(android_webview.WebView, String) onPageFinished =
+            verify(mockWebViewProxy.createWebViewClient(
+          onPageStarted: anyNamed('onPageStarted'),
+          onPageFinished: captureAnyNamed('onPageFinished'),
+          onReceivedError: anyNamed('onReceivedError'),
+          onReceivedRequestError: anyNamed('onReceivedRequestError'),
+          requestLoading: anyNamed('requestLoading'),
+          urlLoading: anyNamed('urlLoading'),
+        )).captured.single as Function(android_webview.WebView, String);
+
+        onPageFinished(mockWebView, 'https://google.com');
         verify(mockCallbacksHandler.onPageFinished('https://google.com'));
       });
 
       testWidgets('onWebResourceError from onReceivedError',
           (WidgetTester tester) async {
         await buildWidget(tester);
-        webViewClient.onReceivedError!(
+
+        final void Function(android_webview.WebView, int, String, String)
+            onReceivedError = verify(mockWebViewProxy.createWebViewClient(
+          onPageStarted: anyNamed('onPageStarted'),
+          onPageFinished: anyNamed('onPageFinished'),
+          onReceivedError: captureAnyNamed('onReceivedError'),
+          onReceivedRequestError: anyNamed('onReceivedRequestError'),
+          requestLoading: anyNamed('requestLoading'),
+          urlLoading: anyNamed('urlLoading'),
+        )).captured.single as Function(
+                android_webview.WebView, int, String, String);
+
+        onReceivedError(
           mockWebView,
           android_webview.WebViewClient.errorAuthentication,
           'description',
@@ -725,7 +780,25 @@
       testWidgets('onWebResourceError from onReceivedRequestError',
           (WidgetTester tester) async {
         await buildWidget(tester);
-        webViewClient.onReceivedRequestError!(
+
+        final void Function(
+          android_webview.WebView,
+          android_webview.WebResourceRequest,
+          android_webview.WebResourceError,
+        ) onReceivedRequestError = verify(mockWebViewProxy.createWebViewClient(
+          onPageStarted: anyNamed('onPageStarted'),
+          onPageFinished: anyNamed('onPageFinished'),
+          onReceivedError: anyNamed('onReceivedError'),
+          onReceivedRequestError: captureAnyNamed('onReceivedRequestError'),
+          requestLoading: anyNamed('requestLoading'),
+          urlLoading: anyNamed('urlLoading'),
+        )).captured.single as Function(
+          android_webview.WebView,
+          android_webview.WebResourceRequest,
+          android_webview.WebResourceError,
+        );
+
+        onReceivedRequestError(
           mockWebView,
           android_webview.WebResourceRequest(
             url: 'https://google.com',
@@ -760,7 +833,17 @@
           url: 'https://google.com',
         )).thenReturn(true);
 
-        webViewClient.urlLoading!(mockWebView, 'https://google.com');
+        final void Function(android_webview.WebView, String) urlLoading =
+            verify(mockWebViewProxy.createWebViewClient(
+          onPageStarted: anyNamed('onPageStarted'),
+          onPageFinished: anyNamed('onPageFinished'),
+          onReceivedError: anyNamed('onReceivedError'),
+          onReceivedRequestError: anyNamed('onReceivedRequestError'),
+          requestLoading: anyNamed('requestLoading'),
+          urlLoading: captureAnyNamed('urlLoading'),
+        )).captured.single as Function(android_webview.WebView, String);
+
+        urlLoading(mockWebView, 'https://google.com');
         verify(mockCallbacksHandler.onNavigationRequest(
           url: 'https://google.com',
           isForMainFrame: true,
@@ -776,7 +859,22 @@
           url: 'https://google.com',
         )).thenReturn(true);
 
-        webViewClient.requestLoading!(
+        final void Function(
+          android_webview.WebView,
+          android_webview.WebResourceRequest,
+        ) requestLoading = verify(mockWebViewProxy.createWebViewClient(
+          onPageStarted: anyNamed('onPageStarted'),
+          onPageFinished: anyNamed('onPageFinished'),
+          onReceivedError: anyNamed('onReceivedError'),
+          onReceivedRequestError: anyNamed('onReceivedRequestError'),
+          requestLoading: captureAnyNamed('requestLoading'),
+          urlLoading: anyNamed('urlLoading'),
+        )).captured.single as Function(
+          android_webview.WebView,
+          android_webview.WebResourceRequest,
+        );
+
+        requestLoading(
           mockWebView,
           android_webview.WebResourceRequest(
             url: 'https://google.com',
diff --git a/packages/webview_flutter/webview_flutter_android/test/webview_android_widget_test.mocks.dart b/packages/webview_flutter/webview_flutter_android/test/webview_android_widget_test.mocks.dart
index 390e2ab..a012ae2 100644
--- a/packages/webview_flutter/webview_flutter_android/test/webview_android_widget_test.mocks.dart
+++ b/packages/webview_flutter/webview_flutter_android/test/webview_android_widget_test.mocks.dart
@@ -1,4 +1,4 @@
-// Mocks generated by Mockito 5.3.1 from annotations
+// Mocks generated by Mockito 5.3.2 from annotations
 // in webview_flutter_android/test/webview_android_widget_test.dart.
 // Do not manually edit this file.
 
@@ -787,10 +787,16 @@
   }
 
   @override
-  bool get shouldOverrideUrlLoading => (super.noSuchMethod(
-        Invocation.getter(#shouldOverrideUrlLoading),
-        returnValue: false,
-      ) as bool);
+  _i5.Future<void> setSynchronousReturnValueForShouldOverrideUrlLoading(
+          bool? value) =>
+      (super.noSuchMethod(
+        Invocation.method(
+          #setSynchronousReturnValueForShouldOverrideUrlLoading,
+          [value],
+        ),
+        returnValue: _i5.Future<void>.value(),
+        returnValueForMissingStub: _i5.Future<void>.value(),
+      ) as _i5.Future<void>);
   @override
   _i2.WebViewClient copy() => (super.noSuchMethod(
         Invocation.method(
@@ -932,6 +938,71 @@
         ),
       ) as _i2.WebView);
   @override
+  _i2.WebViewClient createWebViewClient({
+    void Function(
+      _i2.WebView,
+      String,
+    )?
+        onPageStarted,
+    void Function(
+      _i2.WebView,
+      String,
+    )?
+        onPageFinished,
+    void Function(
+      _i2.WebView,
+      _i2.WebResourceRequest,
+      _i2.WebResourceError,
+    )?
+        onReceivedRequestError,
+    void Function(
+      _i2.WebView,
+      int,
+      String,
+      String,
+    )?
+        onReceivedError,
+    void Function(
+      _i2.WebView,
+      _i2.WebResourceRequest,
+    )?
+        requestLoading,
+    void Function(
+      _i2.WebView,
+      String,
+    )?
+        urlLoading,
+  }) =>
+      (super.noSuchMethod(
+        Invocation.method(
+          #createWebViewClient,
+          [],
+          {
+            #onPageStarted: onPageStarted,
+            #onPageFinished: onPageFinished,
+            #onReceivedRequestError: onReceivedRequestError,
+            #onReceivedError: onReceivedError,
+            #requestLoading: requestLoading,
+            #urlLoading: urlLoading,
+          },
+        ),
+        returnValue: _FakeWebViewClient_8(
+          this,
+          Invocation.method(
+            #createWebViewClient,
+            [],
+            {
+              #onPageStarted: onPageStarted,
+              #onPageFinished: onPageFinished,
+              #onReceivedRequestError: onReceivedRequestError,
+              #onReceivedError: onReceivedError,
+              #requestLoading: requestLoading,
+              #urlLoading: urlLoading,
+            },
+          ),
+        ),
+      ) as _i2.WebViewClient);
+  @override
   _i5.Future<void> setWebContentsDebuggingEnabled(bool? enabled) =>
       (super.noSuchMethod(
         Invocation.method(