ChatGPT解决这个技术问题 Extra ChatGPT

如何监听 WebView 完成加载 URL?

我有一个正在从 Internet 加载页面的 WebView。我想显示一个 ProgressBar 直到加载完成。

如何监听 WebView 的页面加载完成?

请考虑将我的答案标记为正确,因为它解决了 ian 没有解决的一些问题。
我认为在页面加载时使用 js 调用本机 java 代码的更好方法。 Refer this answer, though it's for ios, but the idea applys here too
在下面查看我的答案以获得最小和简洁的解决方案
任何人都知道如何使用 MAUI WebView 做到这一点?

T
Taslim Oseni

扩展 WebViewClient 并调用 onPageFinished(),如下所示:

mWebView.setWebViewClient(new WebViewClient() {

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

完美运行。您可以在加载前使用 mWebView.setVisibility(View.INVISIBLE)。加载完成后将其设置回 View.VISIBLE。我将它与这个初始屏幕一起使用:android-developers.blogspot.de/2009/03/…
这根本不是解决方案。调用此方法时,不能保证页面已经加载。
这对谷歌来说是一个糟糕的设计。几乎在此操作完成时,您都希望围绕父 Activity 做一些事情,而不是 Web 视图本身。重写函数而不是订阅事件是一种常见的反模式,也是我不喜欢 android 开发的原因。
@Override 在哪里?
此方法不保证加载完成,如果 url 加载需要一些中间 url 导航,则可以多次调用。所以这会被多次调用。然而,它是一种检查它的方法。
C
Community

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

更新:

根据文档:当嵌入框架的内容发生变化时,不会调用 onPageStarted,即单击目标为 iframe 的链接。

我在 Twitter 上发现了一个类似的特定案例,其中只调用了一个 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; 
            }
        }
    });

您可能已经注意到 onPageStarted 文档中的警告:当嵌入框架的内容发生更改时,将不会调用 onPageStarted,即单击目标为 iframe 的链接。因此,这可能会扭曲这些情况下的逻辑。顺便说一句,@polen 的简化真的有效吗?
不错的收获,从来没有注意到框架的东西。我还没有尝试过波兰人的代码..我唯一可以保证的工作就是我正在使用的上面的代码。
只是一个小修正。它实际上是“public void onPageStarted (WebView view, String url, Bitmap favicon)”而不是“public void onPageStarted(WebView view, String url)”
不适用于一些从未完成加载的较新网站...例如,“agoda.com”。你永远不会得到 onPageFinished 调用,因为它是一个重定向。
我看到 onPageFinished 在重定向期间被调用了两次。但是,根据 onPageFinished 的文档,您所说的“如果您在一个页面中有多个 iframe,那么您将有多个 onPageFinished(和 onPageStarted)”是不正确的:“此方法仅对主框架调用。”
B
Ben Pearson

我非常偏爱@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.
            }
        }
    });
}

你的代码看起来不错。我一直在为从 html 数据而不是 url 加载的 webview 尝试相同的方法。但是,如果第一个 webview 快速加载并且在第二个 webview 开始加载之前,这个会触发 onPageFinished。正常情况。运行=1,运行=2,--运行=1,--运行=0。失败的异常情况 - running =1 , --running = 0, running =1 running =0
还有另一种情况,当某个事件由于某种原因没有被触发时,将永远不会到达 TODO 部分。所以你需要一个计时器来检查超时。或者,当您知道所有内容都已正确加载时,您可以在 javascript 中调用导出的 java 函数。像 documentReady() 或类似的东西。
为什么不只是 onPageStarted() 中的 running = 1;
@Choletski因为1的最大值和大于1的数字不是1。
S
Skynet

我也找到了一种优雅的解决方案,但尚未对其进行严格测试:

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

我已经对其进行了测试,它运行良好,当然,您可以从 onPageFinished 方法外部调用它并使用 Handler 以短时间间隔进行检查 - 如果您不想扩展 WebViewClient 类。
我相信这可能比接受的答案更好,你只需要检查 onError 就可以了。
F
Francesco Laurita

如果要显示进度条,则需要侦听进度更改事件,而不仅仅是页面完成:

mWebView.setWebChromeClient(new WebChromeClient(){

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

                //change your progress bar
            }


        });

顺便说一句,如果您只想显示一个覆盖方法 onPageFinished 的 Indeterminate ProgressBar 就足够了


C
Community

我已将 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;
            }

        }
 });

很容易理解,OnPageFinished 如果前面的回调是onPageStarted,那么页面就完全加载了。


@polen PAGE_STARTED 永远不会被清除?如果 shouldOverrideUrlLoading() 永远不会被调用怎么办?
R
Robby Pond
B
BenMorel

