Issue
I have an app that gets an xml file from the network, parses it to retreive paths to webpages of a site i have to cache.eg
/services/orthopaedics.php
. I can successfully download the paths of all the pages that need caching. At the moment i do this in an AsyncTask. The results of the webservice call(paths to pages) are store in a contentsValues in the doInBackground method of the AsyncTask. I then iterate through this contentsvalues in the onPostExecute() method where i can one by one load the webpages in a webview's loadUrl() method. this webview is made invisible as it is only used for caching purposes.
The proble is that as the invisible webview is loading another webview that the user can see and is to display the index page of the site it slow in loading. A white screen appears untill the invisible webview has stopped loading the cache. On a phoe it takes around 4 seconds which IS acceptable, but on a android tablet it takes around 30 seconds.
I know that calls to webview must be on the UI thread and that is why i load the webpages(invisible webview) in the onPostExecute method. Would it be possible to somehow load the pages into the cache in the doInBacground method, but place the webview.loadUrl() inside a runOnUiThread(new Runnable)?
I'll give a simplified sample of what i mean below.
private class AsyncCacheSite extends AsyncTask<String, ContentValues, ContentValues>{
ProgressDialog progressDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.e(TAG, "about to load main page");
webView.loadUrl(mobileWebsiteUrl, getHeaders());
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setTitle("Connecting to Server");
progressDialog.setMessage("Caching website for offline use...");
progressDialog.setIndeterminate(true);
progressDialog.show();
}
@Override
protected ContentValues doInBackground(String... params) {
ContentValues cv = null;
try {
//call the service to get the xml file containing paths
cv = ws.checkForUpdates();
} catch (Exception e) {
e.printStackTrace();
}
//iterate through the xml file geting the paths
.......
.......
.......
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
loadUrlIntoCache(page);
}
})
return null;
}
@Override
protected void onPostExecute(ContentValues result) {
super.onPostExecute(result);
progressDialog.dismiss();
}//end of postExecute
}//end of asyncTask
public void loadUrlIntoCache(String pageUrl){
WebView wv2 = new WebView(MainActivity.this);
wv2.getSettings().setSupportZoom(true);
wv2.getSettings().setBuiltInZoomControls(true);
wv2.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
wv2.setScrollbarFadingEnabled(true);
wv2.getSettings().setLoadsImagesAutomatically(true);
wv2.getSettings().setDomStorageEnabled(true);
wv2.getSettings().setAppCacheEnabled(true);
// Set cache size to 8 mb by default. should be more than enough
wv2.getSettings().setAppCacheMaxSize(1024*1024*32);
// 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();
wv2.getSettings().setAppCachePath(appCachePath);
wv2.getSettings().setAllowFileAccess(true);
wv2.getSettings().setJavaScriptEnabled(true);
// wv2.setWebViewClient(new WebViewClient());
////////////////////////////////////////////////////////////////////////////////////////
/////the webviewclient below is the code you gave me to overcome the redirecting issue//
////////////////////////////////////////////////////////////////////////////////////////
webView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url){
// do your handling codes here, which url is the requested url
// probably you need to open that url rather than redirect:
view.loadUrl(url);
return false; // then it is not handled by default action
}
});
wv2.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
wv2.setVisibility(View.GONE);
wv2.loadUrl(mobileWebsiteUrl + pageUrl, getHeaders());
Log.e(TAG, "loading " + mobileWebsiteUrl + pageUrl);
}
Solution
I think the only solution is to load your data with an http request in doInBackground then use loadData in publishProgress.
Answered By - Guillaume Alouege
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.