Come ascoltare un WebView finendo di caricare un URL?


447

Ho un file WebViewche sta caricando una pagina da Internet. Voglio mostrare a ProgressBarfino al completamento del caricamento.

Come ascolto il completamento del caricamento della pagina di un WebView?


1
Per favore, considera di contrassegnare la mia risposta come corretta, in quanto risolve alcuni problemi che ian non ha.
neteinstein,

Penso che un modo migliore per chiamare il codice java nativo con js quando la pagina sia caricata. Fai riferimento a questa risposta, sebbene sia per iOS, ma l'idea si applica anche qui .
Kris Roofe,

Controlla la mia risposta qui sotto per la soluzione minima e concisa
Skynet

Risposte:


716

Estendi WebViewClient e chiama onPageFinished () come segue:

mWebView.setWebViewClient(new WebViewClient() {

   public void onPageFinished(WebView view, String url) {
        // do your stuff here
    }
});

Ho dei problemi con i caricamenti esterni quando Internet non è così veloce. Ad esempio Google Analytics o altre cose del genere. Ho provato alcune soluzioni alternative ed è migliorato molto, ma non è ancora perfetto. A volte l'app si blocca sulla schermata di caricamento ed è impossibile uscire, a meno che non si disconnetta la rete o ci si connette a un'altra buona. Non so ancora come risolverlo, ci sto provando.
Felipe,

1
Funziona perfettamente È possibile utilizzare mWebView.setVisibility (View.INVISIBLE) prima di caricare. Al termine del caricamento, ripristinarlo su View.VISIBLE. L'ho usato con questa schermata iniziale: android-developers.blogspot.de/2009/03/…
Johan Hoeksma,

39
Questa non è affatto una soluzione. Non è garantito che la pagina sia già caricata quando viene chiamato questo metodo.
Falco,

3
Questo è un cattivo design da parte di Google. Quasi sempre quando si completa questa azione, si desidera fare qualcosa orientato all'attività principale, non alla vista Web stessa. L'override di una funzione anziché l'iscrizione a un evento è un anti-pattern comune e motivo per cui non mi piace lo sviluppo Android.
Ryan,

6
Questo metodo non garantisce la finitura del carico e può essere chiamato più di una volta se il carico dell'URL richiede una navigazione dell'URL intermedia. Quindi questo viene chiamato più volte. Tuttavia è un modo per controllarlo.
principiante

151

@ian questo non è preciso al 100%. Se hai più iframe in una pagina, avrai più onPageFinished (e onPageStarted). E se hai diversi reindirizzamenti, potrebbe anche fallire. Questo approccio risolve (quasi) tutti i problemi:

boolean loadingFinished = true;
boolean redirect = false;

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;
            //HIDE LOADING IT HAS FINISHED
        } else {
            redirect = false; 
        }
    }
});

AGGIORNARE:

Secondo la documentazione: onPageStarted NON verrà chiamato quando il contenuto di un frame incorporato cambia, ovvero facendo clic su un collegamento la cui destinazione è un iframe.

Ho trovato un caso specifico come quello su Twitter in cui è stata chiamata solo una pagina finita e ha incasinato un po 'la logica. Per risolvere ciò, ho aggiunto un'attività pianificata per rimuovere il caricamento dopo X secondi. Questo non è necessario in tutti gli altri casi.

AGGIORNAMENTO 2 :

Ora con l'attuale implementazione di Android WebView:

boolean loadingFinished = true;
boolean redirect = false;

    mWebView.setWebViewClient(new WebViewClient() {

        @Override
        public boolean shouldOverrideUrlLoading(
                WebView view, WebResourceRequest request) {
            if (!loadingFinished) {
               redirect = true;
            }

            loadingFinished = false;
            webView.loadUrl(request.getUrl().toString());
            return true;
        }

        @Override
        public void onPageStarted(
                WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            loadingFinished = false;
            //SHOW LOADING IF IT ISNT ALREADY VISIBLE  
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            if (!redirect) {
               loadingFinished = true;
                //HIDE LOADING IT HAS FINISHED
            } else {
                redirect = false; 
            }
        }
    });

