WebView not reflecting changes on server until clearing data - android-webview

I found an interesting bug that I can not replicate, but think someone here could provide some insight.
I have an activity that for now is partially native, partially web-based. By that I mean one element is simply a WebView until implementation on a native level can be achieved.
When I made a change in the page I am loading, I saw an immediate change using Chrome Developer Tools in a mobile interface. However, I was unable to immediately see the change in my WebView in my MainApp. As a test, I installed a new app that loaded the page in a WebView where I saw the changes. After clearing the data in my MainApp, I was able to see said changes.
I made a few more changes, but now these are being reflected immediately in my WebView (upon backing out of the activity and re-entering).
These are my WebView settings, can you see a reason for me not initially seeing these changes? I'm not very savvy (yet :) ) when dealing with how data is stored in a WebView and want to ensure that updates I make to my webpage are reflected immediately in the app. Thank you!
// Initialize WebView
if (Build.VERSION.SDK_INT >= 19)
mWebView.setWebContentsDebuggingEnabled(false);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
// Hide ProgressBar
mProgressBar.setVisibility(View.GONE);
}
});
final ActionBarActivity activity = this;
mWebView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
// Activities and WebViews measure progress with different scales.
// The progress meter will automatically disappear when we reach 100%
mProgressBar.setProgress(progress);
}
});
// Settings for WebView data
WebSettings ws = mWebView.getSettings();
ws.setSaveFormData(false);
ws.setSavePassword(false); // Not needed for API level 18 or greater (deprecated)

You probably need to disable the cache for your webview. When your data changes you need to reload the webview using mWebView.reload()

In case if you want to reload the the webview every time when you reopen.
use this setting for webview
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
This will not load the cache and the requirement will get fulfilled.

Related

Eclipse RAP multi-window/tab

I would like to have a multi-tab/windowed Eclipse RAP application.
I am able to open a second window using
UrlLauncher launcher = RWT.getClient().getService(UrlLauncher.class);
launcher.openURL("/gasf?foo=other_perspective");
Where I use the foo paramter to select the perspetive I want. However using this method will create a speparate http session, thus the various listeners and so on won't communicate with my first window.
I also tried opening a second window/page using
PlatformUI.getWorkbench().getActiveWorkbenchWindow().openPage("other_perspective" , null);
But this merely changes the current window perspective but does not open a second window or tab in my browser.
Has anyone achieved a multi-tab RAP application with working selectionlisteners between the tabs?
Thanks for any help you can provide
EDIT:
THANKS a lot ralfstx, as you pointed out, I can share the listeners or anything using the shared HTTP session, so far so good. Now the next step is to be able to update a tab based on an external event.
To try my idea of refresh from another tab, I did a dummy timer that does something 2 seconds later (i.e. simulate something triggered from another tab) with:
final ServerPushSession pushSession = new ServerPushSession();
pushSession.start();
Display display = Display.getDefault();
NavigationView navigationView = ((NavigationView) window.getActivePage().findView(NavigationView.ID));
timer.schedule(new TimerTask() {
#Override
public void run() {
display.asyncExec(new Runnable() {
public void run() {
navigationView.doSomething();
}
});
}
}, 2000);
This works! The pushSession.start() forces the UI to refresh without any user interaction. So now the action doSomething() is executed on the navigationView as soon as the 2 seconds are reached.
My only remaining concern is how much load this puts on the server, but its a reasonable solution at least. I validated your answer.
EDIT2:
Just to be complete, to make sure not bump in an invalid Thread access error since we are updating a display from another display, in the doSomething() method we must execute actions using display.asyncExec:
Display display = Display.getCurrent();
public void doSomething() {
display.asyncExec(new Runnable() {
public void run() {
treeViewer.refresh();
}
});
}
With the current architecture of RAP, you can't spread workbench windows over different browser tabs. Every new browser starts a new UISession which implies another Display (see Scopes in RAP).
However, the HttpSession should be the same (unless you have cookies turned off), so you could use this as a means of communicating between different browser tabs.

