我有一个WebView,它从服务器加载一个html页面,但该页面在WebView上是不可见的。 html正确加载(我使用chrome调试//检查和html,包括所有javascripts存在),但它在手机屏幕上是不可见的。 当这个bug出现时,我的代码没有变化。当我在手机上安装Android System WebView更新时出现错误。 如果我卸载更新,则一切正常。 另外,我检查了WebViewClient的回调,并注意到没有调用onPageCommitVisible。所以不知何故,页面没有正确加载。只有当我按下Back按钮退出WebView时,我才会看到为我的网页调用onPageCommitVisible(buat它没有帮助,因为后退按钮存在WebView,正如预期的那样)。
以下是我的webview代码:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout rlMain = new RelativeLayout(getActivity());
rlMain.setContentDescription(Constants.STARTAPP_AD_MAIN_LAYOUT_CONTENT_DESCRIPTION);
rlMain.setId(Constants.MAIN_LAYOUT_ID);
getActivity().setContentView(rlMain);
// Create WebView and set its parameters
try{
webView = new WebView(getActivity().getApplicationContext());
webView.setBackgroundColor(0xFF000000);
getActivity().getWindow().getDecorView().findViewById(android.R.id.content).setBackgroundColor(0x00777777);
webView.setVerticalScrollBarEnabled(false);
webView.setHorizontalScrollBarEnabled(false);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient());
// set software acceleration
if (softwareAcceleration) {
ApiUtil.setWebViewLayerTypeSoftware(webView, null);
}
webView.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return true;
}
});
webView.setLongClickable(false);
webView.addJavascriptInterface(createJsInterface(), Constants.INTERFACE);
setWebViewSpecificParameters(webView);
webView.loadDataWithBaseURL("http://www.xxxxxx.com", getHtml(), "text/html", "utf-8", null);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
webView.setWebViewClient(new MyWebViewClient());
RelativeLayout.LayoutParams webviewPrms = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT
);
rlMain.addView(webView, webviewPrms);
}
public void setWebViewSpecificParameters(final WebView webView) {
webView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
return (event.getAction() == MotionEvent.ACTION_MOVE);
}
});
}
private class MyWebViewClient extends WebViewClient {
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
Logger.log(TAG, Log.DEBUG, "!!!!!shouldInterceptRequest" );
return super.shouldInterceptRequest(view, url);
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
Logger.log(TAG, Log.DEBUG, "!!!!!shouldInterceptRequest" );
return super.shouldInterceptRequest(view, request);
}
@Override
public void onPageFinished(WebView view, String url) {
setWebViewBackground(view);
runJavascript(Constants.JAVASCRIPT_SET_MODE_SERVER, getPosition());
runJavascript(Constants.JAVASCRIPT_ENABLE_SCHEME, "externalLinks");
InterstitialMode.this.onWebviewPageFinished();
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return clicked(url);
}
}
答案 0 :(得分:1)
在基于用户输入从一个网站导航到另一个网站的应用中,很有可能(> 50%)第二个网站在调用WebView.loadUrl
之后根本不会显示,并且前一个网站仍然可见-它甚至是交互式的,即滚动作品。通常在再次调用WebView.loadUrl
之后即可解决该问题。除了用户没有看到第二个网站以外,没有明显的迹象表明发生了该错误。依靠用户手动重新加载页面并不是令人满意的解决方案,因为该错误经常发生。
我能够通过使用自定义WebViewClient
来检测第二个网站未正确加载并触发重新加载来解决此问题:
setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
buggyWebViewHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (!wasCommitCalled) {
loadUrl(url);
}
}
}, 2500);
}
}
@Override
public void onPageCommitVisible(WebView view, String url) {
wasCommitCalled = true;
}
});
其中buggyWebViewHandler
是处理程序或任何其他允许将一段代码延迟一段时间的类。此外,每当调用wasCommitCalled = false;
时,您都需要设置WebView.loadUrl
-例如,通过重写方法。
请注意,这仅适用于Android 23及更高版本,因为这是在添加onPageCommitVisible
时开始的。完整的实现请参见此处:https://github.com/TomTasche/OpenDocument.droid/blob/8c2eec5c57e5962e9ac4c46549be2241b259eb32/app/src/main/java/at/tomtasche/reader/ui/widget/PageView.java#L72-L96
如果有人有足够的勇气更深入地了解发生这种情况的原因:在调试时,似乎每当此错误发生时就不会调用onPageStarted。也许有帮助...