WebView caching problem


Introduction to this section:

Nowadays, there are many portal information websites, such as Huxiu, ifanr, Titanium Media and other APPs. To put it simply, they are information reading APPs. There are many They all directly nest a WebView to display relevant information, which may involve the cache of WebView!

The so-called page cache It means: saving the HTML, JS, CSS and other page-related data and other resources required when loading a web page, when there is no Internet or When the network status is poor, load the relevant data saved locally! There are two ways to implement this cache. One is to write a cache in the background. The downloaded Service downloads the article-related data to the database according to your own needs or saves it to the corresponding folder, and then loads it next time Before corresponding to the URL, first determine whether there is a local cache. If there is a local cache, load the local cache first. If not, execute the network request and cache at the same time. Related resources, typically the old version of 36Kr, will first offline the article after entering it, and then display it!

Of course, what this section is going to explain is not This method of writing logic by yourself uses the caching function of WebView itself to cache the page. This method is very easy to use. Simple, we only need to enable relevant functions for WebView settings and set the cache path of the database to complete the cache! specific Let’s implement it one by one~


1. Cache classification:

The first thing to say is the classification of cache. The data we cache is divided into For: Page cache and data cache

  • Page cache: HTML, JS, CSS and other page or resource data when loading a web page, These cached resources are due to the browser Generated by the behavior of the browser, developers can only indirectly affect these cached data by configuring HTTP response headers to affect the behavior of the browser. The cache index is placed under:/data/data/<package name>/databasesThe corresponding file is placed under:/data/data/package_name/cache/webviewCacheChromunm

  • Data cache: divided into AppCache and DOM Storage What we developers can control by ourselves are these cache resources,

  • AppCache: We can selectively cache everything in the web browser, from pages to pictures to scripts, css, etc. This is especially useful when it comes to CSS and JavaScript files that are applied to multiple pages of your website. Its size is currently usually 5M. On Android, you need to manually turn on (setAppCacheEnabled) and set the path (setAppCachePath) and capacity. (setAppCacheMaxSize), and ApplicationCache.db is used in Android to save AppCache data!

  • DOM Storage: Stores some simple data that can be solved using key/value pairs. Depending on the scope, there is Session There are two types of Storage and Local Storage, respectively used for session-level storage (the page disappears when it is closed) and localized storage (unless it is actively Delete, otherwise the data will never expire) You can manually turn on DOM Storage (setDomStorageEnabled) in Android, Set storage path (setDatabasePath) Webkit in Android will generate two files for DOMStorage (my_path/localstorage/http_blog.csdn.net_0.localstorage and my_path/Databases.db)

Okay, after reading the above, do you want to say something, damn, what the hell, it looks so complicated1.jpgOf course, don’t memorize it, just know that these things exist, and then slowly study them when you use them in actual development, and We generally only care about how Setting cache for WebView and how to delete cache! We can take a look at the file structure after running the demo we wrote below, and open the File Explorer of DDMS:

2.png

Hey, it’s clear at a glance, right~, by the way, there’s something else to say Several caching modes:

  • LOAD_CACHE_ONLY: Does not use the network, only reads local cache data
  • LOAD_DEFAULT: Determine whether to retrieve data from the network based on cache-control.
  • LOAD_CACHE_NORMAL: Deprecated in API level 17, it works the same as LOAD_DEFAULT mode starting from API level 11
  • LOAD_NO_CACHE: Does not use cache, only from Obtain data from the network.
  • LOAD_CACHE_ELSE_NETWORK, as long as it is available locally, regardless of whether it is expired or no-cache, the data in the cache will be used.

Summary: Based on the above two modes, the recommended cache strategy is to determine whether there is a network, and if so, use LOAD_DEFAULT, When there is no network, use LOAD_CACHE_ELSE_NETWORK.

The next stacking time!


2. Turn on the caching function for WebView

Let’s turn on the caching function for WebView. First, let’s take a look at the implementation renderings:

Operation rendering:

3.gif

Process analysis: 1. After entering the page, the url is loaded by default, then click on a link to jump to the second page and exit the APP. 2. Turn off wifi and mobile network, and then re-enter. It is found that the page is still loaded even if there is no network. It can be loaded even when you open the first link, but when you open other links, you find that the web page cannot be found! 3. Click to clear cache, close the application, re-enter, and find that the page cannot be opened!

Next is the code implementation: MainActivity.java:

public class MainActivity extends AppCompatActivity {

    private WebView wView;
    private Button btn_clear_cache;
    private Button btn_refresh;
    private static final String APP_CACHE_DIRNAME = "/webcache"; // web缓存目录
    private static final String URL = "http://blog.csdn.net/coder_pig";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        wView = (WebView) findViewById(R.id.wView);
        btn_clear_cache = (Button) findViewById(R.id.btn_clear_cache);
        btn_refresh = (Button) findViewById(R.id.btn_refresh);
        wView.loadUrl(URL);
        wView.setWebViewClient(new WebViewClient() {
            //设置在webView点击打开的新网页在当前界面显示,而不跳转到新的浏览器中
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });
        WebSettings settings = wView.getSettings();
        settings.setJavaScriptEnabled(true);
        //设置缓存模式
        settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        // 开启DOM storage API 功能
        settings.setDomStorageEnabled(true);
        // 开启database storage API功能
        settings.setDatabaseEnabled(true);
        String cacheDirPath = getFilesDir().getAbsolutePath() + APP_CACHE_DIRNAME;
        Log.i("cachePath", cacheDirPath);
        // 设置数据库缓存路径
        settings.setAppCachePath(cacheDirPath);
        settings.setAppCacheEnabled(true);
        Log.i("databasepath", settings.getDatabasePath());

        btn_clear_cache.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                wView.clearCache(true);
            }
        });

        btn_refresh.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                wView.reload();
            }
        });
    }

    //重写回退按钮的点击事件
    @Override
    public void onBackPressed() {
        if(wView.canGoBack()){
            wView.goBack();
        }else{
            super.onBackPressed();
        }
    }
}

The code is very simple. All we do is to enable the cache function, and set the cache mode and cache It’s just the path to the data!


3. Delete the cached data of WebView

In the above example, we have achieved deletion of the cache by calling the clearCache(true) method of WebView! In addition to this method, there are also the following methods:

  • setting.setCacheMode(WebSettings.LOAD_NO_CACHE);
  • deleteDatabase("WebView. db"); and deleteDatabase("WebViewCache.db");
  • webView.clearHistory();
  • webView.clearFormData();
  • getCacheDir().delete();
  • Write the delete method manually and delete the cache folder iteratively!

Of course, as mentioned earlier, we can only directly operate on the data part, and page caching is due to the browser Produced by the behavior of the browser, we can only indirectly affect the behavior of the browser by configuring the HTTP response header. These cache data. So the above method only deletes the cache of the data part!


4. Sample code download:

WebViewDemo7.zipDownload WebViewDemo7.zip


5. Summary of this section:

Okay, this section ends with the WebView caching issue. Here I just write how to enable caching for WebView. As well as deleting the cache, I will look into it slowly when I encounter it in the future. Here is an image~ Well, that’s all~ Thank you

4.gif

By the way, I almost forgot to post this Section reference link:

Android webView cache Cache + HTML5 offline function solution

Android record 25-WebView implements offline cache reading

Android Clear WebView cache