Android的web视图不加载从缓存中第二页视图、缓存、加载、Android

2023-09-07 14:58:06 作者:你的世界我主宰

我有一个Android应用程序,仅仅拥有一个网站。我想应用程序缓存的网站供脱机使用的网页。

我在做一个简单的测试,看看是否缓存工作,但不幸的是它未能加载页面我有previously装在联机模式下,当下线。为了使事情更清楚我加载以下2页在联机模式下时。

  webView.loadUrl(http://www.bmimobile.co.uk/why-bmi.php,getHeaders());webView.loadUrl(http://www.bmimobile.co.uk/,getHeaders()); 

我希望是,为什么 - bmi.php页面加载到缓存中,以及随后的网页。的http:// www.bmimobile.co.uk/ 。后者页面具有其指在第一页上它的链接。如果我再出来的应用程序,并打开网络适配器电源,然后返回到应用程序的 http://www.bmimobile.co .UK / 页面不显示,但是当我点击为什么 - 英伦链接,页面不显示。我敬酒短消息显示说:错误加载页面。

谁能告诉我,为什么Webview是不缓存加载页面供以后脱机使用?

下面是主要的活动,我已经扩展定义appcachepath Application对象。

在此先感谢

 包uk.bmi.mobile;进口的java.io.File;进口的java.util.HashMap;进口的java.util.Map;进口android.app.Activity;进口android.content.Context;进口android.net.ConnectivityManager;进口android.net.NetworkInfo;进口android.os.Bundle;进口android.util.Log;进口android.webkit.WebSettings;进口android.webkit.WebView;进口android.webkit.WebViewClient;公共类MainActivity延伸活动{    私人的WebView web视图;    私有静态最后弦乐TAG = MainActivity.class.getSimpleName();    ApplicationExt bmiAppObj;    //指示服务器来设置它的头,使资源可缓存    私人地图<字符串,字符串> getHeaders(){        地图<字符串,字符串>标题=新的HashMap<字符串,字符串>();        headers.put(IS_ALEX_APP,1);        返回头;    }    @覆盖    公共无效的onCreate(捆绑savedInstanceState){        super.onCreate(savedInstanceState);        的setContentView(R.layout.activity_main);        Log.e(TAG中的onCreate中mainactivity);    } // OnCreate中结束    私人布尔isNetworkAvailable(){        ConnectivityManager connectivityManager =(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);        的NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();        返回activeNetworkInfo!= NULL;    }    @覆盖    保护无效onResume(){        super.onResume();        Log.e(TAG,在onResume中mainactivity);        web视图=(的WebView)findViewById(R.id.webView1);        bmiAppObj =(ApplicationExt)getApplication();        如果(isNetworkAvailable()==真){            。webView.getSettings()setSupportZoom(真);            。webView.getSettings()setBuiltInZoomControls(真);            webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);            webView.setScrollbarFadingEnabled(真);            。webView.getSettings()setLoadsImagesAutomatically(真);            webView.getSettings()setDomStorageEnabled(真)。            webView.getSettings()setAppCacheEnabled(真)。            //设置缓存大小为8 MB默认情况下。应该是绰绰有余            webView.getSettings()setAppCacheMaxSize(1024 * 1024 * 8)。            //这下一个是疯了。这对您的应用程序缓存的默认位置            //但是,这并不适合我没有这条线的工作。            //更新:没有硬性codeD路径。由于凯文·霍金斯            字符串appCachePath = getApplicationContext()getCacheDir()getAbsolutePath()。            Log.e(TAGappCachePath =+ appCachePath);            webView.getSettings()setAppCachePath(appCachePath)。            。webView.getSettings()setAllowFileAccess(真);            webView.getSettings()setJavaScriptEnabled(真)。            //加载的URL web视图内,而不是在外部Web浏览器            webView.setWebViewClient(新WebViewClient());            。webView.getSettings()setCacheMode(WebSettings.LOAD_DEFAULT);            webView.loadUrl(http://www.bmimobile.co.uk/why-bmi.php,getHeaders());            webView.loadUrl(http://www.bmimobile.co.uk/,getHeaders());            }其他{                。webView.getSettings()setSupportZoom(真);                。webView.getSettings()setBuiltInZoomControls(真);                webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);                webView.setScrollbarFadingEnabled(真);                。webView.getSettings()setLoadsImagesAutomatically(真);                webView.getSettings()setDomStorageEnabled(真)。                webView.getSettings()setAppCacheEnabled(真)。                //设置缓存大小为8 MB默认情况下。应该是绰绰有余                webView.getSettings()setAppCacheMaxSize(1024 * 1024 * 8)。                //这下一个是疯了。这对您的应用程序缓存的默认位置                //但是,这并不适合我没有这条线的工作。                //更新:没有硬性codeD路径。由于凯文·霍金斯                字符串appCachePath = getApplicationContext()getCacheDir()getAbsolutePath()。                Log.e(TAGappCachePath =+ appCachePath);                webView.getSettings()setAppCachePath(appCachePath)。                。webView.getSettings()setAllowFileAccess(真);                webView.getSettings()setJavaScriptEnabled(真)。                //加载的URL web视图内,而不是在外部Web浏览器                webView.setWebViewClient(新WebViewClient());                。webView.getSettings()setCacheMode(WebSettings.LOAD_CACHE_ONLY);                webView.loadUrl(http://www.bmimobile.co.uk/,getHeaders());            }    }    @覆盖    公共文件getCacheDir()    {        //注:该方法采用的是Android 2.1使用        Log.e(TAGgetcachedir);        返回getApplicationContext()getCacheDir()。    }    @覆盖    保护无效的onSaveInstanceState(捆绑outState)    {        super.onSaveInstanceState(outState);        //保存的WebView的状态        webView.saveState(outState);    }    @覆盖    保护无效onRestoreInstanceState(捆绑savedInstanceState)    {        super.onRestoreInstanceState(savedInstanceState);        //恢复的WebView的状态        webView.restoreState(savedInstanceState);    }} // mainActivity结束 
新技能Get 如何利用HTTP技术提升网页的加载速度

 包uk.bmi.mobile;进口的java.io.File;进口android.app.Application;进口android.os.Environment;进口android.util.Log;公共类ApplicationExt扩展应用{    私有静态最后弦乐TAG = ApplicationExt.class.getSimpleName();    //注意:这条道路的内容将被删除    当应用程序被卸载//(Android 2.2及更高版本)    受保护的文件extStorageAppBasePath;    受保护的文件extStorageAppCachePath;    web服务web服务;    BmiDB bmiDb;    @覆盖    公共无效的onCreate()    {        super.onCreate();         Log.e(TAG,里面appext);         Web服务=新的WebService(本);         bmiDb =新BmiDB(本);        //检查外部存储可写        如果(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))        {            //检索的基本路径在外部存储的应用程序            文件externalStorageDir = Environment.getExternalStorageDirectory();            如果(externalStorageDir!= NULL)            {                // {} SD_PATH /Android/data/com.devahead.androidwebviewcacheonsd                extStorageAppBasePath =新的文件(externalStorageDir.getAbsolutePath()+                    文件分割符+Android的+文件分割符+数据+                    文件分割符+ getPackageName());            }            如果(extStorageAppBasePath!= NULL)            {                // {} SD_PATH /Android/data/com.devahead.androidwebviewcacheonsd/cache                extStorageAppCachePath =新的文件(extStorageAppBasePath.getAbsolutePath()+                    文件分割符+缓存);                布尔isCachePathAvailable =真;                如果(!extStorageAppCachePath.exists())                {                    //创建在外部存储器中的高速缓存路径                    isCachePathAvailable = extStorageAppCachePath.mkdirs();                }                如果(!isCachePathAvailable)                {                    //无法创建缓存路径                    extStorageAppCachePath = NULL;                }            }        }    } //的onCreate结束    @覆盖    公共文件getCacheDir()    {        //注意:此方法是在Android 2.2及更高版本时        如果(extStorageAppCachePath!= NULL)        {            //使用外部存储高速缓存            Log.e(TAGextStorageAppCachePath =+ extStorageAppCachePath);            返回extStorageAppCachePath;        }        其他        {            // /data/data/com.devahead.androidwebviewcacheonsd/cache            返回super.getCacheDir();        }    }} 

。这是当应用程序在联机模式下首次加载日志

  8月2日至16日:38:52.744:I /非优质(8871):其中,CallBackProxy>发送到WebViewClient。8月2日至16日:38:56.314:D / Skia的(8871):-----开始:[1 325] http://www.bmimobile.co.uk/images/mobile/bg-index.png8月2日至16日:38:56.499:D / Skia的(8871):-----开始:[1 64] http://www.bmimobile.co.uk/CubeCore/modules/cubeMobile/images/bg-black -bar.png8月2日至16日:38:56.509:D / Skia的(8871):-----开始:[26 20] http://www.bmimobile.co.uk/images/mobile/home-icon.png8月2日至16日:38:56.529:D / Skia的(8871):-----开始:[275 189] http://www.bmimobile.co.uk/images/mobile/home-img.png8月2日至16日:38:56.549:D / Skia的(8871):-----开始:[320 450] http://www.bmimobile.co.uk/images/mobile/welcome/bg-welcome.jpg8月2日至16日:38:56.554:D / Skia的(8871):-----开始:[270 38] http://www.bmimobile.co.uk/images/mobile/welcome/next.png8月2日至16日:38:56.584:D / Skia的(8871):-----开始:[16 17] http://www.bmimobile.co.uk/images/mobile/why.png8月2日至16日:38:56.584:D / Skia的(8871):-----开始:[18 17] http://www.bmimobile.co.uk/images/mobile/services.png8月2日至16日:38:56.584:D / Skia的(8871):-----开始:[20 15] http://www.bmimobile.co.uk/images/mobile/visit.png8月2日至16日:38:56.589:D / Skia的(8871):-----开始:[20 15] http://www.bmimobile.co.uk/images/mobile/consultants.png8月2日至16日:38:56.589:D / Skia的(8871):-----开始:[13 19] http://www.bmimobile.co.uk/images/mobile/contact.png 

这是当我出来的应用程序关闭的网络适配器,然后回去到应用程序在离线模式下记录。

  8月2日至16日:41:37.799:E / MainActivity(8871):在onResume在mainactivity8月2日至16日:41:37.804:E / ApplicationExt(8871):extStorageAppCachePath = /storage/sdcard0/Android/data/uk.bmi.mobile/cache8月2日至16日:41:37.804:E / MainActivity(8871):appCachePath = /storage/sdcard0/Android/data/uk.bmi.mobile/cache8月2日至16日:41:37.834:W / dalvikvm(8871):disableGcForExternalAlloc:假的 

其实上的日志记录的仔细检查,这似乎在联机模式下加载时发生了变化。下面是在omline模式logcat的。似乎有与高速缓冲存储器的一个问题。

  02-19 15:16:10.497:E / ApplicationExt(5467):内appext02-19 15:16:10.687:E / ApplicationExt(5467):extStorageAppCachePath = /storage/sdcard0/Android/data/uk.bmi.mobile/cache02-19 15:16:10.722:E / MainActivity(5467):在中的onCreate mainactivity02-19 15:16:10.727:E / MainActivity(5467):在onResume在mainactivity02-19 15:16:10.737:E / ApplicationExt(5467):extStorageAppCachePath = /storage/sdcard0/Android/data/uk.bmi.mobile/cache02-19 15:16:10.737:E / MainActivity(5467):appCachePath = /storage/sdcard0/Android/data/uk.bmi.mobile/cache02-19 15:16:10.792:E /(5467):文件/data/data/com.nvidia.NvCPLSvc/files/driverlist.txt:未找到!02-19 15:16:10.792:I /(5467):试图加载EGL实施方式/系统/ lib目录// EGL / libEGL_tegra_impl02-19 15:16:10.807:I /(5467):加载EGL实施方式/系统/ lib目录// EGL / libEGL_tegra_impl02-19 15:16:10.842:I /(5467):加载GLESv2实施方式/系统/ lib目录// EGL / libGLESv2_tegra_impl02-19 15:16:10.882:E / SQLiteLog(5467):(1)没有这样的表:CacheGroups02-19 15:16:10.882:D / WebKit的(5467):错误:02-19 15:16:10.882:D / WebKit的(5467):应用程序缓存存储:无法执行语句DELETE FROM CacheGroups错误没有这样的表:CacheGroups02-19 15:16:10.882:D / WebKit的(5467):外部/ WebKit的/来源/ WebCore的/装载机/应用程序缓存/ ApplicationCacheStorage.cpp(558):BOOL的We​​bCore :: ApplicationCacheStorage :: executeSQLCommand(常量WTF ::字符串&安培; )02-19 15:16:10.882:E / SQLiteLog(5467):(1)没有这样的表:缓存02-19 15:16:10.882:D / WebKit的(5467):错误:02-19 15:16:10.882:D / WebKit的(5467):应用程序缓存存储:无法执行语句DELETE FROM高速缓存错误没有这样的表:高速缓存02-19 15:16:10.882:D / WebKit的(5467):外部/ WebKit的/来源/ WebCore的/装载机/应用程序缓存/ ApplicationCacheStorage.cpp(558):BOOL的We​​bCore :: ApplicationCacheStorage :: executeSQLCommand(常量WTF ::字符串&安培; )02-19 15:16:10.882:E / SQLiteLog(5467):(1)没有这样的表:起源02-19 15:16:10.882:D / WebKit的(5467):错误:02-19 15:16:10.882:D / WebKit的(5467):应用程序缓存存储:无法执行语句DELETE FROM起源错误没有这样的表:起源02-19 15:16:10.882:D / WebKit的(5467):外部/ WebKit的/来源/ WebCore的/装载机/应用程序缓存/ ApplicationCacheStorage.cpp(558):BOOL的We​​bCore :: ApplicationCacheStorage :: executeSQLCommand(常量WTF ::字符串&安培; )02-19 15:16:10.882:E / SQLiteLog(5467):(1)没有这样的表:DeletedCacheResources02-19 15:16:10.992:E / ApplicationExt(5467):extStorageAppCachePath = /storage/sdcard0/Android/data/uk.bmi.mobile/cache02-19 15:16:11.022:W / dalvikvm(5467):disableGcForExternalAlloc:假的02-19 15:16:13.787的:I /非优质(5467):或其可CallBackProxy>发送到WebViewClient。02-19 15:16:21.427:D / Skia的(5467):-----开始:[1 325] http://www.bmimobile.co.uk/images/mobile/bg-index.png02-19 15:16:21.517:D / Skia的(5467):-----开始:[1 64] http://www.bmimobile.co.uk/CubeCore/modules/cubeMobile/images/bg-black -bar.png02-19 15:16:21.542:D / Skia的(5467):-----开始:[26 20] http://www.bmimobile.co.uk/images/mobile/home-icon.png02-19 15:16:21.577:D / Skia的(5467):-----开始:[275 189] http://www.bmimobile.co.uk/images/mobile/home-img.png02-19 15:16:21.597:D / Skia的(5467):-----开始:[270 38] http://www.bmimobile.co.uk/images/mobile/welcome/next.png02-19 15:16:21.677:D / Skia的(5467):-----开始:[16 17] http://www.bmimobile.co.uk/images/mobile/why.png02-19 15:16:21.677:D / Skia的(5467):-----开始:[20 15] http://www.bmimobile.co.uk/images/mobile/visit.png02-19 15:16:21.677:D / Skia的(5467):-----开始:[18 17] http://www.bmimobile.co.uk/images/mobile/services.png02-19 15:16:21.687:D / Skia的(5467):-----开始:[20 15] http://www.bmimobile.co.uk/images/mobile/consultants.png02-19 15:16:21.687:D / Skia的(5467):-----开始:[13 19] http://www.bmimobile.co.uk/images/mobile/contact.png02-19 15:16:21.692:D / Skia的(5467):-----开始:[320 450] http://www.bmimobile.co.uk/images/mobile/welcome/bg-welcome.jpg 

[注意事项]如果我在为什么-BMI按钮,在联机模式下时,单击然后出来的应用程序,打开关闭适配器然后单击为什么-BMI按钮重新然后显示错误载入页面的消息。

如果我不过切换到以下网址,显示我的SO页面。如果我点击链接到我的赏金页(此页),然后下线去了,SO页面显示你所期望的,但如果你点击在离线模式下赏金链接,然后它不显示。所以有SO站点和BMI网站之间的差异。

 如果(isNetworkAvailable()==真){            。webView.getSettings()setSupportZoom(真);            。webView.getSettings()setBuiltInZoomControls(真);            webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);            webView.setScrollbarFadingEnabled(真);            。webView.getSettings()setLoadsImagesAutomatically(真);            webView.getSettings()setDomStorageEnabled(真)。            webView.getSettings()setAppCacheEnabled(真)。            //设置缓存大小为8 MB默认情况下。应该是绰绰有余            webView.getSettings()setAppCacheMaxSize(1024 * 1024 * 8)。            //这下一个是疯了。这对您的应用程序缓存的默认位置            //但是,这并不适合我没有这条线的工作。            //更新:没有硬性codeD路径。由于凯文·霍金斯            字符串appCachePath = getApplicationContext()getCacheDir()getAbsolutePath()。            Log.e(TAGappCachePath =+ appCachePath);            webView.getSettings()setAppCachePath(appCachePath)。            。webView.getSettings()setAllowFileAccess(真);            webView.getSettings()setJavaScriptEnabled(真)。            //加载的URL web视图内,而不是在外部Web浏览器            webView.setWebViewClient(新WebViewClient());            。webView.getSettings()setCacheMode(WebSettings.LOAD_DEFAULT);            //webView.loadUrl(\"http://www.bmimobile.co.uk/why-bmi.php,getHeaders());            //webView.loadUrl(\"http://www.bmimobile.co.uk/,getHeaders());            webView.loadUrl(http://stackoverflow.com/users/532462/turtleboy?tab=bounties);            webView.loadUrl(http://stackoverflow.com/users/532462/turtleboy);            }其他{                。webView.getSettings()setSupportZoom(真);                。webView.getSettings()setBuiltInZoomControls(真);                webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);                webView.setScrollbarFadingEnabled(真);                。webView.getSettings()setLoadsImagesAutomatically(真);                webView.getSettings()setDomStorageEnabled(真)。                webView.getSettings()setAppCacheEnabled(真)。                //设置缓存大小为8 MB默认情况下。应该是绰绰有余                webView.getSettings()setAppCacheMaxSize(1024 * 1024 * 8)。                //这下一个是疯了。这对您的应用程序缓存的默认位置                //但是,这并不适合我没有这条线的工作。                //更新:没有硬性codeD路径。由于凯文·霍金斯                字符串appCachePath = getApplicationContext()getCacheDir()getAbsolutePath()。                Log.e(TAGappCachePath =+ appCachePath);                webView.getSettings()setAppCachePath(appCachePath)。                。webView.getSettings()setAllowFileAccess(真);                webView.getSettings()setJavaScriptEnabled(真)。                //加载的URL web视图内,而不是在外部Web浏览器                webView.setWebViewClient(新WebViewClient());                。webView.getSettings()setCacheMode(WebSettings.LOAD_CACHE_ONLY);               // webView.loadUrl(http://www.bmimobile.co.uk/,getHeaders());                webView.loadUrl(http://stackoverflow.com/users/532462/turtleboy);            }    } 

 <?XML版本=1.0编码=UTF-8&GT?;    <清单的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android        包=uk.bmi.mobile        安卓版code =5        机器人:=的versionName1.0.4>        <! -  GCM需要使用Android SDK 2.2版本(API等级< IMG SRC =htt​​p://www.androidhive.info/wp-includes/images/smilies/icon_cool.gifALT =8)级= WP-笑脸>或以上。 - >        <用途-SDK            安卓的minSdkVersion =8            机器人:targetSdkVersion =16/>        <! -  GCM连接到Internet服务。 - >        <使用许可权的android:NAME =android.permission.INTERNET对/>        <! -  GCM需要一个谷歌帐户。 - >        <使用许可权的android:NAME =android.permission.GET_ACCOUNTS/>        <! - 从睡眠收到消息时保持处理器。 - >        <使用许可权的android:NAME =android.permission.WAKE_LOCK/>        <! - 创建一个自定义权限所以只有这个程序可以接收它的消息。 - >        <许可            机器人:名字=uk.bmi.mobile.permission.C2D_MESSAGE            安卓的ProtectionLevel =签名/>        <使用许可权的android:NAME =uk.bmi.mobile.permission.C2D_MESSAGE/>        <! - 这个程序有权限注册和接收数据信息。 - >        <使用许可权的android:NAME =com.google.android.c2dm.permission.RECEIVE/>        <! - 网络状态的权限来检测网络状态 - >        <使用许可权的android:NAME =android.permission.ACCESS_NETWORK_STATE/>        <! - 许可振动 - >        <使用许可权的android:NAME =android.permission.VIBRATE/>    <使用许可权的android:NAME =android.permisson.ACCESS_WIFI_STATE/>    <使用许可权的android:NAME =android.permission.WRITE_EXTERNAL_STORAG​​E/><使用许可权的android:NAME =android.permission.READ_EXTERNAL_STORAG​​E/>        <! - 主要活动。 - >        <应用            机器人:图标=@绘制/ bmi_icon            机器人:标签=@字符串/ APP_NAME            机器人:名字=uk.bmi.mobile.ApplicationExt>            <! - 注册活动 - >            <活动                机器人:名字=。RegisterActivity                机器人:标签=@字符串/ APP_NAME>                &所述;意图滤光器>                    <作用机器人:名字=android.intent.action.MAIN/>                    <类机器人:名字=android.intent.category.LAUNCHER/>                &所述; /意图滤光器>            < /活性GT;            <! - 主要活动 - >            <活动                机器人:名字=uk.bmi.mobile.MainActivity                机器人:configChanges =方向| keyboardHidden                机器人:标签=@字符串/ APP_NAME                 机器人:screenOrientation =肖像>            < /活性GT;            <接收                机器人:名字=com.google.android.gcm.GCMBroadcastReceiver                机器人:权限=com.google.android.c2dm.permission.SEND>                &所述;意图滤光器>                    <! - 收到实际的消息。 - >                    <作用机器人:名字=com.google.android.c2dm.intent.RECEIVE/>                    <! - 收到的注册ID。 - >                    <作用机器人:名字=com.google.android.c2dm.intent.REGISTRATION/>                    <类机器人:名字=uk.bmi.mobile/>                &所述; /意图滤光器>            < /接收器>            <服务机器人:名字=uk.bmi.mobile.GCMIntentService/>        < /用途>    < /清单> 

解决方案

这是不准确的回答你的问题,因为你是问的WebView缓存。但是,它可以达到同样的效果。

  //从网页页面保存到文件档案文件=新的文件(this.getExternalFilesDir(空),fileName.html);FileUtils.copyURLToFile(新URL(http://www.bmimobile.co.uk/why-bmi.php),文件);//加载web视图中保存的文件webview.loadUrl(文件://+ file.getPath()); 

这是一个更加灵活的方法,因为你有过载控制,节约,等等。

I have an Android app that simply houses a website. I would like the app to cache the pages of the website for offline use.

I'm doing a simple test to see if the cache is working but unfortunately it is failing to load a page i have previously loaded in online mode, when offline. To make things clearer i load the following 2 pages when in online mode.

webView.loadUrl("http://www.bmimobile.co.uk/why-bmi.php", getHeaders());
webView.loadUrl("http://www.bmimobile.co.uk/", getHeaders());

.

I am hoping that the "why-bmi.php" page is loaded into the cache as well as the subsequent page http://www.bmimobile.co.uk/. The latter page has a link on it which refers to the first page. If i then come out of the app and turn the network adapter off then go back into the app the "http://www.bmimobile.co.uk/" page DOES display but when i click the "why-bmi" link that page DOES NOT display. I short toast message displays saying "error loading page".

Can anyone tell me why the webview is not caching loaded page for later offline use?

Here's the main activity and i've extended the Application object defining the appcachepath.

Thanks in advance

Matt

package uk.bmi.mobile;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.util.Log;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;



public class MainActivity extends Activity {


    private WebView webView;
    private static final String TAG = MainActivity.class.getSimpleName();
    ApplicationExt bmiAppObj;


    //instruct server to set it's headers to make resources cachable
    private Map<String, String> getHeaders() {
        Map<String, String> headers = new HashMap<String, String>();
        headers.put("IS_ALEX_APP", "1");
        return headers;
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.e(TAG, "in onCreate in mainactivity");



    }      //end of oncreate


    private boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null;
    }



    @Override
    protected void onResume() {
        super.onResume();

        Log.e(TAG, "in onResume in mainactivity");
        webView = (WebView)findViewById(R.id.webView1);
        bmiAppObj = (ApplicationExt)getApplication();


        if(isNetworkAvailable() == true){

            webView.getSettings().setSupportZoom(true);
            webView.getSettings().setBuiltInZoomControls(true);
            webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
            webView.setScrollbarFadingEnabled(true);
            webView.getSettings().setLoadsImagesAutomatically(true);
            webView.getSettings().setDomStorageEnabled(true);
            webView.getSettings().setAppCacheEnabled(true);
            // Set cache size to 8 mb by default. should be more than enough
            webView.getSettings().setAppCacheMaxSize(1024*1024*8);
            // This next one is crazy. It's the DEFAULT location for your app's cache
            // But it didn't work for me without this line.
            // UPDATE: no hardcoded path. Thanks to Kevin Hawkins
            String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath();
            Log.e(TAG, "appCachePath = " + appCachePath);
            webView.getSettings().setAppCachePath(appCachePath);
            webView.getSettings().setAllowFileAccess(true);

            webView.getSettings().setJavaScriptEnabled(true);

            // Load the URLs inside the WebView, not in the external web browser
            webView.setWebViewClient(new WebViewClient());  
            webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);


            webView.loadUrl("http://www.bmimobile.co.uk/why-bmi.php", getHeaders());
            webView.loadUrl("http://www.bmimobile.co.uk/", getHeaders());


            }else{

                webView.getSettings().setSupportZoom(true);
                webView.getSettings().setBuiltInZoomControls(true);
                webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
                webView.setScrollbarFadingEnabled(true);
                webView.getSettings().setLoadsImagesAutomatically(true);
                webView.getSettings().setDomStorageEnabled(true);
                webView.getSettings().setAppCacheEnabled(true);
                // Set cache size to 8 mb by default. should be more than enough
                webView.getSettings().setAppCacheMaxSize(1024*1024*8);
                // This next one is crazy. It's the DEFAULT location for your app's cache
                // But it didn't work for me without this line.
                // UPDATE: no hardcoded path. Thanks to Kevin Hawkins
                String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath();
                Log.e(TAG, "appCachePath = " + appCachePath);
                webView.getSettings().setAppCachePath(appCachePath);
                webView.getSettings().setAllowFileAccess(true);

                webView.getSettings().setJavaScriptEnabled(true);



                // Load the URLs inside the WebView, not in the external web browser
                webView.setWebViewClient(new WebViewClient());  



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

                webView.loadUrl("http://www.bmimobile.co.uk/", getHeaders());


            }


    }






    @Override
    public File getCacheDir()
    {
        // NOTE: this method is used in Android 2.1
        Log.e(TAG, "getcachedir");
        return getApplicationContext().getCacheDir();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState)
    {
        super.onSaveInstanceState(outState);

        // Save the state of the WebView
        webView.saveState(outState);
    }

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

        // Restore the state of the WebView
        webView.restoreState(savedInstanceState);
    }



}//end of mainActivity

.

package uk.bmi.mobile;

import java.io.File;

import android.app.Application;
import android.os.Environment;
import android.util.Log;

public class ApplicationExt extends Application
{
    private static final String TAG = ApplicationExt.class.getSimpleName();
    // NOTE: the content of this path will be deleted
    //       when the application is uninstalled (Android 2.2 and higher)
    protected File extStorageAppBasePath;

    protected File extStorageAppCachePath;

    Webservice webservice;
    BmiDB bmiDb;

    @Override
    public void onCreate()
    {
        super.onCreate();
         Log.e(TAG, "inside appext");

         webservice = new Webservice(this);
         bmiDb = new BmiDB(this);
        // Check if the external storage is writeable
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
        {

            // Retrieve the base path for the application in the external storage
            File externalStorageDir = Environment.getExternalStorageDirectory();

            if (externalStorageDir != null)
            {
                // {SD_PATH}/Android/data/com.devahead.androidwebviewcacheonsd
                extStorageAppBasePath = new File(externalStorageDir.getAbsolutePath() +
                    File.separator + "Android" + File.separator + "data" +
                    File.separator + getPackageName());
            }

            if (extStorageAppBasePath != null)
            {
                // {SD_PATH}/Android/data/com.devahead.androidwebviewcacheonsd/cache
                extStorageAppCachePath = new File(extStorageAppBasePath.getAbsolutePath() +
                    File.separator + "cache");

                boolean isCachePathAvailable = true;

                if (!extStorageAppCachePath.exists())
                {
                    // Create the cache path on the external storage
                    isCachePathAvailable = extStorageAppCachePath.mkdirs();
                }

                if (!isCachePathAvailable)
                {
                    // Unable to create the cache path
                    extStorageAppCachePath = null;
                }
            }
        }
    }//end of onCreate

    @Override
    public File getCacheDir()
    {
        // NOTE: this method is used in Android 2.2 and higher

        if (extStorageAppCachePath != null)
        {
            // Use the external storage for the cache
            Log.e(TAG, "extStorageAppCachePath = " + extStorageAppCachePath);
            return extStorageAppCachePath;
        }
        else
        {
            // /data/data/com.devahead.androidwebviewcacheonsd/cache
            return super.getCacheDir();
        }
    }
}

.This is the logging when the app is first loaded in online mode

02-16 08:38:52.744: I/NONPRIME(8871): <CallBackProxy> Send to WebViewClient.
02-16 08:38:56.314: D/skia(8871): ----- started: [1 325] http://www.bmimobile.co.uk/images/mobile/bg-index.png
02-16 08:38:56.499: D/skia(8871): ----- started: [1 64] http://www.bmimobile.co.uk/CubeCore/modules/cubeMobile/images/bg-black-bar.png
02-16 08:38:56.509: D/skia(8871): ----- started: [26 20] http://www.bmimobile.co.uk/images/mobile/home-icon.png
02-16 08:38:56.529: D/skia(8871): ----- started: [275 189] http://www.bmimobile.co.uk/images/mobile/home-img.png
02-16 08:38:56.549: D/skia(8871): ----- started: [320 450] http://www.bmimobile.co.uk/images/mobile/welcome/bg-welcome.jpg
02-16 08:38:56.554: D/skia(8871): ----- started: [270 38] http://www.bmimobile.co.uk/images/mobile/welcome/next.png
02-16 08:38:56.584: D/skia(8871): ----- started: [16 17] http://www.bmimobile.co.uk/images/mobile/why.png
02-16 08:38:56.584: D/skia(8871): ----- started: [18 17] http://www.bmimobile.co.uk/images/mobile/services.png
02-16 08:38:56.584: D/skia(8871): ----- started: [20 15] http://www.bmimobile.co.uk/images/mobile/visit.png
02-16 08:38:56.589: D/skia(8871): ----- started: [20 15] http://www.bmimobile.co.uk/images/mobile/consultants.png
02-16 08:38:56.589: D/skia(8871): ----- started: [13 19] http://www.bmimobile.co.uk/images/mobile/contact.png

.

This is the logging when i've come out of the app turned off the network adapter then gone back into app in offline mode.

02-16 08:41:37.799: E/MainActivity(8871): in onResume in mainactivity
02-16 08:41:37.804: E/ApplicationExt(8871): extStorageAppCachePath = /storage/sdcard0/Android/data/uk.bmi.mobile/cache
02-16 08:41:37.804: E/MainActivity(8871): appCachePath = /storage/sdcard0/Android/data/uk.bmi.mobile/cache
02-16 08:41:37.834: W/dalvikvm(8871): disableGcForExternalAlloc: false

[edit1] Actually on closer inspection of the logging, it seems to have changed when loaded in online mode. below is the logcat in omline mode. There seems to be a problem with the cache storage.

02-19 15:16:10.497: E/ApplicationExt(5467): inside appext
02-19 15:16:10.687: E/ApplicationExt(5467): extStorageAppCachePath = /storage/sdcard0/Android/data/uk.bmi.mobile/cache
02-19 15:16:10.722: E/MainActivity(5467): in onCreate in mainactivity
02-19 15:16:10.727: E/MainActivity(5467): in onResume in mainactivity
02-19 15:16:10.737: E/ApplicationExt(5467): extStorageAppCachePath = /storage/sdcard0/Android/data/uk.bmi.mobile/cache
02-19 15:16:10.737: E/MainActivity(5467): appCachePath = /storage/sdcard0/Android/data/uk.bmi.mobile/cache
02-19 15:16:10.792: E/(5467): file /data/data/com.nvidia.NvCPLSvc/files/driverlist.txt: not found!
02-19 15:16:10.792: I/(5467): Attempting to load EGL implementation /system/lib//egl/libEGL_tegra_impl
02-19 15:16:10.807: I/(5467): Loaded EGL implementation /system/lib//egl/libEGL_tegra_impl
02-19 15:16:10.842: I/(5467): Loading GLESv2 implementation /system/lib//egl/libGLESv2_tegra_impl
02-19 15:16:10.882: E/SQLiteLog(5467): (1) no such table: CacheGroups
02-19 15:16:10.882: D/WebKit(5467): ERROR: 
02-19 15:16:10.882: D/WebKit(5467): Application Cache Storage: failed to execute statement "DELETE FROM CacheGroups" error "no such table: CacheGroups"
02-19 15:16:10.882: D/WebKit(5467): external/webkit/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp(558) : bool WebCore::ApplicationCacheStorage::executeSQLCommand(const WTF::String&)
02-19 15:16:10.882: E/SQLiteLog(5467): (1) no such table: Caches
02-19 15:16:10.882: D/WebKit(5467): ERROR: 
02-19 15:16:10.882: D/WebKit(5467): Application Cache Storage: failed to execute statement "DELETE FROM Caches" error "no such table: Caches"
02-19 15:16:10.882: D/WebKit(5467): external/webkit/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp(558) : bool WebCore::ApplicationCacheStorage::executeSQLCommand(const WTF::String&)
02-19 15:16:10.882: E/SQLiteLog(5467): (1) no such table: Origins
02-19 15:16:10.882: D/WebKit(5467): ERROR: 
02-19 15:16:10.882: D/WebKit(5467): Application Cache Storage: failed to execute statement "DELETE FROM Origins" error "no such table: Origins"
02-19 15:16:10.882: D/WebKit(5467): external/webkit/Source/WebCore/loader/appcache/ApplicationCacheStorage.cpp(558) : bool WebCore::ApplicationCacheStorage::executeSQLCommand(const WTF::String&)
02-19 15:16:10.882: E/SQLiteLog(5467): (1) no such table: DeletedCacheResources
02-19 15:16:10.992: E/ApplicationExt(5467): extStorageAppCachePath = /storage/sdcard0/Android/data/uk.bmi.mobile/cache
02-19 15:16:11.022: W/dalvikvm(5467): disableGcForExternalAlloc: false
02-19 15:16:13.787: I/NONPRIME(5467): <CallBackProxy> Send to WebViewClient.
02-19 15:16:21.427: D/skia(5467): ----- started: [1 325] http://www.bmimobile.co.uk/images/mobile/bg-index.png
02-19 15:16:21.517: D/skia(5467): ----- started: [1 64] http://www.bmimobile.co.uk/CubeCore/modules/cubeMobile/images/bg-black-bar.png
02-19 15:16:21.542: D/skia(5467): ----- started: [26 20] http://www.bmimobile.co.uk/images/mobile/home-icon.png
02-19 15:16:21.577: D/skia(5467): ----- started: [275 189] http://www.bmimobile.co.uk/images/mobile/home-img.png
02-19 15:16:21.597: D/skia(5467): ----- started: [270 38] http://www.bmimobile.co.uk/images/mobile/welcome/next.png
02-19 15:16:21.677: D/skia(5467): ----- started: [16 17] http://www.bmimobile.co.uk/images/mobile/why.png
02-19 15:16:21.677: D/skia(5467): ----- started: [20 15] http://www.bmimobile.co.uk/images/mobile/visit.png
02-19 15:16:21.677: D/skia(5467): ----- started: [18 17] http://www.bmimobile.co.uk/images/mobile/services.png
02-19 15:16:21.687: D/skia(5467): ----- started: [20 15] http://www.bmimobile.co.uk/images/mobile/consultants.png
02-19 15:16:21.687: D/skia(5467): ----- started: [13 19] http://www.bmimobile.co.uk/images/mobile/contact.png
02-19 15:16:21.692: D/skia(5467): ----- started: [320 450] http://www.bmimobile.co.uk/images/mobile/welcome/bg-welcome.jpg

.

[notes] if i click on the why-bmi button when in online mode then come out of the app, turn the adapter off then click the why-bmi button again then it shows the "error loading page" message.

If i however change to the following urls, my SO page is displayed. If i click the link to my bounty page(this page), then go offline, the SO page is display as you would expect but if you click the bounty link in offline mode then it DOES display. so there are differences between the SO site and the bmi site.

if(isNetworkAvailable() == true){

            webView.getSettings().setSupportZoom(true);
            webView.getSettings().setBuiltInZoomControls(true);
            webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
            webView.setScrollbarFadingEnabled(true);
            webView.getSettings().setLoadsImagesAutomatically(true);
            webView.getSettings().setDomStorageEnabled(true);
            webView.getSettings().setAppCacheEnabled(true);
            // Set cache size to 8 mb by default. should be more than enough
            webView.getSettings().setAppCacheMaxSize(1024*1024*8);
            // This next one is crazy. It's the DEFAULT location for your app's cache
            // But it didn't work for me without this line.
            // UPDATE: no hardcoded path. Thanks to Kevin Hawkins
            String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath();
            Log.e(TAG, "appCachePath = " + appCachePath);
            webView.getSettings().setAppCachePath(appCachePath);
            webView.getSettings().setAllowFileAccess(true);

            webView.getSettings().setJavaScriptEnabled(true);

            // Load the URLs inside the WebView, not in the external web browser
            webView.setWebViewClient(new WebViewClient());  
            webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);


            //webView.loadUrl("http://www.bmimobile.co.uk/why-bmi.php", getHeaders());
            //webView.loadUrl("http://www.bmimobile.co.uk/", getHeaders());

            webView.loadUrl("http://stackoverflow.com/users/532462/turtleboy?tab=bounties");
            webView.loadUrl("http://stackoverflow.com/users/532462/turtleboy");
            }else{

                webView.getSettings().setSupportZoom(true);
                webView.getSettings().setBuiltInZoomControls(true);
                webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
                webView.setScrollbarFadingEnabled(true);
                webView.getSettings().setLoadsImagesAutomatically(true);
                webView.getSettings().setDomStorageEnabled(true);
                webView.getSettings().setAppCacheEnabled(true);
                // Set cache size to 8 mb by default. should be more than enough
                webView.getSettings().setAppCacheMaxSize(1024*1024*8);
                // This next one is crazy. It's the DEFAULT location for your app's cache
                // But it didn't work for me without this line.
                // UPDATE: no hardcoded path. Thanks to Kevin Hawkins
                String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath();
                Log.e(TAG, "appCachePath = " + appCachePath);
                webView.getSettings().setAppCachePath(appCachePath);
                webView.getSettings().setAllowFileAccess(true);

                webView.getSettings().setJavaScriptEnabled(true);



                // Load the URLs inside the WebView, not in the external web browser
                webView.setWebViewClient(new WebViewClient());  



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

               // webView.loadUrl("http://www.bmimobile.co.uk/", getHeaders());
                webView.loadUrl("http://stackoverflow.com/users/532462/turtleboy");


            }


    }