3
Probabilmente hai notato l'avvertenza nel documento di onPageStarted: onPageStarted NON verrà chiamato quando il contenuto di un frame incorporato cambia, ovvero facendo clic su un collegamento il cui target è un iframe. Quindi, ciò potrebbe distorcere la logica in quei casi. A proposito, la semplificazione di @ polen funziona davvero?
an00b,

1
Bella cattura, non ho mai notato la roba del telaio. Non ho provato il codice della polena ... l'unico che posso assicurare che il lavoro è quanto sopra che sto usando.
neteinstein,

3
Solo una correzione minore. In realtà è "void pubblico onPageStarted (visualizzazione WebView, URL stringa, favicon Bitmap)" anziché "void pubblico onPageStarted (vista WebView, URL stringa)"
MrMaffen,

Non funziona per alcuni dei siti più recenti che non finiscono mai di caricarsi ... ad es. "Agoda.com". Non ricevi mai la chiamata onPageFinished perché è un reindirizzamento.
Kenyee,

Ho visto su PageFinished essere chiamato due volte durante un reindirizzamento. Ma, quello che hai detto "Se hai diversi iframe in una pagina avrai più onPageFinished (e onPageStarted)" non è corretto come nella documentazione di onPageFinished: "Questo metodo è chiamato solo per il frame principale."
granato

40

Sono abbastanza parziale rispetto alla soluzione @NeTeInStEiN (e @polen) ma l'avrei implementata con un contatore invece di più booleani o osservatori di stato (solo un altro sapore ma pensavo potesse condividere). Ha una sfumatura di JS al riguardo, ma penso che la logica sia un po 'più facile da capire.

private void setupWebViewClient() {
    webView.setWebViewClient(new WebViewClient() {
        private int running = 0; // Could be public if you want a timer to check.

        @Override
        public boolean shouldOverrideUrlLoading(WebView webView, String urlNewString) {
            running++;
            webView.loadUrl(urlNewString);
            return true;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            running = Math.max(running, 1); // First request move it to 1.
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            if(--running == 0) { // just "running--;" if you add a timer.
                // TODO: finished... if you want to fire a method.
            }
        }
    });
}

2
Il tuo codice sembra buono. Ho provato lo stesso per la mia visualizzazione Web che carica da dati HTML non URL. Ma questo attiva onPageFinished se la prima visualizzazione Web viene caricata rapidamente e prima che la seconda inizi a caricarsi. Scenario normale. running = 1, running = 2, --running = 1, --running = 0. Scenario insolito che fallisce - in esecuzione = 1, --running = 0, in esecuzione = 1 in esecuzione = 0
Ajith Memana

1
C'è anche un altro scenario, quando un evento non viene generato per qualche motivo la parte TODO non sarà mai raggiunta. Quindi è necessario un timer per verificare i timeout. Oppure puoi chiamare una funzione java esportata in javascript quando sai che tutto è caricato correttamente. Qualcosa come documentReady () o qualcosa del genere.
Codebeat

perché non solo running = 1;in onPageStarted()?
Choletski,

@Choletski Perché il massimo di 1 e un numero maggiore di 1 non è 1.
Matteo Leggi il

25

Ho trovato anche una soluzione elegante, ma non l'ho testata rigorosamente:

public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if (m_webView.getProgress() == 100) {
                progressBar.setVisibility(View.GONE);
                m_webView.setVisibility(View.VISIBLE);
            }
        } 

2
L'ho testato e funziona perfettamente, puoi ovviamente chiamarlo dall'esterno del metodo onPageFinished e utilizzare un gestore per verificare a brevi intervalli - in alcuni casi, non vuoi estendere la classe WebViewClient.
Gal Rom,

1
Credo che questo potrebbe essere migliore della risposta accettata, avresti solo bisogno di controllare onError e sei pronto.
Evin1_10

1
Questa dovrebbe essere la risposta accettata.
زياد

1
Voto positivo per questo
Khdkls

23

Ho semplificato il codice di NeTeInStEiN in questo modo:

