我只想知道何时加载html页面。在加载整个页面之前调用OnPageFinished。当我通过WebView创建的位图设置图像视图时,我得到了空白视图
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setAlwaysDrawnWithCacheEnabled(true);
mWebView.setWebViewClient(new WebViewClient(){
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon){
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view,String url){
Bitmap b = Bitmap.createBitmap( 480, 240, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
view.draw(c);
mImageView.setImageBitmap(b);
//b.recycle();
}
});
编辑:
我现在只尝试使用Toast消息来实现JavaScriptInterface,但它仍然无法正常工作。我已经粘贴了HTML代码和Java:
编辑:
我终于开始工作了。我正确地使用了JavaScriptInterface。当loadUrl启动时,正在加载html文件。当整个页面在屏幕上可用时,来自html文件的onload函数从JavaScriptInterface类调用captureImage函数。现在我确定页面已满载,我可以抓住它的图片。谢谢你的帮助。
代码:
JAVA:
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setDrawingCacheEnabled(true);
mWebView.addJavascriptInterface(new JavaScriptInterface(this), "Android");
mWebView.setWebViewClient(new WebViewClient(){});
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mWebView.loadUrl("file:///android_asset/html_sample.html");
//mWebView.loadUrl("https://www.onet.pl");
}
});
public class JavaScriptInterface {
private Context mContext;;
public JavaScriptInterface(Context context) {
mContext = context;
}
@JavascriptInterface
public void captureImage(){
Bitmap b = mWebView.getDrawingCache(true);
mImageView.setImageBitmap(b);
}
@JavascriptInterface
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
}
}
HTML:
<html>
<head>
<title>My first styled page</title>
<link rel="stylesheet" href="sample_css.css">
</head>
<body onload="function(){ Android.captureImage() }">
...
</body>
</html>
答案 0 :(得分:5)
这是因为onPageFinished
表示“页面已完成加载”,而不是“页面在屏幕上”。不幸的是,WebView没有“你想要的页面现在在屏幕上”的API。人们通常会使用PictureListener(由于它不可靠而被弃用)和随机超时(超长或在某些设备上不起作用)的组合。
您可以尝试渲染到一个小位图,并检查每个PictureListener
回调是否都是白色的(并且记得在等待完成后停止这样做,否则你将烧掉大量的CPU,如果页面有动画/ gifs / etc ..)。如果页面有大图像,渲染到小位图仍然会占用大量CPU资源,所以这绝对不是一个很好的解决方案。
答案 1 :(得分:1)
找到了一种简单的技术来加载页面,即使在调用onPageFinished之后, 递归调用loadUrl方法,直到页面未成功加载。 @Override public void onPageFinished(WebView view,String url){ // progressDialog.hide();
Log.e("onPageFinished","onPageFinished");
if (view.getContentHeight() == 0){
pbar.setVisibility(View.VISIBLE);
webView.loadUrl("https://drive.google.com/viewerng/viewer?embedded=true&url="+pdf);
}
else {
pbar.setVisibility(View.GONE);
}
}
答案 2 :(得分:0)
try this :-
OnClickListener btnGoListener = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
webView00.loadUrl(etUrl.getText().toString());
webView00.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
Toast.makeText(getBaseContext(), "Loading Finished 2", Toast.LENGTH_LONG)
.show();
}
});
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_web_page00);
webView00 = (WebView) findViewById(R.id.webView00);
btnGo = (Button) findViewById(R.id.go_btn);
etUrl = (EditText) findViewById(R.id.url_edittext);
webView00.getSettings().setJavaScriptEnabled(true);
btnGo.setOnClickListener(btnGoListener);
webView00.loadUrl("http://google.com");
//webView00.setWebViewClient(new myWebViewClient());
//webView00.setWebChromeClient(new myWebChromeClient());
webView00.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
Toast.makeText(getBaseContext(), "Loading Finished 1", Toast.LENGTH_LONG)
.show();
}
});
}
答案 3 :(得分:0)
使用WebViewClient
和onPageFinished
方法,如下所示:
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
if (!loadingFinished) {
redirect = true;
}
loadingFinished = false;
webView.loadUrl(urlNewString);
return true;
}
@Override
public void onPageStarted(WebView view, String url) {
loadingFinished = false;
//SHOW LOADING IF IT ISNT ALREADY VISIBLE
}
@Override
public void onPageFinished(WebView view, String url) {
if(!redirect){
loadingFinished = true;
}
if(loadingFinished && !redirect){
Bitmap b = Bitmap.createBitmap( 480, 240, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
view.draw(c);
mImageView.setImageBitmap(b);
} else{
redirect = false;
}
}
});
有关更多信息,请参阅https://stackoverflow.com/a/5172952/685240
希望它有所帮助。
编辑:根据您的评论,我认为您的网页已成功加载,但在屏幕上呈现/绘制网页需要时间,这是导致问题的原因。尝试为webview实施onPictureListener
。有关更多参考,请参阅https://stackoverflow.com/a/18123023/685240
答案 4 :(得分:0)
在我看来,在WebViewClient中,回调onPageFinished在实际的window.load事件之前启动。
仍然在研究为什么会发生这种情况,这很难,因为Android应用程序是由一个高度定制的内部混合应用程序生成器生成的。
尽管如此,我已经通过实施一个安全措施来解决这个问题,该安全措施检查脚本中是否存在我想在onPageFinished中调用的错误,在这种情况下,我添加了一个事件处理程序,在此期间再次调用我的脚本window.load。
您也可以使用document.addEventListener(&#34; DOMContentLoaded&#34;,...)代替window.load。
下面是一个代码片段,通过debug.log调用来举例说明这一点。您可以将调用作为参数传递给您的javascript界面
private void executeOnLoad(final WebView view, final String jsStringToExecute) {
StringBuilder sb = new StringBuilder("javascript:");
sb.append("try {console.log('native.onPageFinished. document.readyState: ' + document.readyState);").append(jsStringToExecute).append("} catch(err){console.log('error calling jsBridge script on page load, deferring call to window.load event');")
.append("window.addEventListener('load', function() {console.log('window.onload callled from native. document.readyState: ' + document.readyState);").append(jsStringToExecute).append("});").append("}");
String jsWithWindowLoadedFallback = sb.toString();
view.loadUrl(jsWithWindowLoadedFallback);
}