我通过更改一些代码行和3次导入设法解决了应用程序崩溃的问题。
现在我的FlutterWebView看起来像这样:
// Copyright 2018 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.content.Context;
import android.content.ContextWrapper;
import android.hardware.display.DisplayManager;
import android.os.Build;
import android.os.Handler;
import android.view.View;
import android.app.Activity;
import android.webkit.WebStorage;
import android.webkit.WebViewClient;
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.platform.PlatformView;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class FlutterWebView implements PlatformView, MethodCallHandler {
private static final String JS_CHANNEL_NAMES_FIELD = "javascriptChannelNames";
private final InputAwareWebView webView;
private final MethodChannel methodChannel;
private final FlutterWebViewClient flutterWebViewClient;
private final Handler platformThreadHandler;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@SuppressWarnings("unchecked")
FlutterWebView(
final Context context,
BinaryMessenger messenger,
int id,
Map<String, Object> params,
View containerView) {
Context wrappedContext = wrapContext(context);
Context appContext = context.getApplicationContext();
DisplayListenerProxy displayListenerProxy = new DisplayListenerProxy();
DisplayManager displayManager =
(DisplayManager) wrappedContext.getSystemService(Context.DISPLAY_SERVICE);
displayListenerProxy.onPreWebViewInitialization(displayManager);
if (appContext != null) {
wrappedContext = appContext;
}
webView = new InputAwareWebView(wrappedContext, containerView);
displayListenerProxy.onPostWebViewInitialization(displayManager);
platformThreadHandler = new Handler(wrappedContext.getMainLooper());
// Allow local storage.
webView.getSettings().setDomStorageEnabled(true);
methodChannel = new MethodChannel(messenger, "plugins.flutter.io/webview_" + id);
methodChannel.setMethodCallHandler(this);
flutterWebViewClient = new FlutterWebViewClient(methodChannel);
applySettings((Map<String, Object>) params.get("settings"));
if (params.containsKey(JS_CHANNEL_NAMES_FIELD)) {
registerJavaScriptChannelNames((List<String>) params.get(JS_CHANNEL_NAMES_FIELD));
}
updateAutoMediaPlaybackPolicy((Integer) params.get("autoMediaPlaybackPolicy"));
if (params.containsKey("userAgent")) {
String userAgent = (String) params.get("userAgent");
updateUserAgent(userAgent);
}
if (params.containsKey("initialUrl")) {
String url = (String) params.get("initialUrl");
webView.loadUrl(url);
}
}
private Context wrapContext(Context context) {
Context activityContext = context;
Context appContext = context.getApplicationContext();
if (appContext instanceof FlutterApplication) {
Activity currentActivity = ((FlutterApplication) appContext).getCurrentActivity();
if (currentActivity != null) {
activityContext = currentActivity;
}
}
final Context finalContext = activityContext;
// Cannot use activityContext, which will cause the keyboard to be unable to input.
// We have to wrap the original context.
return new ContextWrapper(context) {
@Override
public Object getSystemService(String name) {
if (name == Context.WINDOW_SERVICE) {
return finalContext.getSystemService(name);
}
return super.getSystemService(name);
}
};
}
@Override
public View getView() {
return webView;
}
// @Override
// This is overriding a method that hasn't rolled into stable Flutter yet. Including the
// annotation would cause compile time failures in versions of Flutter too old to include the new
// method. However leaving it raw like this means that the method will be ignored in old versions
// of Flutter but used as an override anyway wherever it's actually defined.
// TODO(mklim): Add the @Override annotation once flutter/engine#9727 rolls to stable.
public void onInputConnectionUnlocked() {
webView.unlockInputConnection();
}
// @Override
// This is overriding a method that hasn't rolled into stable Flutter yet. Including the
// annotation would cause compile time failures in versions of Flutter too old to include the new
// method. However leaving it raw like this means that the method will be ignored in old versions
// of Flutter but used as an override anyway wherever it's actually defined.
// TODO(mklim): Add the @Override annotation once flutter/engine#9727 rolls to stable.
public void onInputConnectionLocked() {
webView.lockInputConnection();
}
// @Override
// This is overriding a method that hasn't rolled into stable Flutter yet. Including the
// annotation would cause compile time failures in versions of Flutter too old to include the new
// method. However leaving it raw like this means that the method will be ignored in old versions
// of Flutter but used as an override anyway wherever it's actually defined.
// TODO(mklim): Add the @Override annotation once stable passes v1.10.9.
public void onFlutterViewAttached(View flutterView) {
webView.setContainerView(flutterView);
}
// @Override
// This is overriding a method that hasn't rolled into stable Flutter yet. Including the
// annotation would cause compile time failures in versions of Flutter too old to include the new
// method. However leaving it raw like this means that the method will be ignored in old versions
// of Flutter but used as an override anyway wherever it's actually defined.
// TODO(mklim): Add the @Override annotation once stable passes v1.10.9.
public void onFlutterViewDetached() {
webView.setContainerView(null);
}
@Override
public void onMethodCall(MethodCall methodCall, Result result) {
switch (methodCall.method) {
case "loadUrl":
loadUrl(methodCall, result);
break;
case "updateSettings":
updateSettings(methodCall, result);
break;
case "canGoBack":
canGoBack(result);
break;
case "canGoForward":
canGoForward(result);
break;
case "goBack":
goBack(result);
break;
case "goForward":
goForward(result);
break;
case "reload":
reload(result);
break;
case "currentUrl":
currentUrl(result);
break;
case "evaluateJavascript":
evaluateJavaScript(methodCall, result);
break;
case "addJavascriptChannels":
addJavaScriptChannels(methodCall, result);
break;
case "removeJavascriptChannels":
removeJavaScriptChannels(methodCall, result);
break;
case "clearCache":
clearCache(result);
break;
case "getTitle":
getTitle(result);
break;
default:
result.notImplemented();
}
}
@SuppressWarnings("unchecked")
private void loadUrl(MethodCall methodCall, Result result) {
Map<String, Object> request = (Map<String, Object>) methodCall.arguments;
String url = (String) request.get("url");
Map<String, String> headers = (Map<String, String>) request.get("headers");
if (headers == null) {
headers = Collections.emptyMap();
}
webView.loadUrl(url, headers);
result.success(null);
}
private void canGoBack(Result result) {
result.success(webView.canGoBack());
}
private void canGoForward(Result result) {
result.success(webView.canGoForward());
}
private void goBack(Result result) {
if (webView.canGoBack()) {
webView.goBack();
}
result.success(null);
}
private void goForward(Result result) {
if (webView.canGoForward()) {
webView.goForward();
}
result.success(null);
}
private void reload(Result result) {
webView.reload();
result.success(null);
}
private void currentUrl(Result result) {
result.success(webView.getUrl());
}
@SuppressWarnings("unchecked")
private void updateSettings(MethodCall methodCall, Result result) {
applySettings((Map<String, Object>) methodCall.arguments);
result.success(null);
}
@TargetApi(Build.VERSION_CODES.KITKAT)
private void evaluateJavaScript(MethodCall methodCall, final Result result) {
String jsString = (String) methodCall.arguments;
if (jsString == null) {
throw new UnsupportedOperationException("JavaScript string cannot be null");
}
webView.evaluateJavascript(
jsString,
new android.webkit.ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
result.success(value);
}
});
}
@SuppressWarnings("unchecked")
private void addJavaScriptChannels(MethodCall methodCall, Result result) {
List<String> channelNames = (List<String>) methodCall.arguments;
registerJavaScriptChannelNames(channelNames);
result.success(null);
}
@SuppressWarnings("unchecked")
private void removeJavaScriptChannels(MethodCall methodCall, Result result) {
List<String> channelNames = (List<String>) methodCall.arguments;
for (String channelName : channelNames) {
webView.removeJavascriptInterface(channelName);
}
result.success(null);
}
private void clearCache(Result result) {
webView.clearCache(true);
WebStorage.getInstance().deleteAllData();
result.success(null);
}
private void getTitle(Result result) {
result.success(webView.getTitle());
}
private void applySettings(Map<String, Object> settings) {
for (String key : settings.keySet()) {
switch (key) {
case "jsMode":
updateJsMode((Integer) settings.get(key));
break;
case "hasNavigationDelegate":
final boolean hasNavigationDelegate = (boolean) settings.get(key);
final WebViewClient webViewClient =
flutterWebViewClient.createWebViewClient(hasNavigationDelegate);
webView.setWebViewClient(webViewClient);
break;
case "debuggingEnabled":
final boolean debuggingEnabled = (boolean) settings.get(key);
webView.setWebContentsDebuggingEnabled(debuggingEnabled);
break;
case "userAgent":
updateUserAgent((String) settings.get(key));
break;
default:
throw new IllegalArgumentException("Unknown WebView setting: " + key);
}
}
}
private void updateJsMode(int mode) {
switch (mode) {
case 0: // disabled
webView.getSettings().setJavaScriptEnabled(false);
break;
case 1: // unrestricted
webView.getSettings().setJavaScriptEnabled(true);
break;
default:
throw new IllegalArgumentException("Trying to set unknown JavaScript mode: " + mode);
}
}
private void updateAutoMediaPlaybackPolicy(int mode) {
// This is the index of the AutoMediaPlaybackPolicy enum, index 1 is always_allow, for all
// other values we require a user gesture.
boolean requireUserGesture = mode != 1;
webView.getSettings().setMediaPlaybackRequiresUserGesture(requireUserGesture);
}
private void registerJavaScriptChannelNames(List<String> channelNames) {
for (String channelName : channelNames) {
webView.addJavascriptInterface(
new JavaScriptChannel(methodChannel, channelName, platformThreadHandler), channelName);
}
}
private void updateUserAgent(String userAgent) {
webView.getSettings().setUserAgentString(userAgent);
}
@Override
public void dispose() {
methodChannel.setMethodCallHandler(null);
webView.dispose();
webView.destroy();
}
}
现在,当我尝试打开此选择时:
我使用cortexpower.de网站
我从Android Studio的Logcat中收到以下错误:
2019-12-16 15:55:16.338 32604-32627/com.example.newapp E/AwareLog: AtomicFileUtils: readFileLines file not exist: android.util.AtomicFile@b76c34c
2019-12-16 15:55:16.343 32604-32622/com.example.newapp E/MemoryLeakMonitorManager: MemoryLeakMonitor.jar is not exist!
2019-12-16 15:55:23.549 32604-32604/com.example.newapp A/chromium: [FATAL:jni_android.cc(249)] Please include Java exception stack in crash report
2019-12-16 15:55:23.550 32604-32604/com.example.newapp A/libc: Fatal signal 5 (SIGTRAP), code 1 (TRAP_BRKPT), fault addr 0x76b69143e8 in tid 32604 (.example.newapp), pid 32604 (.example.newapp)
在创建新应用时,我必须设置一个名称和网站。多数民众赞成在这个奇怪的链接在错误。我不知道这是否引起水灾。
感谢您的帮助!