【问题标题】:How to Load Cache Page in Webview如何在 Webview 中加载缓存页面
【发布时间】:2018-01-19 12:03:11
【问题描述】:

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

在 Chrome 浏览器上,当互联网连接断开时,它会重定向到缓存模式。 好吧,Android-Webview 并非如此。它给出了以下错误:

网页无法加载

网络: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);
    }
}

【问题讨论】:

    标签: android webview cache-manifest


    【解决方案1】:

    只包含 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);
        }
    

    【讨论】:

    • 好答案。但是,您可以考虑使用更通用的路径,而不是 mWebview.getSettings().setAppCachePath("/data/data/" + getPackageName() + "/cache");,例如:settings.setAppCachePath(getCacheDir().getAbsolutePath( ));
    【解决方案2】:
    mWebview.getSettings().setCacheMode( WebSettings.LOAD_CACHE_ELSE_NETWORK)
    

    这将告诉 WebView 从缓存中加载页面,但如果它需要缓存中没有的任何内容,它会查看网络,当你没有连接时,它只会给你“页面可以无法加载错误。”这是因为遗憾的是并非所有内容都存储在缓存中,即使使用此设置,您也会注意到浏览器正在使用网络。

    使用 WebSettings.LOAD_CACHE_ONLY

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

    【讨论】:

      【解决方案3】:

      改变这一行:

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

      收件人:

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

      【讨论】:

      • 您是否尝试在有互联网连接时打开它然后关闭连接并重新加载网页视图?
      • 是的,我做到了。我认为它正在寻找未找到的路径
      【解决方案4】:

      2021 年更新内容发生了变化:已弃用 应用程序缓存 API 已弃用,一旦 Chromium 中删除支持,此方法将在所有 Android 版本上成为无操作。考虑改用 Service Worker。请参阅https://web.dev/appcache-removal/ 了解更多信息。 改为阅读有关服务人员的信息 :) 快乐编码:P

      【讨论】:

        猜你喜欢
        • 2015-02-25
        • 1970-01-01
        • 2013-06-20
        • 2013-01-08
        • 2013-02-01
        • 2015-05-03
        • 1970-01-01
        • 1970-01-01
        • 2012-03-19
        相关资源
        最近更新 更多