Intereting Posts
OnClickListener на представлениях внутри настраиваемого ScrollView ActivityManager не содержит предупреждения REAL_GET_TASKS CollapsingToolbarLayout не сжимается, когда EditText становится сфокусированным Правильный дизайн кода для Android / Java Android LruCache в Android 1.6+ Как создать локализованное время назад String на Android Сбой панели состояния панели инструментов Google Analytics SDK V2 для Android-приложения: новые пользователи, пользователи, активные пользователи, сеансы меня смущают Как вставить запись SQLite с установленным значением «сейчас» в приложении Android? В чем разница между безголовым фрагментом и службой на Android? Android – контроллер popover аналогичен ipad Android: Как я могу сделать текстовые представления float слева? Как обнаружить прокрутку влево или вправо в Android? Как разработать одно приложение для Android для разных экранов? Поддержание / сохранение / восстановление позиции прокрутки при возврате в ListView

Android WebView не загружает вторую страницу из кеша

У меня есть приложение для Android, в котором просто находится веб-сайт. Я хотел бы, чтобы приложение кэшировало страницы веб-сайта для использования в автономном режиме.

Я делаю простой тест, чтобы проверить, работает ли кеш, но, к сожалению, он не загружает страницу, которую я ранее загружал в онлайн-режиме, когда отключен. Чтобы сделать все более ясным, я загружаю следующие 2 страницы в онлайн-режиме.

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

,

Я надеюсь, что страница «why-bmi.php» загружена в кеш, а также последующую страницу http://www.bmimobile.co.uk/ . На последней странице есть ссылка на нее, которая относится к первой странице. Если я выйду из приложения и выключу сетевой адаптер, вернитесь в приложение, где отображается страница « http://www.bmimobile.co.uk/ », но когда я нажимаю ссылку «why-bmi», которая Страница НЕ отображается. Я показываю короткие сообщения с тостами, говорящие «страница загрузки ошибок».

Может ли кто-нибудь сказать мне, почему веб-просмотр не кэширует загруженную страницу для последующего использования в автономном режиме?

Вот основное действие, и я расширил объект Application, определяющий путь appcachepath.

заранее спасибо

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(); } } } 

. Это регистрация, когда приложение загружается в онлайн-режиме

 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 

,

Это журнал, когда я вышел из приложения, отключил сетевой адаптер, а затем вернулся в приложение в автономном режиме.

 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] Собственно, при ближайшем рассмотрении регистрации, похоже, она изменилась при загрузке в онлайн-режиме. Ниже – logcat в режиме omline. Кажется, что проблема с хранилищем кешей.

 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 

,

[Примечания], если я нажимаю кнопку why-bmi в режиме онлайн, а затем выхожу из приложения, выключите адаптер и снова нажмите кнопку why-bmi, затем отобразите сообщение «страница загрузки ошибки».

Если я, тем не менее, изменяюсь на следующие URL-адреса, отображается моя страница SO. Если я нажму ссылку на мою страницу бонусов (эта страница), а затем откройте ее в автономном режиме, страница SO будет отображаться так, как вы ожидали, но если вы нажмете ссылку «Баунти» в автономном режиме, она появится. Поэтому существуют различия между сайтом SO и сайтом bmi.

 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> 

Это не точный ответ на ваш вопрос, поскольку вы спрашиваете о кеше веб-просмотра. Но он может достичь того же результата.

 // 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()); 

Это более гибкий подход, так как вы контролируете загрузку, экономию и многое другое.

Возможно, решение вашей проблемы состояло бы в том, чтобы запрос HTTP получить вместе с вашей загрузкой веб-браузера.

Результат запроса get может быть сохранен в строке постоянно в sharedpreferences, и это будет HTML, который ваш php отображает.

В вашем жизненном цикле Android вы можете определить, находится ли приложение в автономном режиме, а если он отключен, вы можете загрузить последнюю сохраненную версию сайта из строки

webview.loadData(yourSavedString, "text/html", "UTF-8");

Хотя, если есть изображения, вам нужно будет сделать дополнительные соображения, но если изображения не являются динамическими, вы можете сохранить их в папке с активами приложения и заменить URL-адрес в сохраненной строке местоположениями ресурсов.

Хотя он не решает, почему ваш веб-просмотр не кэшируется, он выполнит ту же конечную цель или просмотрит страницу в автономном режиме

Другой очень гибкий и мощный вариант может использовать HTML5 для управления кэшированием в вашем приложении.

Взгляните на http://diveintohtml5.info/offline.html

Вы можете просто включить кеширование в своем приложении и управлять кешированием с самого веб-сайта.

С наилучшими пожеланиями

Аман Гаутам

Его мало Глупо, что это работает. В URL-адресе есть перенаправление

http://www.bmimobile.co.uk/ http://www.bmimobile.co.uk/index.php

Ты должен попытаться

WebView.loadUrl (« http://www.bmimobile.co.uk/why-bmi.php », getHeaders ()); WebView.loadUrl (" http://www.bmimobile.co.uk/index.php ", getHeaders ());

Бывают случаи, когда WebView нельзя кэшировать изначально. Если заголовок страницы содержит следующие поля, WebView не сможет кэшировать содержимое с этой страницы.

 Cache-Control: no-store, no-cache Pragma: no-cache 

В этом случае вам придется изменить свойство страницы на сервере, чтобы решить проблему кэширования.