简体   繁体   中英

How to save webpage as web archive and then display the web archive as a webpage using Android's WebView?

I am developing an Android application in Android Studio 3.0.1, Xubuntu 16.04 LTS, using a WebView as a wrapper for a responsive web app that contains HTML, CSS, JavaScript/jQuery and uses PHP/MySQL for the backend. Almost everything is working as expected: the pages fully render, JavaScript runs and the sign-up/login/news-feed systems work as they should.

But now I would like to implement some kind of simple caching system, so that the user can still see the last available version of the pages when there's no Internet connection.

As of now, I've managed to detect whether there is Internet connection; In case there's no connection, the WebView displays a local "Error" page, stored in the app files - which is better than the default Android "Connection Error" screen, but still the user can't see the images and text posts from the news feed when offline like in the Facebook app.

What I have tried (Java/Android Studio):

When the user opens the app (onCreate) :

  • If there's no connection, check for a locally saved version of the page it's trying to retrieve; If there is connection, save the page as a .mht file for the next time:

     if (!isConnected()) { try { File file = new File(getFilesDir(), FilenameUtils.getBaseName(url)); webView.loadUrl("file://" + file.getAbsolutePath() + ".mht"); } catch (Exception e) { Toast.makeText(getApplicationContext(), "Exception detected", Toast.LENGTH_LONG).show(); } } else { try { File file = new File(getFilesDir(), FilenameUtils.getBaseName(url)); webView.loadUrl(url); webView.saveWebArchive("file://" + file.getAbsolutePath() + ".mht"); } catch (Exception e) { Toast.makeText(getApplicationContext(), "Exception detected", Toast.LENGTH_LONG).show(); } } 

I have tried using webView.saveWebArchive() with different paths, including simple /path/to/file , file:///path/to/file , etc., to no avail. The closest I got to displaying something on the WebView was a bunch of raw MHTML, but apparently it wasn't rendered. I also got "File not found" screens and plain white screens without anything on them.

How can I properly save a web page from a WebView into a web archive, and then retrieve from the local storage and display it as a web page again?

Edit:

As suggested by greenapps in the comments, I overrode the "onPageFinished" method in the WebViewClient and called "saveWebArchive()" there:

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

    view.saveWebArchive(path);
    showMsg("Finished loading");

}

When the phone is connected to the Internet and the home page loads, it does show "Finished loading". After closing the app, disconnecting and opening it again, it now shows a blank background with the color of the original page, no more white pages or error messages. But there aren't any images, text or anything.

The problem here is that you need to wait for the page to finish loading before attempting to save it to an archive.

webView.loadUrl(url);
webView.saveWebArchive(path);

won't work since the page isn't fully loaded yet. So you need to override the "onPageFinished" method in your WebViewClient in order to save the archive only when the page is finished:

webView.setWebViewClient(new WebViewClient() {

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

        if (isConnected()) {

            try {

                Thread.sleep(2000);
                view.saveWebArchive(path_to_saveDir);

            } catch (InterruptedException e) {

                Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();

            }

        }

    }

});

Note that I've used Thread.sleep(2000) because there is a jQuery animation when the page loads, so it waits 2 seconds for the animation to finish, then saves the web archive.

webView.loadUrl(url); 
webView.saveWebArchive("file://" + file.getAbsolutePath() + ".mht");. 

You cannot save the page there.

Too early.

The page is not yet loaded.

Do it in onPageLoaded() or in onPageFinished().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM