为什么evaluatateJavascript在handler(Android)内部被迭代



我想在Webview Android中评估一个javascript,如下代码所示。我想在3秒钟后进行评估。它是有效的,它在3秒钟后得到评估,但它(run((中的代码(在无限循环中每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将被加载/执行

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

执行click((后,返回false,这将停止重新加载浏览器。

例如,更改

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

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

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

最新更新