mWebView.setWebViewClient(new WebViewClient() {
        private int       webViewPreviousState;
        private final int PAGE_STARTED    = 0x1;
        private final int PAGE_REDIRECTED = 0x2;

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
            webViewPreviousState = PAGE_REDIRECTED;
            mWebView.loadUrl(urlNewString);
            return true;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            webViewPreviousState = PAGE_STARTED;
            if (dialog == null || !dialog.isShowing())
                dialog = ProgressDialog.show(WebViewActivity.this, "", getString(R.string.loadingMessege), true, true,
                        new OnCancelListener() {

                            @Override
                            public void onCancel(DialogInterface dialog) {
                                // do something
                            }
                        });
        }

        @Override
        public void onPageFinished(WebView view, String url) {

            if (webViewPreviousState == PAGE_STARTED) {
                dialog.dismiss();
                dialog = null;
            }

        }
 });

È facile da capire, OnPageFinished se il callback precedente è su OnPageStarted, quindi la pagina è completamente caricata.


3
@polen PAGE_STARTED non viene mai cancellato? Che cosa succede se OverrideUrlLoading () non viene mai chiamato?
an00b,

20

Se vuoi mostrare una barra di avanzamento devi ascoltare un evento di cambiamento di avanzamento, non solo per il completamento della pagina:

mWebView.setWebChromeClient(new WebChromeClient(){

            @Override
            public void onProgressChanged(WebView view, int newProgress) {

                //change your progress bar
            }


        });

A proposito, se si desidera visualizzare solo un ProgressBar indeterminato che sostituisce il metodo onPageFinished è sufficiente



5

È possibile tracciare il progresso Staus dal getProgress metodo nella WebView di classe.

Inizializza lo stato di avanzamento

private int mProgressStatus = 0;

quindi l'AsyncTask per il caricamento in questo modo:

private class Task_News_ArticleView extends AsyncTask<Void, Void, Void> {
    private final ProgressDialog dialog = new ProgressDialog(
            your_class.this);

    // can use UI thread here
    protected void onPreExecute() {
        this.dialog.setMessage("Loading...");
        this.dialog.setCancelable(false);
        this.dialog.show();
    }

    @Override
    protected Void doInBackground(Void... params) {
        try {
            while (mProgressStatus < 100) {
                mProgressStatus = webview.getProgress();

            }
        } catch (Exception e) {

        }
        return null;

    }

    protected void onPostExecute(Void result) {
        if (this.dialog.isShowing()) {
            this.dialog.dismiss();
        }
    }
}

mProgressStatus = webview.getProgress (); deve essere chiamato da un thread dell'interfaccia utente.
Skynet,

5

grazie per le risposte. Mi ha aiutato, ma ho dovuto migliorarlo un po 'per le mie esigenze. Ho avuto diverse date e finiture, quindi ho aggiunto un timer che controlla se al termine del pagefinish è stata avviata una nuova pagina. Ok, cattiva spiegazione. Vedi il codice :)

myWebView.setWebViewClient(new WebViewClient() {
        boolean loadingFinished = true;
        boolean redirect = false;

        long last_page_start;
        long now;

        // Load the url
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (!loadingFinished) {
                redirect = true;
            }

            loadingFinished = false;
            view.loadUrl(url);
            return false;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            Log.i("p","pagestart");
            loadingFinished = false;
            last_page_start = System.nanoTime();
            show_splash();
        }

        // When finish loading page
        public void onPageFinished(WebView view, String url) {
            Log.i("p","pagefinish");
            if(!redirect){
                loadingFinished = true;
            }
            //call remove_splash in 500 miSec
            if(loadingFinished && !redirect){
                now = System.nanoTime();
                new android.os.Handler().postDelayed(
                        new Runnable() {
                            public void run() {
                                remove_splash();
                            }
                        },
                        500);
            } else{
                redirect = false;
            }
        }
        private void show_splash() {
            if(myWebView.getVisibility() == View.VISIBLE) {
                myWebView.setVisibility(View.GONE);
                myWebView_splash.setVisibility(View.VISIBLE);
            }
        }
        //if a new "page start" was fired dont remove splash screen
        private void remove_splash() {
            if (last_page_start < now) {
                myWebView.setVisibility(View.VISIBLE);
                myWebView_splash.setVisibility(View.GONE);
            }
        }

});

2

Ecco un nuovo metodo per rilevare quando un URL è stato caricato utilizzando la funzionalità di Android per gli hook di JavaScript . Usando questo modello, sfruttiamo la conoscenza di JavaScript dello stato del documento per generare una chiamata di metodo nativa nel runtime di Android. Queste chiamate accessibili tramite JavaScript possono essere effettuate utilizzando il@JavaScriptInterface annotazione.

Questa implementazione richiede che chiamiamo setJavaScriptEnabled(true)le WebViewimpostazioni, quindi potrebbe non essere adatto seconda dei requisiti della tua applicazione, ad es.

src / io / github / cawfree / webviewcallback / MainActivity.java (Jelly Bean, API Level 16)

package io.github.cawfree.webviewcallback;

/**
 *  Created by Alex Thomas (@Cawfree), 30/03/2017.
 **/

import android.net.http.SslError;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.JavascriptInterface;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

/** An Activity demonstrating how to introduce a callback mechanism into Android's WebView. */
public class MainActivity extends AppCompatActivity {

    /* Static Declarations. */
    private static final String HOOK_JS             = "Android";
    private static final String URL_TEST            = "http://www.zonal.co.uk/";
    private static final String URL_PREPARE_WEBVIEW = "";

    /* Member Variables. */
    private WebView mWebView = null;

    /** Create the Activity. */
    @Override protected final void onCreate(final Bundle pSavedInstanceState) {
        // Initialize the parent definition.
        super.onCreate(pSavedInstanceState);
        // Set the Content View.
        this.setContentView(R.layout.activity_main);
        // Fetch the WebView.
        this.mWebView = (WebView)this.findViewById(R.id.webView);
        // Enable JavaScript.
        this.getWebView().getSettings().setJavaScriptEnabled(true);
        // Define the custom WebClient. (Here I'm just suppressing security errors, since older Android devices struggle with TLS.)
        this.getWebView().setWebViewClient(new WebViewClient() { @Override     public final void onReceivedSslError(final WebView pWebView, final SslErrorHandler pSslErrorHandler, final SslError pSslError) { pSslErrorHandler.proceed(); } });
        // Define the WebView JavaScript hook.
        this.getWebView().addJavascriptInterface(this, MainActivity.HOOK_JS);
        // Make this initial call to prepare JavaScript execution.
        this.getWebView().loadUrl(MainActivity.URL_PREPARE_WEBVIEW);
    }

    /** When the Activity is Resumed. */
    @Override protected final void onPostResume() {
        // Handle as usual.
        super.onPostResume();
        // Load the URL as usual.
        this.getWebView().loadUrl(MainActivity.URL_TEST);
        // Use JavaScript to embed a hook to Android's MainActivity. (The onExportPageLoaded() function implements the callback, whilst we add some tests for the state of the WebPage so as to infer when to export the event.)
        this.getWebView().loadUrl("javascript:" + "function onExportPageLoaded() { " + MainActivity.HOOK_JS + ".onPageLoaded(); }" + "if(document.readyState === 'complete') { onExportPageLoaded(); } else { window.addEventListener('onload', function () { onExportPageLoaded(); }, false); }");
    }

    /** Javascript-accessible callback for declaring when a page has loaded. */
    @JavascriptInterface @SuppressWarnings("unused") public final void onPageLoaded() {
        // Display the Message.
        Toast.makeText(this, "Page has loaded!", Toast.LENGTH_SHORT).show();
    }

    /* Getters. */
    public final WebView getWebView() {
        return this.mWebView;
    }

}

res / layout / activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<WebView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/webView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
/>

In sostanza, stiamo aggiungendo una funzione JavaScript aggiuntiva che viene utilizzata per testare lo stato del documento. Se è caricato, lanciamo un onPageLoaded()evento personalizzato in Android MainActivity; in caso contrario, registriamo un listener di eventi che aggiorna Android una volta che la pagina è pronta, utilizzandowindow.addEventListener('onload', ...); .

