如何在Webview中加载缓存页面

6

我在HTML页面上应用了缓存清单。

在Chrome浏览器中,当互联网连接断开时,它会重定向到缓存模式。但是,在Android-Webview中情况并非如此。它会出现以下错误:

无法加载网页

net:ERR_NAME_NOT_RESOLVED

我已经查阅了各种资源,但似乎都没有帮助。

下面是我正在使用的代码:

package com.example.page;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

import com.google.firebase.iid.FirebaseInstanceId;

public class MainActivity extends Activity {
    public static WebView mWebview;
    private android.content.Context Context;
    private static String getIntentValue = null;
    public static SharedPreferences sharedPreferences;
    private ProgressDialog mProgressDialog;
    private String mCM;
    private ValueCallback<Uri> mUM;
    private ValueCallback<Uri[]> mUMA;
    private final static int FCR=1;

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent){
        super.onActivityResult(requestCode, resultCode, intent);
        mWebview.setWebViewClient(new Callback());

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        Context = this;
        String regId = FirebaseInstanceId.getInstance().getToken();

        getIntentValue = getIntent().getStringExtra("value");

        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);

        if (!DetectConnection.checkInternetConnection(this)) {
            Toast.makeText(getApplicationContext(), "No Internet Connection!", Toast.LENGTH_LONG).show();
            finish(); //Calling this method to close this activity when internet is not available.

        } else {

            mWebview = (WebView) findViewById(R.id.webview1);
            WebSettings webSettings = mWebview.getSettings();
            mWebview.getSettings().setJavaScriptEnabled(true);
            mWebview.setWebChromeClient(new WebChromeClient());
            mWebview.setWebViewClient(new CustomWebViewClient());

            //improve WebView Performance
            mWebview.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
            mWebview.getSettings().setAppCacheEnabled(false);
            mWebview.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);


            if(Build.VERSION.SDK_INT >=23 && (ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)) {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.CAMERA}, 1);
            }

            mWebview.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
            webSettings.setDomStorageEnabled(true);
            webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
            webSettings.setUseWideViewPort(true);
            webSettings.setAllowFileAccess(true);
            webSettings.setSavePassword(true);
            webSettings.setSaveFormData(true);
            webSettings.setEnableSmoothTransition(true);

            // progress dialog
            mProgressDialog = new ProgressDialog(Context);

            if (sharedPreferences.getBoolean("isKeyGenerated", true)) {

                if (getIntentValue != null) {
                    mWebview.loadUrl("http://www.example.com/page");
                    getIntentValue = null;

                } else {
                    mWebview.loadUrl("http://www.example.com/page2");
                }
            }
        }


    }



    public class Callback extends WebViewClient{
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl){
            Toast.makeText(getApplicationContext(), "Failed loading app!", Toast.LENGTH_SHORT).show();
        }
    }


    // Function to load all URLs in same webview
    private class CustomWebViewClient extends WebViewClient {
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (url.contains(".pdf")) {
                Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                startActivity(i);
            } else {
                view.loadUrl(url);
            }
            return true;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            // TODO Auto-generated method stub
            super.onPageStarted(view, url, favicon);

            //on page started, show loading page
            mProgressDialog.setCancelable(true);
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            mProgressDialog.show();

        }

        @Override
        public void onPageFinished(WebView view, String url)
        {
            String currentPage= mWebview.getUrl();

            SharedPreferences.Editor editor = sharedPreferences.edit();
            editor.putString("currentpage",currentPage);
            editor.commit();

            //after loading page, remove loading page

            // TODO Auto-generated method stub
            super.onPageFinished(view, url);
            mProgressDialog.dismiss();
        }

        @Override
        public void onReceivedError(WebView view, int errorCode,
                                    String description, String failingUrl) {
            view.loadUrl("http://example.com/page");
        }

    }

    @Override
    public void onBackPressed() {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        String currenturl = sharedPreferences.getString("currentpage", null);

        mWebview.requestFocus();

        if (currenturl.contains("http://example.com/page")){
            moveTaskToBack(true);
        }else{
            mWebview.goBack();
        }

        if (mWebview.canGoBack()) {
            if (!DetectConnection.checkInternetConnection(Context)) {
                Toast.makeText(Context, "No Internet Connection!", Toast.LENGTH_SHORT).show();
            }

        }
    }


    public static void loadUrl(String key) {

        if (getIntentValue != null) {
            mWebview.loadUrl("http://example.com/page");
            getIntentValue = null;
        } else {
            mWebview.loadUrl("http://example.com/page");
        }

    }


    public static void reLoad() {
        mWebview.reload();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig){
        super.onConfigurationChanged(newConfig);
    }
}
4个回答

4

只需包含 enableHTML5AppCache() 方法即可。

private void enableHTML5AppCache() {
        mWebview.getSettings().setDomStorageEnabled(true);
        mWebview.getSettings().setAppCachePath("/data/data/" + getPackageName() + "/cache");
        mWebview.getSettings().setAppCacheEnabled(true);
        mWebview.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
    }

1
好答案。不过,你可以考虑使用更多用途的路径,如:settings.setAppCachePath(getCacheDir().getAbsolutePath());,而不是mWebview.getSettings().setAppCachePath("/data/data/" + getPackageName() + "/cache"); - M. Marmor

3
mWebview.getSettings().setCacheMode( WebSettings.LOAD_CACHE_ELSE_NETWORK)

这将告诉WebView从缓存中加载页面,但如果需要加载的内容不在缓存中,它会查找网络。当您没有连接时,它将只显示“无法加载页面”的错误信息。这是因为遗憾的是,并非所有内容都存储在缓存中,即使使用此设置,您也会注意到浏览器正在使用网络。
使用WebSettings.LOAD_CACHE_ONLY。
mWebview.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ONLY);

1

更改此行:

mWebview.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);

至:

mWebview.getSettings().setCacheMode( WebSettings.LOAD_CACHE_ELSE_NETWORK)

你尝试过在有网络连接的情况下打开它,然后断开连接并重新加载 Webview 吗? - TREAF ALSHEMERI
是的,我做了那个。我认为它正在寻找未找到的路径。 - Observer

1

2021 年更新,一些事情已经发生了变化:已废弃。 应用程序缓存 API 已被废弃,一旦 Chromium 中的支持被删除,此方法将在所有 Android 版本上成为 no-op。考虑改用 Service Workers。有关更多信息,请参见https://web.dev/appcache-removal/。 请阅读有关服务工作者的文章 :) 祝编码愉快 :P


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接