Disabling caching, cookies, and everything else in WebView

I have a web service that I am trying to authenticate in the background using webview. When I initially submit the request, it will work accordingly (failure / success based on credentials), but after it seems to me that I am getting a cached response.

Here is my webview setup code:

WebView browser = new WebView(this);
WebSettings settings = browser.getSettings();
settings.setJavaScriptEnabled(true);
settings.setSavePassword(false);
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
settings.setAppCacheEnabled(false);
browser.setWebChromeClient(new WebChromeClient() {
    public void onProgressChanged(WebView view, int progress) {
    Log.d("BROWSERPROGRESS", Integer.toString(progress));
}
});
jsInterface = new AddAccountJSInterface();
browser.addJavascriptInterface(jsInterface, "ADDACCOUNTJSINTERFACE");
browser.setWebViewClient(new AddAccountClient(this));

So, as you can see, I have two additional classes controlling my webView:

  • An object that provides an interface for javascript (AddAccountJSInterface)
  • Webviewclient

In addition, I have a WebChromeClient, but it is only available for debugging, and I'm sure it won’t hurt anything.

The JS interface simply provides an easy way to get the HTML body to do the analysis, so I'm sure this is not a problem either.

WebViewClient , "" -.

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if(url.contains(INSTALL_PREFIX)) {
            HashMap<String, String> params = extractParameters(url);
            verificationComplete(params);
            return true;
        }
        return false;
    }

    @Override
    public void onPageFinished(WebView view, String url){
        if(invalidShop(view)) {
            Toast.makeText(context, context.getString(R.string.no_find_shop), Toast.LENGTH_SHORT).show();
            shopAddressField.requestFocus();
            replaceUiElements(loadingBar, addAccountButton);
        } else if(url.contains(ADMIN_AUTH_LOGIN)) {
            if(invalidLogin(view)) {
                Toast.makeText(context, context.getString(R.string.invalid_login),Toast.LENGTH_SHORT).show();
                emailField.requestFocus();
                replaceUiElements(loadingBar, addAccountButton);
            } else {
                String email = emailField.getText().toString();
                String password = passwordField.getText().toString();
                String submitJS = String.format(FORM_SUBMISSION_JS, email, password);

                jsInterface.setInnerHTML("");

                browser.loadUrl(submitJS);
            }
        }
    }

3 , , , . (shopAddressField, usernameField, passwordField), javascript, ( -), .

, , , , (, cookie?) , , , .

:

JSInterface - Java, javascript -, . JSInterface , setInnerHtml (String html).

javascript, webview:

javascript:window.ADDACOUNTJSINTERFACE.setInnerHTML(document.body.innerHTML)

setInnerHtml:

public void setInnerHtml(String innerHtml) {
    this.innerHtml = innerHtml;
}

, jsInterface.setInnerHtml(""), HTML-, ( , - ).

submitJS, Javascript, - :

// submitJS will be something like this once all the credentials have been set
// Note: I know that the server will make jQuery available
// Note: Much of the Java string formatting has been removed to help clarify
// the code.
String submitJS = 
    "javascript:(function() {
        $('login-input').value='username';
        $('password').value='password';
        $('sign-in-form').up().submit();
    })()"
// I then simply get the webview to execute the javascript above
webView.loadData(submitJS);
+5
1

, , , , .

javascript webView . , - .

, Mutex. , Javascript webView .

:

private class AddAccountJSInterface {
    private final String TAG = getClass().getName().toUpperCase();
    private Semaphore mutex = new Semaphore(1, false);
    private String innerHTML;

    public void aquireSemaphore() {
        Log.d(TAG, "Attempting to lock semaphore");
        try {
            mutex.acquire();
        } catch(InterruptedException e) {
            Log.d(TAG, "Oh snap, we got interrupted.  Just going to abort.");
            return;
        }
        Log.d(TAG, "Semaphore has been aquired");
    }

    @SuppressWarnings("unused")
    public void setInnerHTML(String html) {
            this.innerHTML = html;
            Log.d(TAG, "setInnerHTML is now releasing semaphore.");
            mutex.release();
            Log.d(TAG, "setInnerHTML has successfully released the semaphore.");
    }

    public synchronized String getInnerHTML() {
        Log.d(TAG, "getInnerHTML attempting to aquire semaphore, may block...");
        String innerHTML = "";
        try {
            mutex.acquire();

            Log.d(TAG, "getInnerHTML has aquired the semaphore, grabbing data.");
            innerHTML = this.innerHTML;

            Log.d(TAG, "getInnerHTML no longer needs semaphore, releasing");
            mutex.release();
        } catch (InterruptedException e) {
            Log.d(TAG, "Something has gone wrong while attempting to aquire semaphore, aborting");
        }

        return innerHTML;
    }
}

:

// I have access to the jsInterface object which is an instance of the class above as well as a webView which I will be executing the javascript on.
String getInnerHtmlJS = "javascript:window.MYJSINTERFACE.setInnerHTML(document.body.innerHTML);"
jsInterface.aquireSemaphore()
// Execute my JS on the webview
jsInterface.loadUrl(getInnerHtmlJS)
// Now we get our inner HTML
// Note: getInnerHTML will block since it must wait for the setInnerHTML (executed via the JS) function to release the semaphore
String theInnerHTML = jsInterface.getInnerHTML();
+2

All Articles