Detect Wicket user inactivity

Does anybody have an idea on how I can accomplish this using Wicket?
I want to display a Wicket odal window automatically when no user activity has been detected for a certain amount of time. I'm thinking of using an AjaxSelfUpdatingBehavior in some way, but I have no clear ideas actually.
Is this possible with Wicket?
Also, you can use some js library not to catch all ajax calls and to be sure, that your user is really afk (even does not touching his mouse).
For example, see this free framework and it's demo.
And (if you using this js framework) in wicket you must handle
ifvisible.idle(function(){
Wicket.Ajax.get({u: '${callbackUrl}'})// This code will work when page goes into idle status
});
You must set ${callbackUrl} from wicket code to let js know what action to proceed in java code. It is not hard to do this. Look here.
This approach is more tricky, but if you implement this, you don't have to worry about users actions at all (he can read site's info and don't click any ajax links, but suddenly he will see modal window).
Yes you can, I use this as autologout function
public class MyTimer extends AbstractAjaxTimerBehavior {
public MyTimer(int seconds) {
this(Duration.seconds(seconds));
}
#Override
protected void onTimer(AjaxRequestTarget target) {
// show your window magic
}
}
Add this to you page (add(new MyTimer(300));) and this will be called after the number of seconds you specify. Make sure to replace the timer with a new one when doing ajax calls, or reset it.

Reloading an iframe in GWT

I am currently working on a GWT project where I am displaying an HTML file within an iframe in my application. This HTML file is actually being written to as it is getting displayed, and I am hoping to be able to reload the frame so that the changes made to the HTML file are reflected on screen. I am able to do this two different ways that both work when running in development mode, however neither seem to work when the project is deployed.
The first method I tried was setting the frame's URL to itself:
frame.setUrl(frame.getUrl());
The second method I tried using JSNI:
public native void refresh() /*-{
if($doc.getElementById('__reportFrame') != null) {
$doc.getElementById('__reportFrame').src =
$doc.getElementById('__reportFrame').src;
}
}-*/;
When deployed, the frame gets displayed in a Window, and when the file is finished being written to, a call to either of these refresh methods is made, and the frame refreshes to contain the finished HTML file. When I am deployed, the call to refresh does not reload the contents of the frame, however if I bring up the frame's context menu (in Firefox), then go into 'This Frame', and click Reload, it successfully reloads the frame to contain the finished HTML file. I have tested this on multiple versions of Firefox without any luck.
Does anyone have any suggestions? Why would the behavior be different from one mode to the other?
Thanks.
wow, google is really fast with his search^^
You can use some JSNI to do this. Create a method such as
protected native void reloadIFrame(Element iframeEl) /-{
iframeEl.contentWindow.location.reload(true); }-/;
Then call it with your iFrame element
so your question you posted twice was already answerd here
http://groups.google.com/group/google-web-toolkit/browse_thread/thread/64aa7712890652d3
We had a requirement where one GWT application(parent) had another GWT application(child) loaded in an iframe. The child application had to refresh the iframe after it performs certain DB operations. We used JSNI to accomplish the same.
private native void refreshChild(String url)/*-{
$wnd.location.href=url;
}-*/
In case, if the child frame needs to be redirected to another webpage, the url can be modified accordingly.
We did try to use the reload() method, but it did not help.
The above piece of code, of course needs to be written in the child application.

Scroll Event inside Facebook Canvas Applications

I'm looking to use a LazyLoad technique for images and infinite scroll to load new content into my page. Both these things make use of the $(window).scrollTop() function that inside a Facebook canvas application doesn't work. I know i can use FB.Canvas.getPageInfo() to get the current scrollTop value however I'm encountering some performance issues with this, my code is as follows:
var oldScroll = 0; // current scroll
var newScroll = null; // new scroll (fetched from FB.Canvas)
// Override the normal function to work within fb
// !!This seems to kill the browser
$.fn.scrollTop = function() {
return FB.Canvas.getPageInfo().scrollTop;
};
// poll to check for any changes in scroll
setInterval(function() {
newScroll = FB.Canvas.getPageInfo().scrollTop;
if(oldScroll != newScroll) { // have we scrolled at all?
oldScroll = newScroll;
$(window).trigger($.Event('scroll')); // fire a scroll event to keep the rest of the application that is listening
}
}, 1000);
It appears to be fine if i don't override the scrollTop function but once I do my browser soon crashes.
Am i going about this completely wrong? Has someone already created a way to do this inside FB canvas? Cheers.
Im trying to solve the same problem and my solution is a additional element (div#xscroll, pos:abs, L) inside Facebook application + setInterval:
function wininfo() {
FB.Canvas.getPageInfo(
function(info) {
$('#xscroll').height(info.clientHeight+info.offsetTop+info.scrollTop).trigger('scroll');
}
);
};
now you can use this #xscroll for LazyLoad:
$(".img").lazyload({threshold:400,effect:"fadeIn",skip_invisible:true,container:'#xscroll'});
the problem is - huge CPU usage while FB.Canvas.getPageInfo, my interval is 2000 - and CPU usage is hight. After hour of script work - Safari slows down and memoryleaked...
Do you insist on having the scrollTop() function overridden? Originally it works for any element that you supply via the jQuery selector, while you seem to restrict it to only the facebook canvas. If any other javascript tries to use scrollTop(), it will fail miserably, won't it?
As for the solution, I've done infinite scrolling pretty much the same way - setInterval() to see if you've reached the bottom, then load content, then check scroll again, and so on. But I'm not triggering the original scroll event of the window at any time, as there is no need to - at least in my case.

GWT 2.0.3 on IE8 image LoadHandler Not Called intermittently

has anyone encountered a problem where you register a LoadHandler on the image, and when the image is loaded the LoadHandler doesn't get called sometimes? Is there some voodoo to make it work? Like some ridiculous order of initialization? This is driving me nuts.
The code works on Firefox, Chrome, IE6 and IE7. The image is attached to the DOM (I know LoadHandler won't get called if the image is not attached).
Edit
I have reduce the larger code to the following snippet.
private void loadNext() {
if (count < urlList.size())
Image displayImage = new Image();
displayImage.addLoadHandler(new ImageLoadHandler());
displayImage.addErrorHandler(new ImageLoadError());
mainPanel.add(displayImage);
displayImage.setUrl(urlList.get(count));
return;
}
}
private class ImageLoadHandler implements LoadHandler {
public void onLoad(LoadEvent event) {
count ++;
Log.TRACE("Success");
loadNext();
}
}
private class ImageLoadError implements ErrorHandler {
public void onError(ErrorEvent event) {
Log.ALERT("Error");
}
}
So basically this loads images one by one once the previous one has finished loading. The problem that occurs is the first image shows up as red x in IE8 and an error is caught. Now, if I right click on the image and click "show picture" it shows up, and triggers something such that the onLoad event is fired and the rest of the images load without errors! Now all of a sudden onLoad event works, all the other images which are same type are no longer an error.
the urlList is a list of urls to the images. The URL does not contain an extension for image type. The URLs go to a servlet which generate an image. I have taken care to set the proper Content-type headers (image/jpeg) in the response.
Furthermore, if I right click on the broken image, IE8 shows that it doesn't know its type. If I copy the URL, paste it in the address bar, IE loads the image just fine on its own. Now it seems to know the type when it's not in tags.
Very frustrating.
Thanks.
I encountered the same problem, after several days of inspection we found that it is internal bug of IE8 with its image cache. Try to delete complete browser history if it works for the first time. If it is your case then working solution is to add dummyParam to every image URL (with value e.g. new Date().timeInMilis() or something similar). I made this param enabled for user.agent=ie8 only.
I am really afraid of IE9 :(.
It turned out that this is a known GWT Bug.
Updating to GWT 2.1 should solve the problem.