我正在制作一个Android Webview应用程序。而且我几乎做到了,它在Android 23或更高版本中无法正常运行。在网站上,有许多链接覆盖有图像等。在我测试过的Motorola-Lollipop(Android 21)中,一切正常。但是在模拟器(Nexus 5x-android 24)中,滚动正常,但链接无效。我的webview客户端代码如下:
public class CustomWebViewClient extends WebViewClient {
private boolean mSuccess = true;
private Map<String, String> reloadMap = new HashMap<>();
public CustomWebViewClient(){
}
public void addToReloadMap(String from, String to) {
reloadMap.put(from, to);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
progress_view.setVisibility(View.VISIBLE);
swipeRefreshLayout.setRefreshing(false); // TODO: called too often, find a better place
}
@Override
public void onPageFinished(final WebView view, final String url) {
progress_view.setVisibility(View.GONE);
if (url.contains(C.BRING_BACK_LOGIN) && PrefsUtil.getBringBack()) {
removeAllCookies();
PrefsUtil.setBringBack(false);
showLoginActivity();
}
if (reloadRound < 10) {
if (url.contains(C.WEBVIEW_FACEBOOK_URL)) {
if (PrefsUtil.get(FacebookProfile.class) != null) {
FacebookLoginService.INSTANCE.fbProfile().onNext(PrefsUtil.get(FacebookProfile.class));
}
removeAllCookies();
showLoginActivity();
}
if (PrefsUtil.getRegisterCheck() && !url.contains(C.FACEBOOK_REGISTER_URL) && !url.contains(C.CONTAINER_URL) && !url.contains(C.REGISTER_URL_THREE)
&& !url.contains(C.WEBVIEW_FACEBOOK_URL) && !url.contains(C.STANDARD_LOGIN_URL) && !PrefsUtil.isLoggedIn(PrefsUtil.getCity().name()) && !url.contains(C.REGISTER_URL_FOUR) && !url.contains(C.REGISTER_URL)) {
if (!url.contains(C.LOGIN_SUCCESS_URL)) {
removeAllCookies();
showLoginActivity();
} else {
UserLoginService.INSTANCE.getUserLoginUrlSubj().onNext(url);
Map<String, String> cookieMap = new HashMap<>();
cookieMap.put(C.USER_LOGGIN_KEY, C.USER_LOGGIN_VALUE);
PrefsUtil.saveUserCookies(cookieMap, PrefsUtil.getCity().name());
}
}
if (PrefsUtil.getCityChange() && !PrefsUtil.isLoggedIn(PrefsUtil.getCity().name())) {
showLoginActivity();
}
if (PrefsUtil.isLoggedIn(PrefsUtil.getCity().name()) && url.contains(C.LOGIN_URL)) {
PrefsUtil.setLastUrl(url);
}
runTaskCallback(new Runnable() {
public void run() {
if (mSuccess) {
showContent(3000);
}
if (reloadMap.containsKey(url) || url.contains(FB_API_KEY)) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
reloadPage();
}
}, 1800);
}
Log.i(TAG, "onPageFinished: " + url);
}
});
progress_view.setVisibility(View.GONE);
if (PrefsUtil.getFlag() && !PrefsUtil.getPermission()) {
startService(new Intent(MainActivity.this, PermissionDetectService.class));
}
}
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
if (failingUrl.contains("#")) {
Log.v("LOG", "failing url:"+ failingUrl);
final int sdkVersion = Integer.parseInt(Build.VERSION.SDK);
if (sdkVersion > Build.VERSION_CODES.GINGERBREAD) {
String[] temp;
temp = failingUrl.split("#");
view.loadUrl(temp[0]); // load page without internal link
try {
Thread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
view.loadUrl(failingUrl); // try again
} else {
view.loadUrl(failingUrl);
} }
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
runTaskCallback(new Runnable() {
@Override
public void run() {
mSuccess=false;
if (NetworkManager.isOnline(MainActivity.this)) {
webView.reload();
} else {
showOffline();
}
}
});
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
if (DownloadUtility.isDownloadableFile(url)) {
Toast.makeText(MainActivity.this, R.string.fragment_main_downloading, Toast.LENGTH_LONG).show();
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
if (!PrefsUtil.getDownloadUrl().equals(url)) {
PrefsUtil.saveDownloadUrl(url);
DownloadUtility.downloadFile(MainActivity.this, url, DownloadUtility.getFileName(url));
}
return true;
} else if (UrlUtil.isFBEvent(url)) {
try {
getPackageManager().getPackageInfo("com.facebook.katana", 0);
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(UrlUtil.getFBUrl(url))));
} catch (Exception e) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
Crashlytics.logException(e);
}
return true;
} else if (url != null && (url.startsWith("http://") || url.startsWith("https://"))) {
return true;
} else if (url != null && url.startsWith("mailto:")) {
MailTo mailTo = MailTo.parse(url);
startEmailActivity(mailTo.getTo(), mailTo.getSubject(), mailTo.getBody());
return true;
} else if (url != null && url.startsWith("tel:")) {
startCallActivity(url);
return true;
} else if (url != null && url.startsWith("sms:")) {
startSmsActivity(url);
return true;
} else if (url != null && url.startsWith("geo:")) {
startMapSearchActivity(url);
return true;
} else {
return false;
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public boolean onRenderProcessGone(WebView view, RenderProcessGoneDetail detail) {
if (!detail.didCrash()) {
Log.e("MY_APP_TAG", "System killed the WebView rendering process " +
"to reclaim memory. Recreating...");
if (webView != null) {
ViewGroup webViewContainer =
(ViewGroup) findViewById(R.id.fragment_main_webview);
webViewContainer.removeView(webView);
webView.destroy();
webView = null;
}
return true; // The app continues executing.
}
Log.e("MY_APP_TAG", "The WebView rendering process crashed!");
}
}
我的Web视图设置部分如下:
try {
WebView.setWebContentsDebuggingEnabled(true);
} catch (Exception ignored) {
Crashlytics.logException(ignored);
}
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setSupportZoom(true);
webView.getSettings().setAppCacheEnabled(true);
webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setDisplayZoomControls(false);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.getSettings().setPluginState(WebSettings.PluginState.ON);
webView.getSettings().setDefaultTextEncodingName("utf-8");
webView.setBackgroundColor(getResources().getColor(R.color.global_bg_front));
webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY); // fixes scrollbar on Froyo
webView.setWebViewClient(customWebViewClient);
webView.setWebChromeClient(new CustomWebChromeClient());
webView.setOnKeyListener(new CustomOnKeyListener());
webView.requestFocus(View.FOCUS_DOWN); // http://android24hours.blogspot.cz/2011/12/android-soft-keyboard-not-showing-on.html
webView.setOnTouchListener(new CustomOnTouchListener());
webView.setDownloadListener((url, userAgent, contentDisposition, mimetype, contentLength) -> {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
});
// webview hardware acceleration
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
App在Android 21 / Motorola中运行良好。我在寻找一些好的答案,但是没有合适的答案。我尝试了很多次。我该如何解决这个问题?