This repository was archived by the owner on Feb 22, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
[webview_flutter]Allow specifying a navigation delegate(Android and Dart). #1236
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
729bcbd
[WebView] Allow specifying a navigation delegate.
amirh 8ac15be
review comments follow-up
amirh 8e2a9e9
remove stray thanks
amirh 46d8bf6
retain HTTP headers when possible when using a navigation delegate
amirh 8d9101c
add more documentation for caveats on Android
amirh a743f8d
format
amirh 6df13d9
use WebViewClientCompat, rename isMainFrame to isForMainFrame
amirh d9d671e
typo fix, update documentation
amirh e3eec87
bump version, update changelog
amirh 530d024
don't call super.shouldOverrideUrlLoading
amirh 151b47d
Merge branch 'master' into navigation_delegate
amirh ad30926
fix nit
amirh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
124 changes: 124 additions & 0 deletions
124
...flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| // Copyright 2019 The Chromium Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| package io.flutter.plugins.webviewflutter; | ||
|
|
||
| import android.annotation.TargetApi; | ||
| import android.os.Build; | ||
| import android.util.Log; | ||
| import android.webkit.WebResourceRequest; | ||
| import android.webkit.WebView; | ||
| import androidx.webkit.WebViewClientCompat; | ||
| import io.flutter.plugin.common.MethodChannel; | ||
| import java.util.HashMap; | ||
| import java.util.Map; | ||
|
|
||
| // We need to use WebViewClientCompat to get | ||
| // shouldOverrideUrlLoading(WebView view, WebResourceRequest request) | ||
| // invoked by the webview on older Android devices, without it pages that use iframes will | ||
| // be broken when a navigationDelegate is set on Android version earlier than N. | ||
| class FlutterWebViewClient extends WebViewClientCompat { | ||
| private static final String TAG = "FlutterWebViewClient"; | ||
| private final MethodChannel methodChannel; | ||
| private boolean hasNavigationDelegate; | ||
|
|
||
| FlutterWebViewClient(MethodChannel methodChannel) { | ||
| this.methodChannel = methodChannel; | ||
| } | ||
|
|
||
| void setHasNavigationDelegate(boolean hasNavigationDelegate) { | ||
| this.hasNavigationDelegate = hasNavigationDelegate; | ||
| } | ||
|
|
||
| @TargetApi(Build.VERSION_CODES.LOLLIPOP) | ||
| @Override | ||
| public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { | ||
| if (!hasNavigationDelegate) { | ||
| return false; | ||
| } | ||
| notifyOnNavigationRequest( | ||
| request.getUrl().toString(), request.getRequestHeaders(), view, request.isForMainFrame()); | ||
| // We must make a synchronous decision here whether to allow the navigation or not, | ||
| // if the Dart code has set a navigation delegate we want that delegate to decide whether | ||
| // to navigate or not, and as we cannot get a response from the Dart delegate synchronously we | ||
| // return true here to block the navigation, if the Dart delegate decides to allow the | ||
| // navigation the plugin will later make an addition loadUrl call for this url. | ||
| // | ||
| // Since we cannot call loadUrl for a subframe, we currently only allow the delegate to stop | ||
| // navigations that target the main frame, if the request is not for the main frame | ||
| // we just return false to allow the navigation. | ||
| // | ||
| // For more details see: https://github.com/flutter/flutter/issues/25329#issuecomment-464863209 | ||
| return request.isForMainFrame(); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean shouldOverrideUrlLoading(WebView view, String url) { | ||
| if (!hasNavigationDelegate) { | ||
| return false; | ||
| } | ||
| // This version of shouldOverrideUrlLoading is only invoked by the webview on devices with | ||
| // webview versions earlier than 67(it is also invoked when hasNavigationDelegate is false). | ||
| // On these devices we cannot tell whether the navigation is targeted to the main frame or not. | ||
| // We proceed assuming that the navigation is targeted to the main frame. If the page had any | ||
| // frames they will be loaded in the main frame instead. | ||
| Log.w( | ||
| TAG, | ||
| "Using a navigationDelegate with an old webview implementation, pages with frames or iframes will not work"); | ||
| notifyOnNavigationRequest(url, null, view, true); | ||
| return true; | ||
| } | ||
|
|
||
| private void notifyOnNavigationRequest( | ||
| String url, Map<String, String> headers, WebView webview, boolean isMainFrame) { | ||
| HashMap<String, Object> args = new HashMap<>(); | ||
| args.put("url", url); | ||
| args.put("isForMainFrame", isMainFrame); | ||
| if (isMainFrame) { | ||
| methodChannel.invokeMethod( | ||
| "navigationRequest", args, new OnNavigationRequestResult(url, headers, webview)); | ||
| } else { | ||
| methodChannel.invokeMethod("navigationRequest", args); | ||
| } | ||
| } | ||
|
|
||
| private static class OnNavigationRequestResult implements MethodChannel.Result { | ||
| private final String url; | ||
| private final Map<String, String> headers; | ||
| private final WebView webView; | ||
|
|
||
| private OnNavigationRequestResult(String url, Map<String, String> headers, WebView webView) { | ||
| this.url = url; | ||
| this.headers = headers; | ||
| this.webView = webView; | ||
| } | ||
|
|
||
| @Override | ||
| public void success(Object shouldLoad) { | ||
| Boolean typedShouldLoad = (Boolean) shouldLoad; | ||
| if (typedShouldLoad) { | ||
| loadUrl(); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public void error(String errorCode, String s1, Object o) { | ||
| throw new IllegalStateException("navigationRequest calls must succeed"); | ||
| } | ||
|
|
||
| @Override | ||
| public void notImplemented() { | ||
| throw new IllegalStateException( | ||
| "navigationRequest must be implemented by the webview method channel"); | ||
| } | ||
|
|
||
| private void loadUrl() { | ||
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||
| webView.loadUrl(url, headers); | ||
| } else { | ||
| webView.loadUrl(url); | ||
| } | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| org.gradle.jvmargs=-Xmx1536M | ||
| android.useAndroidX=true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.