2014-07-07 4 views
6

Voglio solo sapere quando viene caricata la pagina html. OnPageFinished viene chiamato prima che venga caricata tutta la pagina. Ho vista vuota quando ho impostato Vista da bitmap creato da WebViewonPageFinished sta sparando prima che venga caricata la pagina

 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(); 
      } 



     }); 

EDIT:

Ho cercato di implementare JavaScriptInterface per ora solo con fare un messaggio Toast, ma ancora non funziona. Ho incollato il codice HTML e Java:

EDIT:

ho finalmente capito di lavoro. Ho usato JavaScriptInterface con corretto. Quando loadUrl è avviato, viene caricato il file html. Quando tutta la pagina è disponibile sullo schermo, funzione onload dalla funzione html call captureImage dalla classe JavaScriptInterface. Ora ho la certezza che quella pagina sia completamente caricata e posso riprenderne un'immagine. Grazie per tutto l'aiuto.

CODICE:

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

Puoi approfondire ciò che stai cercando di fare? A quale livello di API stai mirando? L'HTML contiene iframe? ecc. Iniziando ~ API-12 le modifiche interne a WebView iniziarono a rompere cose come WebView.PictureListener ... –

risposta

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(); 
     } 
    }); 
} 
0

Usa WebViewClient e onPageFinished metodo come di seguito:

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; 
    } 

} 
}); 

Per ulteriori informazioni, fare riferimento a https://stackoverflow.com/a/5172952/685240

Spero che sia d'aiuto.

MODIFICA: Come per il tuo commento, penso che la tua pagina venga caricata correttamente ma ci vuole del tempo per renderizzare/disegnare la pagina sullo schermo, che è la causa del tuo problema. Prova con l'implementazione di onPictureListener per la visualizzazione web. Per ulteriori riferimenti, fare riferimento a https://stackoverflow.com/a/18123023/685240

+1

Tutto è ok quando carico la pagina web per esempio "https://www.google.com", ma quando voglio carica il file html statico memorizzato nelle risorse, onFinishedPage viene attivato prima che venga caricata tutta la pagina. C'è un modo per chiamare quella pagina? Forse da html? – dzakens

+0

Esiste la possibilità di utilizzare html per notificare che tutto il contenuto è stato caricato? – dzakens

+0

@dzakens controlla la mia risposta modificata. –

5

Questo perché onPageFinished significa che "la pagina ha completato il caricamento", non "la pagina è sullo schermo". Sfortunatamente la WebView non ha una API "la pagina che si desidera è ora sullo schermo". La gente di solito ricorre a una combinazione di PictureListener (che è stato deprecato dal momento che è inaffidabile) e timeout casuali (che sono molto lunghi o non funzionano su alcuni dispositivi).

Si potrebbe provare eseguendo il rendering su una piccola bitmap e controllando se è tutto bianco su ogni callback PictureListener (e ricorda di smettere di farlo quando hai finito di aspettare, altrimenti brucerai tonnellate di CPU se la pagina contiene animazioni/gif/etc ..). Il rendering su una piccola bitmap sarà ancora molto impegnativo per la CPU se la pagina ha grandi immagini, quindi questa non è sicuramente una grande soluzione.

0

È successo anche a me, che in WebViewClient, il callback suPageFinished si attiva prima dell'effettivo evento window.load.

Ancora indagando sul motivo per cui questo accade a volte, il che è difficile perché l'app per Android è prodotta da un generatore di app ibrido in-house altamente personalizzato.

Tuttavia, ho superato questo problema implementando una protezione che controlla se c'è un errore nello script che desidero chiamare suPageFinished, nel qual caso aggiungo un gestore di eventi che richiama il mio script durante la finestra .caricare.

È inoltre possibile utilizzare document.addEventListener ("DOMContentLoaded", ...) anziché window.load.

Di seguito è riportato uno snippet di codice che esemplifica questo, anche con le chiamate debug.log. Puoi passare la chiamata all'interfaccia javascript come argomento

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); 
     }