Android Studio: WebView loading twice

I’m doing a little personal project and I have a login screen that inputs username and password into a webpage and clicks login button, all that using Javascript. I have a problem though, the code works, but it executes two times, first time it doesn’t work and the second time it works.

Here’s my code

webView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);

                webView.loadUrl("javascript: {" +
                        "document.getElementById('username').value = '" + username.getText().toString() + "';" +
                        "document.getElementById('password').value = '" + password.getText().toString() + "';" +
                        "document.getElementsByClassName('ZLoginButton DwtButton')[0].click();" +
                        "};"
                );

                System.out.println("================>" + username.getText().toString() + " " + password.getText().toString());
                System.out.println("================> " + webView.getUrl());

                if (webView.getUrl().equals("https://mail.metropolitan.ac.rs/m/zmain")) { // If it goes from login webpage to the main webpage
                    System.out.println("Connected...");
                } else {
                    System.out.println("Disconnected..." + " Website: " + webView.getUrl());
                }
            }
        });

Here’s the output

I/.example.metap: Waiting for a blocking GC ProfileSaver
W/.example.metap: Accessing hidden method Landroid/media/AudioManager;->getOutputLatency(I)I (greylist, reflection, allowed)
W/cr_media: Requires BLUETOOTH permission
D/HostConnection: HostConnection::get() New Host Connection established 0xcd0965f0, tid 19767
D/HostConnection: HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_vulkan ANDROID_EMU_deferred_vulkan_commands ANDROID_EMU_vulkan_null_optional_strings ANDROID_EMU_vulkan_create_resources_with_requirements ANDROID_EMU_YUV_Cache ANDROID_EMU_async_unmap_buffer ANDROID_EMU_vulkan_ignored_handles ANDROID_EMU_vulkan_free_memory_sync ANDROID_EMU_vulkan_shader_float16_int8 ANDROID_EMU_vulkan_async_queue_submit GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_gles_max_version_2 
E/chromium: [ERROR:gl_surface_egl.cc(549)] eglChooseConfig failed with error EGL_SUCCESS
D/EGL_emulation: eglCreateContext: 0xf6e62210: maj 2 min 0 rcv 2
D/EGL_emulation: eglMakeCurrent: 0xf6e62210: ver 2 0 (tinfo 0xf71b0490) (first time)
E/chromium: [ERROR:gl_surface_egl.cc(549)] eglChooseConfig failed with error EGL_SUCCESS
I/VideoCapabilities: Unsupported profile 4 for video/mp4v-es
W/cr_MediaCodecUtil: HW encoder for video/avc is not available on this device.
D/EGL_emulation: eglCreateContext: 0xf6e62f30: maj 2 min 0 rcv 2

I/System.out: ================>"myUsername" "myPassword"
I/System.out: ================> https://mail.metropolitan.ac.rs/         
    Disconnected... Website: https://mail.metropolitan.ac.rs/         //<-----------Here is the first

I/chromium: [INFO:CONSOLE(9)] "Error parsing a meta element's content: ';' is not a valid key-value pair separator. Please use ',' instead.", source: https://mail.metropolitan.ac.rs/m/zmain (9)
I/chromium: [INFO:CONSOLE(10)] "An error occured in: https://mail.metropolitan.ac.rs/m/zmain
    {
        msg: Uncaught ReferenceError: dId is not defined,
        line: 1081
    }", source: https://mail.metropolitan.ac.rs/m/zmain (10)
    [INFO:CONSOLE(1081)] "Uncaught ReferenceError: dId is not defined", source: https://mail.metropolitan.ac.rs/m/zmain (1081)

I/System.out: ================>"myUsername" "myPassword"
    ================> https://mail.metropolitan.ac.rs/m/zmain
    Connected...                                                   //<-----------Here is the second

I/chromium: [INFO:CONSOLE(10)] "An error occured in: https://mail.metropolitan.ac.rs/m/zmain
    {
        msg: Uncaught TypeError: Cannot set property 'value' of null,
        line: 1
    }", source: https://mail.metropolitan.ac.rs/m/zmain (10)
    [INFO:CONSOLE(1)] "Uncaught TypeError: Cannot set property 'value' of null", source: https://mail.metropolitan.ac.rs/m/zmain (1)

So, If the URL changes from https://mail.metropolitan.ac.rs/ to https://mail.metropolitan.ac.rs/m/zmain, that means that the login was successful. But as you see, the code runs twice, first time it says that it didn’t connect but the second time it says that it connected.

Answer

If the url is OK after onPageStarted method starts onPageFinished, but if the url is redirected after onPageStarted starts shouldOverrideUrlLoading and then onPageFinished. You should just check if the loading URL is redirected or not

private boolean isRedirected;

@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {   

  if (!isRedirected) {      
    //Do something you want when starts loading
  }

  isRedirected = false;
}

If the URL is redirected the callback starts this function

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {

  view.loadUrl(url);
  isRedirected = true;
  return true;
}

Before doing something in onPageFinished check if the callback has entered into shouldOverrideUrlLoading method

@Override
public void onPageFinished(WebView view, String url) {

  if (!isRedirected) {
    //Do something you want when finished loading 
  }
}