[edit2]

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="uk.bmi.mobile"
        android:versionCode="5"
        android:versionName="1.0.4" >

        <!-- GCM requires Android SDK version 2.2 (API level <img src="http://www.androidhive.info/wp-includes/images/smilies/icon_cool.gif" alt="8)" class="wp-smiley"> or above. -->
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="16" />

        <!-- GCM connects to Internet Services. -->
        <uses-permission android:name="android.permission.INTERNET" />

        <!-- GCM requires a Google account. -->
        <uses-permission android:name="android.permission.GET_ACCOUNTS" />

        <!-- Keeps the processor from sleeping when a message is received. -->
        <uses-permission android:name="android.permission.WAKE_LOCK" />

        <!-- Creates a custom permission so only this app can receive its messages. -->
        <permission
            android:name="uk.bmi.mobile.permission.C2D_MESSAGE"
            android:protectionLevel="signature" />

        <uses-permission android:name="uk.bmi.mobile.permission.C2D_MESSAGE" />

        <!-- This app has permission to register and receive data message. -->
        <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

        <!-- Network State Permissions to detect Internet status -->
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

        <!-- Permission to vibrate -->
        <uses-permission android:name="android.permission.VIBRATE" />

    <uses-permission android:name="android.permisson.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

        <!-- Main activity. -->
        <application
            android:icon="@drawable/bmi_icon"
            android:label="@string/app_name"
            android:name="uk.bmi.mobile.ApplicationExt" >
            <!-- Register Activity -->
            <activity
                android:name=".RegisterActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />

                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>

            <!-- Main Activity -->
            <activity
                android:name="uk.bmi.mobile.MainActivity"
                android:configChanges="orientation|keyboardHidden"
                android:label="@string/app_name"
                 android:screenOrientation="portrait" >
            </activity>

            <receiver
                android:name="com.google.android.gcm.GCMBroadcastReceiver"
                android:permission="com.google.android.c2dm.permission.SEND" >
                <intent-filter>

                    <!-- Receives the actual messages. -->
                    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                    <!-- Receives the registration id. -->
                    <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

                    <category android:name="uk.bmi.mobile" />
                </intent-filter>
            </receiver>

            <service android:name="uk.bmi.mobile.GCMIntentService" />
        </application>

    </manifest>

解决方案

This is not the exact answer to your question, as you are asking about webview cache. But, it can achieve the same result.

// saving page from web to file 
File file = new File(this.getExternalFilesDir(null), "fileName.html");
FileUtils.copyURLToFile(new URL("http://www.bmimobile.co.uk/why-bmi.php"), file);


// loading saved file in webview
webview.loadUrl("file://" + file.getPath());

This is a more flexible approach, as you have control over loading, saving, and much more.