Poiché stiamo aggiungendo questo script dopo che this.getWebView().loadURL("")è stata effettuata la chiamata a , è probabile che non abbiamo bisogno di "ascoltare" per gli eventi, dato che abbiamo solo la possibilità di aggiungere l'hook JavaScript effettuando una chiamata successiva a loadURL, una volta che la pagina è già stata caricata.


Soluzione eccezionale, che generalmente funziona. Sto riscontrando problemi con https://reddit.com/r/Nature (con Reddit in generale), quando fai clic su un thread e il thread viene caricato, non riesco a catturare quell'evento. Mi puoi aiutare?
Primož Kralj,

@ PrimožKralj Sono contento di sapere che stai avendo qualche successo con questo ... Non sono sicuro di cosa suggerire in modo specifico, ma se ci sono eventi pubblici che sai che vengono attivati, puoi agganciarti, ad esempio quando il conteggio dei commenti viene aggiornato, è possibile utilizzarlo come fonte. Hai considerato che forse il tuo problema potrebbe essere risolto colpendo direttamente l' API di Reddit ?
Mapsy,

1
Grazie, darò un'altra occhiata agli eventi innescati e cercherò di collegarmi a uno di essi. Sono a conoscenza dell'API e cercherò di implementare una soluzione più solida utilizzandola in futuro. Grazie!
Primož Kralj,

1

Solo per mostrare la barra di avanzamento, sono sufficienti i metodi "onPageStarted" e "onPageFinished"; ma se si desidera avere un flag "is_loading" (insieme ai reindirizzamenti delle pagine, ...), questi metodi possono essere eseguiti con non-sequencing, come "onPageStarted> onPageStarted> onPageFinished> onPageFinished".

Ma con il mio breve test (testalo tu stesso), la coda dei valori del metodo "onProgressChanged" è "0-100> 0-100> 0-100> ..."

private boolean is_loading = false;

webView.setWebChromeClient(new MyWebChromeClient(context));

private final class MyWebChromeClient extends WebChromeClient{
    @Override
    public void onProgressChanged(WebView view, int newProgress) {
        if (newProgress == 0){
            is_loading = true;
        } else if (newProgress == 100){
            is_loading = false;
        }
        super.onProgressChanged(view, newProgress);
    }
}

Impostare anche " is_loading = false" alla chiusura dell'attività, se si tratta di una variabile statica perché l'attività può essere terminata prima del completamento della pagina.


0

Caricamento SwipeRefreshLayoutProgressBardell'URL con e :

UrlPageActivity.java:

    WebView webView;
    SwipeRefreshLayout _swipe_procesbar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_url_page);


        String url = "http://stackoverflow.com/";

        _swipe_procesbar = (SwipeRefreshLayout)findViewById(R.id.url_path_swipe_procesbar);

        _swipe_procesbar.post(new Runnable() {
                                  @Override
                                  public void run() {
                                      _swipe_procesbar.setRefreshing(true);
                                  }
                              }
        );

        webView = (WebView) findViewById(R.id.url_page_web_view);
        webView.getSettings().setJavaScriptEnabled(true);

        webView.setWebViewClient(new WebViewClient() {
            public void onPageFinished(WebView view, String url) {
                _swipe_procesbar.setRefreshing(false);
                _swipe_procesbar.setEnabled(false);
            }
        });
        webView.loadUrl(url);
    }

activity_url_page.xml:

<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/url_path_swipe_procesbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context="com.test.test1.UrlPageActivity">


            <WebView
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:id="@+id/url_page_web_view" />
        </RelativeLayout>

</android.support.v4.widget.SwipeRefreshLayout>

0

Ecco un metodo che consente di registrare un Runnableda eseguire una volta terminato il caricamento di un determinato indirizzo Web. Associamo ciascuno Runnablea un URL corrispondente Stringin a Mape utilizziamo il metodo di WebViews getOriginalUrl()per scegliere il callback appropriato.

package io.github.cawfree.webviewcallback;

/**
 *  Created by Alex Thomas (@Cawfree), 30/03/2017.
 **/

import android.net.http.SslError;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import java.util.HashMap;
import java.util.Map;

/** An Activity demonstrating how to introduce a callback mechanism into Android's WebView. */
public class MainActivity extends AppCompatActivity {

