为什么 evaluateJavascript 在 handler(Android) 中迭代?

why evaluateJavascript is getting iterated inside handler(Android)?

我想在 Webview Android 中评估 javascript,如下面的代码所示。我想在 3 秒后评估它。它有效,它在 3 秒后得到评估,但它(运行() 内的代码)在无限循环中每 3 秒后不断重复。 我只想3秒后评价一次

                    int delay = 3000;
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {

                            Toast.makeText(MainActivity.this,"Reached",Toast.LENGTH_LONG).show();
                            final String js3 = "javascript:document.getElementsByClassName('icon')[0].click();";
                            view.evaluateJavascript(js3,null);
                        }
                    },delay);

MainActivity.java

public class MainActivity extends AppCompatActivity {

    //webview
    private WebView webView;
    private String uname,password;
    private int x=0;
    private  CountDownTimer timer;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        webView = (WebView) findViewById(R.id.webView);

       
        final String password = "Pass@123";
        final String username = "111111111";
        //url
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setDomStorageEnabled(true);
        webView.loadUrl("https://something.com/xyz/abc/student2020.html#");
        webView.setWebViewClient(new WebViewClient(){
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);

                final String js = "javascript:" +
                        "document.getElementById('phone_1').value = '" + username + "';"  +
                        "document.getElementById('submit_1').click()";

                if (Build.VERSION.SDK_INT >= 19) {
                    view.evaluateJavascript(js,null);

                            final String js2 = "javascript:"+"document.getElementById('pass_2').value = '"+password+"';"
                                    + "document.getElementById('phone_2').value = '" + username + "';"
                                    + "javascript:document.getElementById('submit_2').click()";
                            view.evaluateJavascript(js2,null);
                            

                    int delay = 3000;
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {

                            Toast.makeText(MainActivity.this,"Reached",Toast.LENGTH_LONG).show();
                            final String js3 = "javascript:document.getElementsByClassName('icon')[0].click();";
                            view.evaluateJavascript(js3,null);
                        }
                    },delay);

                } else {
                    view.loadUrl(js);

                }
            }
        });

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <WebView
        android:id="@+id/webView"
        android:layout_height="match_parent"
        android:layout_width="match_parent"/>

</RelativeLayout>

调用 evaluateJavascript 将使 onPageFinished 被进一步调用,您将在其中再次设置您的 Handler

避免这种情况的最简单方法是引入一些 boolean,这将在评估 JS 后被标记并防止第二次和进一步的调用

private WebView webView;
private String uname,password;
private int x=0;
private  CountDownTimer timer;
private boolean jsExecuted = false;

回调中

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if (jsExecuted) return;
            jsExecuted = true
            // JS execution code
        }

顺便说一句。您可能在 <19 岁的流程中遇到了一些错误,只有第一个 JS 会是 loaded/executed

您正在代码中执行 click() 操作,这会导致页面再次呈现,然后再次启动整个过程,导致它永远 运行。

执行 click() 后,return false,这应该会停止浏览器重新加载。

e.g.change

document.getElementById('submit_1').click()

document.getElementById('submit_1').click(); return false;

您需要在调用 click() 的所有实例上执行此操作。