Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
use WebViewClientCompat, rename isMainFrame to isForMainFrame
  • Loading branch information
amirh committed Mar 8, 2019
commit 6df13d9b3fee402fa74cd738dc53a60e8480eee8
4 changes: 4 additions & 0 deletions packages/webview_flutter/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,8 @@ android {
lintOptions {
disable 'InvalidPackage'
}

dependencies {
implementation 'androidx.webkit:webkit:1.0.0'
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,20 @@

import android.annotation.TargetApi;
import android.os.Build;
import android.util.Log;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.webkit.WebViewClientCompat;
import io.flutter.plugin.common.MethodChannel;
import java.util.HashMap;
import java.util.Map;

class FlutterWebViewClient extends WebViewClient {
// 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;

Expand All @@ -40,7 +46,7 @@ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request
// 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 originated in the main frame, if the request is not for the main frame
// 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
Expand All @@ -52,6 +58,14 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (!hasNavigationDelegate) {
return super.shouldOverrideUrlLoading(view, url);
}
// 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;
}
Expand All @@ -60,7 +74,7 @@ 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("isMainFrame", isMainFrame);
args.put("isForMainFrame", isMainFrame);
if (isMainFrame) {
methodChannel.invokeMethod(
"navigationRequest", args, new OnNavigationRequestResult(url, headers, webview));
Expand Down
1 change: 1 addition & 0 deletions packages/webview_flutter/example/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
org.gradle.jvmargs=-Xmx1536M
android.useAndroixX=true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
android.useAndroixX=true
android.useAndroidX=true

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, thanks fixed.

10 changes: 5 additions & 5 deletions packages/webview_flutter/lib/webview_flutter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,17 @@ typedef void JavascriptMessageHandler(JavascriptMessage message);

/// Information about a navigation action that is about to be executed.
class NavigationRequest {
NavigationRequest._({this.url, this.isMainFrame});
NavigationRequest._({this.url, this.isForMainFrame});

/// The URL that will be loaded if the navigation is executed.
final String url;

/// Whether the navigation request originated from the main HTML frame.
final bool isMainFrame;
/// Whether the navigation request is to be loaded as the main frame.
final bool isForMainFrame;

@override
String toString() {
return '$runtimeType(url: $url, isMainFrame: $isMainFrame)';
return '$runtimeType(url: $url, isForMainFrame: $isForMainFrame)';
}
}

Expand Down Expand Up @@ -385,7 +385,7 @@ class WebViewController {
case 'navigationRequest':
final NavigationRequest request = NavigationRequest._(
url: call.arguments['url'],
isMainFrame: call.arguments['isMainFrame'],
isForMainFrame: call.arguments['isForMainFrame'],
);

// _navigationDelegate can be null if the widget was rebuilt with no
Expand Down
13 changes: 9 additions & 4 deletions packages/webview_flutter/test/webview_flutter_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -619,9 +619,10 @@ void main() {
expect(platformWebView.currentUrl, 'https://youtube.com');
expect(navigationRequests.length, 1);
expect(navigationRequests[0].url, 'https://www.google.com');
expect(navigationRequests[0].isMainFrame, true);
expect(navigationRequests[0].isForMainFrame, true);

platformWebView.fakeNavigate('https://flutter.dev');
await tester.pump();
expect(platformWebView.currentUrl, 'https://flutter.dev');
});
});
Expand Down Expand Up @@ -737,12 +738,16 @@ class FakePlatformWebView {
final StandardMethodCodec codec = const StandardMethodCodec();
final Map<String, dynamic> arguments = <String, dynamic>{
'url': url,
'isMainFrame': true
'isForMainFrame': true
};
final ByteData data =
codec.encodeMethodCall(MethodCall('navigationRequest', arguments));
BinaryMessages.handlePlatformMessage(
channel.name, data, (ByteData data) {});
BinaryMessages.handlePlatformMessage(channel.name, data, (ByteData data) {
final bool allow = codec.decodeEnvelope(data);
if (allow) {
_loadUrl(url);
}
});
}

void _loadUrl(String url) {
Expand Down