URL로드가 완료된 WebView를 수신하는 방법은 무엇입니까?


447

나는이 WebView인터넷에서 페이지를로드된다. ProgressBar로딩이 완료 될 때까지 표시하고 싶습니다 .

페이지로드가 완료된 것을 수신하려면 어떻게합니까 WebView?


1
이안이 해결하지 못하는 몇 가지 문제를 해결하므로 내 답변을 올바른 것으로 표시하십시오.
neteinstein

페이지가로드 될 때 js로 기본 Java 코드를 호출하는 더 좋은 방법이 있다고 생각합니다. 이 답변은 iOS 용이지만 아이디어는 여기에도 적용됩니다 .
Kris Roofe

최소의 간결한 솔루션에 대한 아래 답변을 확인하십시오
Skynet

답변:


716

WebViewClient를 확장 하고 다음과 같이 onPageFinished ()를 호출 하십시오 .

mWebView.setWebViewClient(new WebViewClient() {

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

인터넷이 그렇게 빠르지 않은 경우 외부 로딩에 문제가 있습니다. 예를 들어 Google 애널리틱스 또는 기타 유사한 것들. 몇 가지 해결 방법을 시도했지만 많이 개선되었지만 아직 완벽하지는 않습니다. 때로는 앱이 로딩 화면에서 정지되어 네트워크 연결을 끊거나 다른 좋은 네트워크에 연결하지 않으면 종료가 불가능합니다. 나는 이것을 해결하는 방법을 아직 모른다. 나는 노력하고있다.
Felipe

1
완벽하게 작동합니다. 로드하기 전에 mWebView.setVisibility (View.INVISIBLE)를 사용할 수 있습니다. 로드가 완료되면 다시 View.VISIBLE로 설정하십시오. 이 스플래시 화면과 함께 사용했습니다 : android-developers.blogspot.de/2009/03/…
Johan Hoeksma

39
이것은 전혀 해결책이 아닙니다. 이 메소드가 호출 될 때 페이지가 이미로드되었다는 보장은 없습니다.
Hawk

3
이것은 구글 측에서 나쁜 디자인입니다. 이 조치가 완료 될 때마다 거의 항상 웹보기 자체가 아닌 상위 활동을 중심으로 무언가를 수행하려고합니다. 이벤트를 구독하는 대신 함수를 재정의하는 것이 일반적인 안티 패턴이며 안드로이드 개발을 싫어하는 이유입니다.
Ryan

6
이 메소드는로드 완료를 보장하지 않으며 URL로드에 중간 URL 탐색이 필요한 경우 두 번 이상 호출 할 수 있습니다. 그래서 이것은 여러 번 호출됩니다. 그러나 그것을 확인하는 방법.
초보자

150

@ian 이것은 100 % 정확하지 않습니다. 한 페이지에 여러 개의 iframe이있는 경우 여러 개의 onPageFinished (및 onPageStarted)가 있습니다. 리디렉션이 여러 개인 경우 실패 할 수도 있습니다. 이 접근 방식은 거의 모든 문제를 해결합니다.

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

최신 정보:

설명서에 따르면 : 포함 된 프레임의 내용이 변경 될 때, 즉 대상이 iframe 인 링크를 클릭하면 onPageStarted가 호출되지 않습니다.

트위터에서 pageFinished 만 호출되고 논리가 약간 엉망 인 특정 사례를 발견했습니다. 이를 해결하기 위해 X 초 후에로드를 제거하는 예약 된 작업을 추가했습니다. 다른 모든 경우에는 이것이 필요하지 않습니다.

업데이트 2 :

현재 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
onPageStarted의 문서에서주의 사항을 알았을 것 입니다. 포함 된 프레임의 내용이 변경 될 때 (예 : 대상이 iframe 인 링크 클릭) onPageStarted가 호출 되지 않습니다 . 따라서이 경우 논리가 왜곡 될 수 있습니다. BTW, @polen의 단순화는 실제로 작동합니까?
an00b

1
좋은 캐치, 프레임 물건을 눈치 채지 못했습니다. 나는 polen의 코드를 시도하지 않았다. 내가 그 일을 확신 할 수있는 유일한 것은 내가 사용하는 위의 것입니다.
neteinstein

3
사소한 수정. 실제로 "public void onPageStarted (WebView view, String url)"대신 "public void onPageStarted (WebView보기, 문자열 URL, 비트 맵 파비콘)"
MrMaffen

로드가 완료되지 않은 일부 최신 사이트 (예 : "agoda.com")에서는 작동하지 않습니다. 리디렉션이기 때문에 onPageFinished 호출을받지 않습니다.
kenyee

리디렉션 중에 onPageFinished가 두 번 호출되는 것을 보았습니다. 그러나 "페이지에 여러 개의 iframe이있는 경우 onPageFinished (및 onPageStarted)가 여러 개있을 것"이라고 말한 내용은 onPageFinished의 설명서에 따라 맞지 않습니다. "이 메서드는 메인 프레임에 대해서만 호출됩니다."
가닛

40

나는 @NeTeInStEiN (및 @polen) 솔루션에 꽤 부분적이지만 여러 부울 또는 상태 감시자 대신 카운터로 구현했을 것입니다 (다른 맛이지만 공유 할 수 있다고 생각했습니다). 그것에 대해 JS 뉘앙스가 있지만 논리가 이해하기 쉽다고 생각합니다.

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
코드가 좋아 보인다. URL이 아닌 html 데이터에서로드하는 webview에 대해 동일한 노력을 기울였습니다. 그러나 첫 번째 웹보기가 빠르게로드되고 두 번째 웹보기가로드되기 전에 onPageFinished를 트리거합니다. 정상적인 시나리오. running = 1, running = 2, --running = 1, --running = 0입니다. 실패한 비정상적인 시나리오-실행 중 = 1, --running = 0, 실행 중 = 1 실행 중 = 0
Ajith Memana

1
어떤 이유로 이벤트가 시작되지 않을 때 TODO 부분에 도달하지 못하는 또 다른 시나리오도 있습니다. 따라서 시간 초과를 확인하려면 타이머가 필요합니다. 또는 모든 것이 올바르게로드 된 것을 알면 JavaScript로 내 보낸 Java 함수를 호출 할 수 있습니다. documentReady () 또는 이와 유사한 것.
Codebeat

왜 그냥 running = 1;에서 onPageStarted()?
Choletski

@Choletski 1의 최대 값과 1보다 큰 숫자가 1이 아니기 때문에
Matthew는

25

하나의 우아한 솔루션을 찾았지만 엄격하게 테스트하지 않았습니다.

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
나는 그것을 테스트했고 완벽하게 작동하고 있습니다. 물론 onPageFinished 메소드 외부에서 호출하고 핸들러를 사용하여 짧은 간격을 검사 할 수 있습니다-경우에 따라 WebViewClient 클래스를 확장하고 싶지 않습니다.
Gal Rom

1
나는 이것이 허용 된 답변보다 낫다고 생각합니다 .onError를 확인하면됩니다.
Evin1_

1
이것이 정답입니다.
زياد

1
이것에 대한
찬성

23

NeTeInStEiN 의 코드를 다음과 같이 단순화 했습니다.

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

        }
 });

이전 콜백이 onPageStarted에 있으면 OnPageFinished를 쉽게 이해할 수 있으므로 페이지가 완전히로드됩니다.


3
@polen PAGE_STARTED가 지워지지 않습니까? shouldOverrideUrlLoading ()이 호출되지 않으면 어떻게됩니까?
an00b

20

진행률 표시 줄을 표시하려면 페이지 완료뿐만 아니라 진행률 변경 이벤트를 수신해야합니다.

mWebView.setWebChromeClient(new WebChromeClient(){

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

                //change your progress bar
            }


        });

BTW onPageFinished 메서드를 재정의하는 Indeterminate ProgressBar 만 표시하려면 충분합니다.



5

webview 클래스 의 getProgress 메소드로 Progress Staus를 추적 할 수 있습니다 .

진행 상태 초기화

private int mProgressStatus = 0;

다음과 같이로드하기위한 AsyncTask :

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 (); UI 스레드에서 호출해야합니다.
Skynet

5

답변 주셔서 감사합니다. 그것은 나에게 도움이되었지만 내 필요에 따라 조금 개선해야했습니다. 여러 페이지 시작과 완료가 있었으므로 pagefinish가 시작되었는지 새 페이지 시작인지 확인하는 타이머를 추가했습니다. 좋아요, 나쁜 설명입니다. 코드를 참조하십시오 :)

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

