我仅在将CSS文件注入HTML后才尝试显示Web视图。我试图将其放在onPageCommitVisible函数上,但它仅在以上23个api和d上有效。有人知道只有在CSS加载完成后才能显示webview吗?现在它“跳了起来”,在替换新CSS之前,我看到了第一秒钟的原始CSS。
@Override
public void onPageFinished(WebView view, String url) {
Utils.logDebug(this, "Page finished");
if (android.os.Build.VERSION.SDK_INT < 23) {
injectCSS(view);
}
super.onPageFinished(view, url);
showWebView(true);
onPageChange();
}
这是我的InjestCSS函数:
private void injectCSS(WebView webView) {
try {
webView.loadUrl("javascript:(function() {" +
"var css = document.createElement(\"style\");\n" +
"css.type = \"text/css\";\n" +
"css.innerHTML = \"" + readFileAsString() + "\";\n" +
"document.body.appendChild(css);" +
"})()");
} catch (Exception e) {
e.printStackTrace();
}
}
如您在函数中所见,此函数将CSS代码注入HTML。
在少数地方可以处理此问题。
evaluateJavaScript
代替loadUrl
(API级别19)并传递回调,在该回调中将Webview设置为可见。addJavaScriptInterface
并在脚本结尾处调用它WebChromeClient
并覆盖,onJsAlert
然后在脚本中使用特定消息引发警报。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.encodeToString(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);
}
});
}
}
}
问题内容: 我想检查活动是否正在运行或完成。有什么方法可以检查活动状态? 我找到了,但是我不确定。 问题答案: 如果您想执行任何步骤,将变得不可见。 他们是这里的几种选择。 onDestroy() -进行最终清理。 isFinishing() - 调用后立即返回true。 onStop() -当被框架进程终止时。(未销毁) onPause() -当被其他覆盖 onBackPressed() -捕获
问题内容: 我有一个名为的方法的对象,该方法启动三个线程。 每个线程执行完毕后,如何获得通知? 有没有办法知道一个(或全部)线程是否已完成或仍在执行? 问题答案: 你可以通过多种方式执行此操作: 在主线程中使用以阻塞方式等待每个线程完成,或者 以轮询方式(通常不鼓励使用)检查,等待每个线程完成,或者 非常规的,对于每个有问题的线程,调用来调用对象中的方法,并对每个线程进行编程以在完成时抛出未捕获的
在角度分量的顶部有以下初始化。 在我的组件中的某个地方,我使用选择器对Ngrx存储进行以下调用,以获取可观测数据。所有这些都很好,我得到了我想要的数据。 我需要知道这个可观察的什么时候完成。我需要设置一个布尔值,当所有可观察到的数据都试图完成时,它将关闭加载指示器。这是通过Web服务完成的。 因为可观测的源来自其他地方,所以我无法挂起“完整”回调
问题内容: 我有一个带有行的表格样式页面。每行都有一个复选框。我可以选中所有/很多复选框,然后单击“提交”,这是对每一行的Jquery ajax调用。 基本上,我为每一行都有一个表单,并且遍历所有选中的行并提交执行jquery ajax调用的表单。 所以我有一个按钮,它可以: 那么每一行都有: 该表格提交给processRow: 我想知道的是,通过这种方法,我可以判断出我所有的Ajax调用是否均已
问题内容: 我有一个 可编辑的 JComboBox,无论何时通过键入或选择更改文本,我都想在其中进行一些操作。在这种情况下,文本是一个模式,我想验证该模式是否有效,并显示导致某些测试数据匹配的内容。 完成显而易见的操作后,附加一个ActionHandler,我发现,对于键入而言,该事件充其量似乎是不可靠的(选择很好)。而当它 做 火打字的结果,文字检索(使用getEditor()。getItem(
问题内容: 我想知道我是否在通话。 如果我正在通话,请启动服务(服务部分已清除)。我该怎么做呢? 参加通话时,我需要致电服务中心…我不知道该怎么做?有什么帮助吗? 问题答案: 您需要广播接收器… 在清单中声明广播接收器… 还声明使用权限… 广播接收器类… 还有一类可自定义电话状态侦听器…