您可以通过 webview 类中的 getProgress 方法跟踪进度状态。

初始化进度状态

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 线程调用。
E
EscapeNetscape

感谢您的回答。它对我有帮助,但我必须根据自己的需要对其进行一些改进。我有几个 pagestarts 和 finish,所以我添加了一个计时器来检查是否在 pagefinish 开始一个新的 pagestart。好吧,不好的解释。看代码:)

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

});

A
Amin Keshavarzian

对于 Kotlin 用户:

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

虽然有很多方法可以覆盖


M
Mapsy

这是一种利用 Android's capability for JavaScript hooks 检测何时加载 URL 的新颖方法。使用这种模式,我们利用 JavaScript 对文档状态的了解在 Android 运行时生成本地方法调用。可以使用 @JavaScriptInterface 注释进行这些 JavaScript 可访问的调用。

此实现要求我们在 WebView 的设置上调用 setJavaScriptEnabled(true),因此它可能不适合,具体取决于您的应用程序的要求,例如安全问题。

src/io/github/cawfree/webviewcallback/MainActivity.java(果冻豆,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;
    }

}

资源/布局/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 函数,用于测试文档的状态。如果已加载,我们会在 Android 的 MainActivity 中启动自定义 onPageLoaded() 事件;否则,我们使用 window.addEventListener('onload', ...); 注册一个事件侦听器,该侦听器在页面准备好后更新 Android。

由于我们是在调用 this.getWebView().loadURL("") 后附加此脚本,因此我们可能根本不需要 'listen' 事件,因为我们只有机会一旦页面已经加载,通过连续调用 loadURL 来附加 JavaScript 钩子。


很棒的解决方案,通常有效。我在使用 https://reddit.com/r/Nature 时遇到问题(通常使用 Reddit),当您单击某个线程并加载该线程时,我无法捕捉到该事件。你能帮我吗?
@PrimožKralj 很高兴听到你在这方面取得了一些的成功......我不确定具体建议什么,但如果有任何类型的公共事件你知道触发了你可以例如,当评论计数更新时,您可以将其用作源。您是否考虑过直接点击 Reddit 的 API 可以解决您的问题?
谢谢,我会再看看触发的事件并尝试连接其中一个。我知道 API,并将尝试在未来使用它来实现更强大的解决方案。谢谢!
J
Jalil Hamdollahi Oskouei

只是为了显示进度条,“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”,如果它是一个静态变量,因为活动可以在页面完成之前完成。


s
shreedhar

当调用 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.

            }
        }

H
Hamid

使用 SwipeRefreshLayoutProgressBar 加载 url:

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>

M
Mapsy

这是一个允许您注册一个 Runnable 以在特定网址完成加载后执行的方法。我们将每个 RunnableMap 中的相应 URL String 相关联,并使用 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;
    }

}

S
SomeOne

使用它应该会有所帮助。`var currentUrl = "google.com" var partOfUrl = currentUrl.substring(0, currentUrl.length-2)

webView.setWebViewClient(object: 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,以查看所有这些方法是如何一个接一个地调用的,以及它们在使用断点调试时的行为方式。 } `


n
niek tuytel

这将在他开始加载页面之前被调用(并获得与 onFinished() 相同的参数)

@Override
public void onPageCommitVisible(WebView view, String url) {
   super.onPageCommitVisible(view, url);
}

C
Cemil AKAN

Kotlin 解决方案第一个解决方案是将 webviewclient 创建为私有类,它更有效。另一方面,第二个解决方案是分拣机:)

第一个解决方案

class MainActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val webView : WebView = findViewById(R.id.webView)
    webView.webViewClient = MyWebViewClient()
 }

private class MyWebViewClient : WebViewClient() {
    override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
        println("Load Started")
    }
    override fun onPageFinished(view: WebView, url: String) {
        println("Load Finished")
    }
  }
}

第二种解决方案

class MainActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val webView : WebView = findViewById(R.id.webView)
    webView.webViewClient = object : WebViewClient() {
        override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
            println("Load Started")
        }
        override fun onPageFinished(view: WebView, url: String) {
            println("Load Finished")
        }
     }
 }

两种解决方案实际上相同。所以 onPageStarted 函数在页面开始加载时运行,另一个挂起 onPageFinished 函数在页面完全加载时工作。您可能希望在 onPageFinished 函数中编写示例 loadFinishedRun() 函数。

迟到总比不到好


一般来说,如果答案包括对代码的用途的解释,以及为什么在不介绍其他人的情况下解决问题的原因,答案会更有帮助。
该评论是从评论中发布的。如果您对评论有任何问题,尽管您的关注表示赞赏,但最好将其标记出来。无论问题、答案或评论的内容如何,都必须遵循 Code of Conduct,这一点也很重要。