다음 은 JavaScript 후크에 대한 Android 기능을 활용하여 URL이로드 될 때 감지되는 새로운 방법입니다 . 이 패턴을 사용하여 문서 상태에 대한 JavaScript 지식을 활용하여 Android 런타임 내에서 고유 메소드 호출을 생성합니다. @JavaScriptInterface주석을 사용하여 이러한 JavaScript 액세스 가능 호출을 수행 할 수 있습니다 .

이 구현은 우리가 전화를해야합니다 setJavaScriptEnabled(true)WebView이되도록의 설정이 적합하지 않을 수 있습니다 응용 프로그램의 요구 사항, 예를 들어 보안 문제에 따라 달라집니다.

src / io / github / cawfree / webviewcallback / MainActivity.java (Jelly Bean, API 레벨 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"
/>

기본적으로 문서 상태를 테스트하는 데 사용되는 추가 JavaScript 함수를 추가합니다. 로드되면 onPageLoaded()Android에서 맞춤 이벤트를 시작합니다 MainActivity. 그렇지 않으면 페이지가 준비되면를 사용하여 Android를 업데이트하는 이벤트 리스너를 등록합니다 window.addEventListener('onload', ...);.

호출 한 후에이 스크립트를 추가 하고 있으므로 이벤트 this.getWebView().loadURL("")'듣지' 않아도됩니다 . 이벤트를 연속적으로 호출하여 JavaScript 후크를 추가 할 수있는 기회 만 있기 때문입니다. loadURL페이지가 이미로드 된 후


일반적으로 작동하는 멋진 솔루션입니다. 일부 스레드를 클릭하고 스레드가로드되면 https://reddit.com/r/Nature (일반적으로 Reddit 사용)에 문제가 있습니다 . 스레드가로드되면 해당 이벤트를 잡을 수 없습니다. 당신이 나를 도울 수 있습니까?
Primož Kralj

@ PrimožKralj 당신 이 이것으로 어떤 성공을 거두고 있다는 것을 알게되어 기쁘다 ... 구체적으로 제안 할 것이 확실하지 않지만, 당신이 알고있는 공개 이벤트가 있다면, 예를 들어 주석 개수가 업데이트되면 소스로 사용할 수 있습니다. Reddit의 API를 직접 눌러 문제를 해결할 수 있다고 생각 했습니까 ?
맵시

1
감사합니다. 트리거 된 이벤트를 다시 살펴보고 그 중 하나에 연결하려고합니다. API를 알고 있으며 앞으로이를 사용하여보다 강력한 솔루션을 구현하려고합니다. 감사!
Primož Kralj

1

진행률 표시 줄을 표시하려면 "onPageStarted"및 "onPageFinished"메서드로 충분합니다. 그러나 페이지 리디렉션과 함께 "is_loading"플래그를 사용하려는 경우이 메소드는 "onPageStarted> onPageStarted> onPageFinished> onPageFinished"큐와 같은 비 시퀀싱으로 실행될 수 있습니다.

그러나 짧은 테스트 (직접 테스트하십시오)에서 "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);
    }
}

is_loading = false페이지 종료 전에 활동을 완료 할 수 있으므로 정적 변수 인 경우 활동 종료시 " "를 설정 하십시오.


0

함께 URL을로드 SwipeRefreshLayout하고 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>

0

Runnable특정 웹 주소의 로딩이 완료되면 a를 실행 하도록 등록 할 수있는 방법이 있습니다 . 의 각 RunnableURL String을 해당 URL과 연결 Map하고 WebViewgetOriginalUrl()메소드를 사용 하여 적절한 콜백을 선택합니다.

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

OnPageFinshed 메서드가 호출되거나 진행률이 100 %에 도달하면 렌더러가 렌더링을 완료하지 않으므로 두 메서드가 모두 뷰가 완전히 렌더링되었다고 보장하지는 않습니다.

그러나 OnLoadResource 메소드에서 이미 렌더링 된 것과 여전히 렌더링중인 것을 알아낼 수 있습니다. 그리고이 방법은 여러 번 호출됩니다.

        @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

도움이 될 것입니다 .`var currentUrl = "google.com"var partOfUrl = currentUrl.substring (0, currentUrl.length-2)

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

// onReceiveError와 같은 오류에 대한 다른 재정의 메서드를 재정 의하여 이러한 모든 메서드가 차례로 호출되는 방식과 중단 점으로 디버깅하는 동안 동작 방식을 확인해야합니다. }`


-1

Kotlin 사용자의 경우 :

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

그래도 재정의 할 수있는 많은 방법이 있습니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.