Bagaimana cara mendengarkan penyelesaian WebView memuat URL?

447

Saya punya WebViewyang memuat halaman dari Internet. Saya ingin menunjukkan ProgressBarsampai pemuatan selesai.

Bagaimana cara saya mendengarkan penyelesaian pemuatan halaman a WebView?

Janusz
sumber
1
Tolong pertimbangkan menandai jawaban saya sebagai benar, karena itu memecahkan beberapa masalah yang ian tidak.
neteinstein
Saya pikir cara yang lebih baik untuk memanggil kode java asli dengan js ketika halaman dimuat. Rujuk jawaban ini, meskipun ini untuk ios, tetapi gagasan itu juga berlaku di sini .
Kris Roofe
Periksa jawaban saya di bawah ini untuk solusi minimal dan ringkas
Skynet

Jawaban:

716

Perluas WebViewClient dan panggil onPageFinished () sebagai berikut:

mWebView.setWebViewClient(new WebViewClient() {

   public void onPageFinished(WebView view, String url) {
        // do your stuff here
    }
});
ian
sumber
Saya memiliki beberapa masalah dengan pemuatan eksternal ketika Internet tidak begitu cepat. Misalnya Google Analytics atau barang lain seperti itu. Saya mencoba beberapa solusi dan sudah banyak membaik, tetapi belum sempurna. Kadang-kadang aplikasi membeku di layar memuat dan tidak mungkin untuk keluar, kecuali jika Anda memutuskan jaringan atau menghubungkan yang lain dengan baik. Saya belum tahu bagaimana menyelesaikannya, saya sedang mencoba.
Felipe
1
Bekerja dengan sempurna. Anda dapat menggunakan mWebView.setVisibility (View.INVISIBLE) sebelum memuat. Saat memuat selesai atur kembali ke View.VISIBLE. Saya menggunakannya dengan layar splash ini: android-developers.blogspot.de/2009/03/…
Johan Hoeksma
39
Ini bukan solusi sama sekali. Tidak ada jaminan halaman sudah dimuat saat metode ini dipanggil.
Elang
3
Ini adalah desain yang buruk di pihak Google. Hampir sepanjang waktu ketika tindakan ini selesai Anda ingin melakukan sesuatu yang berorientasi di sekitar Aktivitas induk, bukan tampilan web itu sendiri. Mengganti fungsi alih-alih berlangganan acara adalah anti-pola umum dan alasan saya tidak suka pengembangan android.
Ryan
6
Metode ini tidak menjamin selesai beban dan dapat dipanggil lebih dari sekali jika beban url mengambil beberapa navigasi url menengah. Jadi ini dipanggil beberapa kali. Namun itu cara untuk memeriksanya.
pemula
150

@ apakah ini tidak 100% akurat. Jika Anda memiliki beberapa iframe di halaman, Anda akan memiliki beberapa onPageFinished (dan onPageStarted). Dan jika Anda memiliki beberapa pengalihan, mungkin juga gagal. Pendekatan ini memecahkan (hampir) semua masalah:

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

MEMPERBARUI:

Menurut dokumentasi: onPageStarted TIDAK akan dipanggil ketika konten bingkai yang disematkan berubah, yaitu mengklik tautan yang targetnya adalah iframe.

Saya menemukan kasus khusus seperti itu di Twitter di mana hanya halamanFinished dipanggil dan mengacaukan logikanya sedikit. Untuk mengatasi itu saya menambahkan tugas yang dijadwalkan untuk menghapus pemuatan setelah X detik. Ini tidak diperlukan dalam semua kasus lainnya.

PEMBARUAN 2 :

Sekarang dengan implementasi Android WebView saat ini:

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; 
            }
        }
    });
neteinstein
sumber
3
Anda mungkin telah memperhatikan peringatan di dokumen onPageStarted: onPageStarted TIDAK akan dipanggil ketika konten dari bingkai yang disematkan berubah, yaitu mengklik tautan yang targetnya adalah iframe. Jadi ini mungkin condong logika dalam kasus-kasus itu. BTW, apakah penyederhanaan @ polen benar-benar berfungsi?
an00b
1
Tangkapan yang bagus, tidak pernah memperhatikan bingkai. Saya belum mencoba kode polen .. satu-satunya yang saya dapat memastikan bahwa pekerjaan itu di atas yang saya gunakan.
neteinstein
3
Hanya koreksi kecil. Ini sebenarnya "public void onPageStarted (tampilan WebView, String url, Bitmap favicon)" alih-alih "public void onPageStarted (tampilan WebView, String url)"
MrMaffen
Tidak berfungsi untuk beberapa situs baru yang tidak pernah selesai memuat ... misalnya, "agoda.com". Anda tidak pernah mendapatkan panggilan onPageFinished karena ini merupakan pengalihan.
kenyee
Saya telah melihat onPageFinished dipanggil dua kali selama redirect. Tapi, apa yang Anda katakan "Jika Anda memiliki beberapa iframe di halaman, Anda akan memiliki beberapa onPageFinished (dan onPageStarted)" tidak benar sesuai dengan dokumentasi onPageFinished: "Metode ini hanya dipanggil untuk bingkai utama."
garnet
40

Saya cukup menyukai solusi @NeTeInStEiN (dan @polen) tetapi akan menerapkannya dengan counter, bukan boolean atau pengamat negara (hanya rasa lain tapi saya pikir mungkin akan berbagi). Memang ada nuansa JS tentang hal itu tetapi saya merasa logikanya sedikit lebih mudah dimengerti.

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.
            }
        }
    });
}
SciSpear
sumber
2
Kode Anda terlihat bagus. Saya telah mencoba hal yang sama untuk tampilan web saya yang memuat dari data html bukan url. Tapi yang satu ini memicu onPageFinished jika tampilan web pertama dimuat dengan cepat dan sebelum yang kedua mulai memuat. Skenario normal. running = 1, running = 2, --running = 1, --running = 0. Skenario yang tidak biasa yang gagal - running = 1, --running = 0, running = 1 running = 0
Ajith Memana
1
Ada juga skenario lain, ketika suatu peristiwa tidak dipecat karena alasan tertentu bagian TODO tidak akan pernah tercapai. Jadi, Anda perlu timer untuk memeriksa timeout. Atau Anda dapat memanggil fungsi java yang diekspor dalam javascript ketika Anda tahu semuanya dimuat dengan benar. Sesuatu seperti documentReady () atau sesuatu seperti itu.
Codebeat
mengapa tidak hanya running = 1;di onPageStarted()?
Choletski
@Choletski Karena maksimal 1 dan angka yang lebih besar dari 1 bukan 1.
Matius Baca
25

Saya menemukan satu solusi elegan juga, belum mengujinya dengan ketat:

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);
            }
        } 
Skynet
sumber
2
Saya telah mengujinya dan berfungsi dengan baik, Anda tentu saja dapat memanggilnya dari luar metode onPageFinished dan menggunakan Handler untuk memeriksa dalam interval pendek - dalam kasus-kasus, Anda tidak ingin memperluas kelas WebViewClient.
Gal Rom
1
Saya percaya ini mungkin lebih baik daripada jawaban yang diterima, Anda hanya perlu memeriksa onError dan Anda sudah siap.
Evin1_
1
Ini harus menjadi jawaban yang diterima.
زياد
1
Suara positif
23

Saya telah menyederhanakan kode NeTeInStEiN menjadi seperti ini:

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

        }
 });

Sangat mudah dimengerti, OnPageFinished jika panggilan balik sebelumnya pada onPageStarted, sehingga halaman benar-benar dimuat.

polen
sumber
3
@polen PAGE_STARTED tidak pernah dihapus? Bagaimana jika shouldOverrideUrlLoading () tidak pernah dipanggil?
an00b
20

Jika Anda ingin menampilkan bilah kemajuan, Anda perlu mendengarkan acara perubahan kemajuan, tidak hanya untuk penyelesaian halaman:

mWebView.setWebChromeClient(new WebChromeClient(){

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

                //change your progress bar
            }


        });

BTW jika Anda ingin menampilkan ProgressBar tak tentu hanya menimpa metode onPageFinished cukup

Francesco Laurita
sumber
5

Anda dapat melacak Progress Staus dengan metode getProgress di kelas tampilan web .

Inisialisasi status kemajuan

private int mProgressStatus = 0;

maka AsyncTask untuk memuat seperti ini:

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();
        }
    }
}
Praveen
sumber
mProgressStatus = webview.getProgress (); perlu dipanggil dari utas UI.
Skynet
5

terima kasih atas jawabannya. Itu membantu saya, tetapi saya harus memperbaikinya sedikit untuk kebutuhan saya. Saya punya beberapa pagestart dan selesai jadi saya menambahkan timer yang memeriksa apakah atfer pagefinish memulai pagestart baru. Oke, penjelasan yang buruk. Lihat kodenya :)

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

});
EscapeNetscape
sumber
2

Berikut adalah metode baru untuk dideteksi ketika URL telah dimuat dengan memanfaatkan kemampuan Android untuk kait JavaScript . Dengan menggunakan pola ini, kami mengeksploitasi pengetahuan JavaScript tentang status dokumen untuk menghasilkan pemanggilan metode asli dalam runtime Android. Panggilan yang dapat diakses JavaScript ini dapat dibuat menggunakan @JavaScriptInterfaceanotasi.

