Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android

Neil Gittens
Neil Gittens
1,826 Points

Webview offline

I have created a webview for my android app.

When there is internet the page loads. When there is no internet there is an error. How can i save the page when it is loaded via an internet connection and to display a locally stored HTML page or graphic when offline.

here is my code so far.

 mwebView = (WebView) rootView.findViewById(R.id.mywebView);
WebSettings webSettings = mwebView.getSettings()        webSettings.setJavaScriptEnabled(true);
mwebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
mwebView.getSettings().setAppCacheEnabled(true);
webSettings.setDomStorageEnabled(true);        webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
webSettings.setUseWideViewPort(true);
webSettings.setSavePassword(true);
webSettings.setSaveFormData(true);
webSettings.setEnableSmoothTransition(true);
mwebView.loadUrl("http://www.google.com");
mwebView.setWebViewClient(new MyWebviewClient());
return rootView;

1 Answer

Hi Neil,

There are a bunch of different items on your agenda (of what you are trying to do)

so I'll try to break things down into modular pieces.

First up - Determining and Monitoring the Connectivity Status.

If you aren't connected to the Internet, or the connection is too slow to complete your download, why bother even waking the device (that could be in a low battery state)?

You'll may wish to peruse this Android developer page which might have some useful information in this regard:

http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html


It looks like your code is trying to load content directly into the Webview component

without any "network awareness" Of internet connectivity state (let alone error handling

for a possible offline state).

I would argue from a UIX (User Interface Experience) that this is less than ideal

and certainly not "robust" by any means.


There are many potential issues to think about when doing a "datasync".

1.) Battery efficiency – The system schedules the sync to run when other syncs run, or when some other network request was already made on the device. This prevents awaking the device from its sleep for performing a single sync.

2.) Interface – All sync adapter on the device can be accessed from the Settings screen, under the account they are tied to. This gives the end user the option to change sync preferences, see if there are any sync problem or even disable the sync.

3.) Content awareness – If we use ContentProvider for accessing/manipulating our data, the sync adapter can observe any changes done to it. That way it can run only when the data **actually **changes.

4.) Retry mechanism – The sync manager has its implementation to retry failed syncs, using timeouts and exponential back offs. All those to conserve battery and sync your data as soon as possible.


As it so happens the Android Developer has several pages on working with "Sync Adapters":

http://developer.android.com/training/sync-adapters/index.html

http://developer.android.com/training/sync-adapters/creating-sync-adapter.html

http://developer.android.com/training/sync-adapters/running-sync-adapter.html

If you are feeling brave you can write your own sync adapter:

http://blog.udinic.com/2013/07/24/write-your-own-android-sync-adapter


In your case there is probably no server authentication involved

(which is required by, and built in to, the sync adapter).

The workaround, if you don't need authentication is to simply use a "stub authenticator":

http://developer.android.com/training/sync-adapters/creating-authenticator.html


All of that I have just described is the "robust" (fully developed way) to handle

internet syncing in an android app (without necessarily going into

using Sqlite for storage locally the html or graphic on the removable SD card,

or internal flash memory, of the Android device).


It should be noted that using the older Android 2.2 and Android 2.3

you can use the trick of invoking a constructor of AsyncTask in the class SyncAdapter

and used Looper.prepare() using code in this stackoverflow page:

http://stackoverflow.com/questions/8890841/how-to-correctly-use-asynctask-during-syncadapter-onperformsync


However, what if you wanted to implement just a "quick and dirty" webview component caching?

For completeness of alternative options (but not recommended),

here are a couple of links for that approach:

http://stackoverflow.com/questions/14670638/webview-load-website-when-online-load-local-file-when-offline

http://web.archive.org/web/20140314001433/http://alex.tapmania.org/2010/11/html5-cache-android-webview.html

http://stackoverflow.com/questions/3787800/loading-cache-when-offline-in-android-webview

http://stackoverflow.com/questions/17959561/android-how-to-prevent-webview-to-load-when-no-internet-connection

http://stackoverflow.com/questions/8911666/storing-a-webview-for-offline-browsing-android

That last stackoverflow thread has a link to:

http://html5demos.com/offlineapp

If you want to explore this topic further I would recommend:

http://www.html5rocks.com/en/tutorials/appcache/beginner/

Hopefully that is enough to get you past the point where your stuck at using your present code..