    /* Member Variables. */
    private WebView               mWebView;
    private Map<String, Runnable> mCallbackMap;

    /** Create the Activity. */
    @Override protected final void onCreate(final Bundle pSavedInstanceState) {
        // Initialize the parent definition.
        super.onCreate(pSavedInstanceState);
        // Set the Content View.
        this.setContentView(R.layout.activity_main);
        // Fetch the WebView.
        this.mWebView     = (WebView)this.findViewById(R.id.webView);
        this.mCallbackMap = new HashMap<>();
        // Define the custom WebClient. (Here I'm just suppressing security errors, since older Android devices struggle with TLS.)
        this.getWebView().setWebViewClient(new WebViewClient() {
            /** Handle when a request has been launched. */
            @Override public final void onPageFinished(final WebView pWebView, final String pUrl) {
                // Determine whether we're allowed to process the Runnable; if the page hadn't been redirected, or if we've finished redirection.
                if(pUrl.equals(pWebView.getOriginalUrl())) {
                    // Fetch the Runnable for the OriginalUrl.
                    final Runnable lRunnable = getCallbackMap().get(pWebView.getOriginalUrl());
                    // Is it valid?
                    if(lRunnable != null) { lRunnable.run(); }
                }
                // Handle as usual.
                super.onPageFinished(pWebView, pUrl);
            }
            /** Ensure we handle SSL state properly. */
            @Override public final void onReceivedSslError(final WebView pWebView, final SslErrorHandler pSslErrorHandler, final SslError pSslError) { pSslErrorHandler.proceed(); }
        });
        // Assert that we wish to visit Zonal's website.
        this.getWebView().loadUrl("http://www.zonal.co.uk/");
        // Align a Callback for Zonal; this will be serviced once the page has loaded.
        this.getCallbackMap().put("http://www.zonal.co.uk/", new Runnable() {     @Override public void run() { /* Do something. */ } });
    }

    /* Getters. */
    public final WebView getWebView() {
        return this.mWebView;
    }

    private final Map<String, Runnable> getCallbackMap() {
        return this.mCallbackMap;
    }

}

0

Il renderer non terminerà il rendering quando viene chiamato il metodo OnPageFinshed o l'avanzamento raggiunge il 100%, quindi entrambi i metodi non garantiscono che la vista sia stata completamente renderizzata.

Ma puoi capire dal metodo OnLoadResource cosa è già stato reso e cosa sta ancora eseguendo il rendering. E questo metodo viene chiamato più volte.

        @Override
        public void onLoadResource(WebView view, String url) {
            super.onLoadResource(view, url);
           // Log and see all the urls and know exactly what is being rendered and visible. If you wanna know when the entire page is completely rendered, find the last url from log and check it with if clause and implement your logic there.
            if (url.contains("assets/loginpage/img/ui/forms/")) {
                // loginpage is rendered and visible now.
               // your logic here.

            }
        }

0

Utilizzare questo dovrebbe aiutare ..var currentUrl = "google.com" var partOfUrl = currentUrl.substring (0, currentUrl.length-2)

webView.setWebViewClient (oggetto: WebViewClient () {

override fun onLoadResource(WebView view, String url) {
     //call loadUrl() method  here 
     // also check if url contains partOfUrl, if not load it differently.
     if(url.contains(partOfUrl, true)) {
         //it should work if you reach inside this if scope.
     } else if(!(currentUrl.startWith("w", true))) {
         webView.loadurl("www.$currentUrl")

     } else if(!(currentUrl.startWith("h", true))) {
         webView.loadurl("https://$currentUrl")

     } else { ...}


 }

override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler?, error: SslError?) {
   // you can call again loadUrl from here too if there is any error.
}

// Dovresti anche sostituire altri metodi di sostituzione per errori come onReceiveError per vedere come tutti questi metodi vengono chiamati uno dopo l'altro e come si comportano durante il debug con il punto di interruzione. } `


-1

per gli utenti di Kotlin:

webView.webViewClient = object : WebViewClient() {
            override fun onPageFinished(view: WebView?, url: String?) {
                // do your logic
            }
        }

ci sono molti metodi che è possibile ignorare

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.