Implementasi ini mengharuskan kita sebut setJavaScriptEnabled(true)pada WebViewpengaturan 's, sehingga mungkin tidak cocok tergantung pada kebutuhan aplikasi Anda, misalnya masalah keamanan.

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"
/>

Pada dasarnya, kami menambahkan fungsi JavaScript tambahan yang digunakan untuk menguji keadaan dokumen. Jika dimuat, kami meluncurkan onPageLoaded()acara khusus di Android MainActivity; jika tidak, kami mendaftarkan pendengar acara yang memperbarui Android setelah halaman siap, menggunakan window.addEventListener('onload', ...);.

Karena kami akan menambahkan skrip ini setelah panggilan this.getWebView().loadURL("")dibuat, besar kemungkinan kami tidak perlu 'mendengarkan' acara sama sekali, karena kami hanya mendapatkan kesempatan untuk menambahkan kait JavaScript dengan melakukan panggilan berturut-turut ke loadURL, setelah halaman telah dimuat.

Mapsy
sumber
Solusi luar biasa, yang umumnya berfungsi. Saya mengalami masalah dengan https://reddit.com/r/Nature (dengan Reddit umumnya), ketika Anda mengklik beberapa utas dan utas dimuat, saya tidak dapat mengetahui acara itu. Bisakah Anda membantu saya?
Primož Kralj
@ PrimožKralj Senang mendengar Anda mengalami beberapa keberhasilan dengan ini ... Saya tidak yakin apa untuk menyarankan khusus, tetapi jika ada jenis acara publik yang Anda tahu dipicu bahwa Anda dapat menghubungkan ke dalam, misalnya ketika jumlah komentar diperbarui, Anda dapat menggunakannya sebagai sumber. Sudahkah Anda mempertimbangkan bahwa mungkin masalah Anda dapat diperbaiki dengan menekan API Reddit secara langsung?
Mapsy
1
Terima kasih, saya akan melihat lagi peristiwa yang dipicu dan mencoba untuk terhubung ke salah satu dari mereka. Saya mengetahui API, dan akan mencoba menerapkan solusi yang lebih kuat menggunakannya di masa depan. Terima kasih!
Primož Kralj
1

Hanya untuk memperlihatkan progress bar, metode "onPageStarted" dan "onPageFinished" sudah cukup; tetapi jika Anda ingin memiliki bendera "is_loading" (bersama dengan pengalihan halaman, ...), metode ini dapat dijalankan dengan non-sequencing, seperti "onPageStarted> onPageStarted> onPageFinished> onPageFinished" antrian.

Tetapi dengan tes singkat saya (tes sendiri.), Antrian nilai metode "onProgressChanged" adalah "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);
    }
}

Juga setel " is_loading = false" pada aktivitas tutup, jika itu adalah variabel statis karena aktivitas dapat diselesaikan sebelum halaman selesai.

Jalil Hamdollahi Oskouei
sumber
0

Memuat url dengan SwipeRefreshLayoutdan ProgressBar:

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>
Hamid
sumber
0

Berikut adalah metode yang memungkinkan Anda untuk mendaftar Runnableuntuk dieksekusi setelah alamat web tertentu selesai dimuat. Kita kaitkan masing-masing Runnabledengan URL yang sesuai Stringdalam Map, dan kami menggunakan WebView's getOriginalUrl()metode untuk memilih callback yang sesuai.

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

}
Mapsy
sumber
0

Perender tidak akan menyelesaikan rendering ketika metode OnPageFinshed dipanggil atau progresnya mencapai 100% sehingga kedua metode tidak menjamin Anda bahwa tampilan telah sepenuhnya di-render.

Tapi Anda bisa mencari tahu dari metode OnLoadResource apa yang telah dirender dan apa yang masih render. Dan metode ini dipanggil beberapa kali.

        @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.

            }
        }
shreedhar
sumber
0

Gunakan ini untuk membantu.`var currentUrl = "google.com" var partOfUrl = currentUrl.substring (0, currentUrl.length-2)

webView.setWebViewClient (objek: 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.
}

// Anda juga harus mengganti metode override lain untuk kesalahan seperti onReceiveError untuk melihat bagaimana semua metode ini disebut satu demi satu dan bagaimana mereka berperilaku saat debugging dengan break point. } `

Some one
sumber
-1

untuk pengguna Kotlin:

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

ada banyak metode yang bisa Anda timpa

Amin Keshavarzian
sumber