在少数地方可以处理此问题。
- 您可以使用
evaluateJavascript
代替loadUrl
(API级别19)并传递回调,在该回调中将Webview设置为可见。 - 您可以使用注册自己的javascript接口,
addJavascriptInterface
并在脚本结尾处调用它 - 您可以设置
WebChromeClient
并覆盖,onJsalert
然后在脚本中使用特定消息引发警报。 - 更新 :此外,这可以通过拦截“ css”请求之一,并在加载的文件中附加所需的内容来实现。这将使您可以在之前插入样式
onPageFinished
。检查此线程。
在以下示例中,我结合了所有方法:
package com.j2ko.webviewapp; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.base64; import android.util.Log; import android.view.View; import android.webkit.JavascriptInterface; import android.webkit.JsResult; import android.webkit.ValueCallback; import android.webkit.WebChromeClient; import android.webkit.WebView; import android.webkit.WebViewClient; import java.io.InputStream; import java.io.StringReader; import java.io.StringWriter; public class MainActivity extends AppCompatActivity { private static final String MAIN_FUNC_FMT = "(function() { %s })()"; private static final String FUNC_BODY_FMT = "var parent = document.loadedgetElementsByTagName('head').item(0);" + "var css = document.createElement('style');" + "css.type = 'text/css';" + "css.innerHTML = %s;" + "parent.appendChild(css);"; private static final String base64_DECODE_FMT = "window.atob('%s')"; WebView mWebView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mWebView = (WebView) findViewById(R.id.webview); mWebView.getSettings().setJavascriptEnabled(true); mWebView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); //Change it to whatever injectWithevaluateAndInterface(view); } @Override public void onLoadResource(WebView view, String url) { super.onLoadResource(view, url); } }); mWebView.setVisibility(View.INVISIBLE); mWebView.loadUrl("http://wiki.org"); } private static class CSSInjectBuilder { private final String mOrigin; private String mAtEnd = null; private boolean mUsebase64 = false; public CSSInjectBuilder(String css) { mOrigin = css; } public CSSInjectBuilder withbase64() { mUsebase64 = true; return this; } public CSSInjectBuilder withexpressionAtEnd(String expression){ mAtEnd = expression; return this; } String build() { String func_body = FUNC_BODY_FMT; if (mAtEnd != null) { func_body += mAtEnd; } final String css; if (mUsebase64) { byte[] buffer = mOrigin.getBytes(); css = String.format(base64_DECODE_FMT, base64.enpreToString(buffer, base64.NO_WRAP)); } else { css = "'" + mOrigin + "'"; } func_body = String.format(func_body, css); return String.format(MAIN_FUNC_FMT, func_body); } } byte[] loadAsset() { try { InputStream inputStream = getAssets().open("style.css"); byte[] buffer = new byte[inputStream.available()]; inputStream.read(buffer); inputStream.close(); return buffer; } catch (Exception e) { } return null; } String loadCSS() { return new String(loadAsset()); } void injectWithevaluate(final WebView view) { view.evaluateJavascript(new CSSInjectBuilder(loadCSS()).withbase64().build(), new ValueCallback<String>() { @Override public void onReceivevalue(String value) { view.setVisibility(View.VISIBLE); } }); } void injectWithevaluateAndInterface(WebView view) { view.addJavascriptInterface(new WebViewInterface(), "WebViewBackEnd"); final String injector = new CSSInjectBuilder(loadCSS()) .withbase64() .withexpressionAtEnd("window.WebViewBackEnd.CSSInjectionComplete();") .build(); view.evaluateJavascript(injector, null); } void injectWithLoadUrlSimple(WebView view) { view.loadUrl("javascript:" + loadCSS()); view.setVisibility(View.VISIBLE); } void injectWithLoadUrlAndCheckalert(final WebView view) { view.setWebChromeClient(new WebChromeClient() { @Override public boolean onJsalert(WebView view, String url, String message, JsResult result) { if (message.equals("CSSInjectionComplete")) { view.setVisibility(View.VISIBLE); return true; } return super.onJsalert(view, url, message, result); } }); //alert could hang aplying scripts so put it on timeout final String injector = new CSSInjectBuilder(loadCSS()) .withbase64() .withexpressionAtEnd("setTimeout(function(){alert('CSSInjectionComplete');}, 1);") .build(); view.loadUrl("javascript:" + injector); } private class WebViewInterface { @JavascriptInterface public void CSSInjectionComplete(){ mWebView.post(new Runnable() { @Override public void run() { mWebView.setVisibility(View.VISIBLE); } }); } } }


