8

(using Samsung Galaxy Tab and Android 3.0, this is intended to work on every 3.0+ tablet, like it does in their browsers, just not webview)

I have a page with CSS and jQuery that loads fine in browsers, android browsers and iOS devices, but android webview refuses to load it consistently.

I've narrowed down the problem to it simply skipping javascript on load (by replicating the problem with some webview javascript demo apps). Why is this?

HERE IS THE COMPLETE TEST HTML CODE http://pastebin.com/GmE2vEYx

and here is how I call it:

  myWebview.loadUrl("file:///android_asset/myPage.html");
  myWebview.getSettings().setJavaScriptEnabled(true);
  myWebview.setWebChromeClient(new WebChromeClient());

The ordering of these three calls doesn't effect the result.

  myWebview.getSettings().setJavaScriptEnabled(true);
  myWebview.setWebChromeClient(new WebChromeClient());
  myWebview.loadUrl("file:///android_asset/myPage.html");

One thing I've noticed is that if you give it time (by pausing the app with a breakpoint in the debugger) then the javascript will more consistently load. This led me to some farfetched experiments of trying to make the app load slower, but this is really not the desired user experience. I'm really hoping that Android webview really aren't the IE6 of mobile development.

Additional facts:

If you remove the <script> tags that contain all of the Jquery, then the page loads quickly with all of the CSS formatting. As soon as the Jquery is added, nothing loads at all.

I have also found several other questions that encounter the exact same problem, many go unanswered or have no conclusive answer to what the OP was seeking :(

see: Android: can't get javascript to work on WebView even with setJavaScriptEnabled(true)

Page reload (Webview.loadUrl) results in Javascript not being (fully) processed

http://groups.google.com/group/android-developers/browse_thread/thread/9962064ef217a5a7#

JavaScript sometimes doesn't work in android's webview

Android WebView not loading a JavaScript file, but Android Browser loads it fine

Android's Webview cannot handle javascript?

suggestions? lets get to the bottom of this! The android documentation says the webview has limitations but I don't know where that limit is, since people make HTML CSS JS apps all the time!

Community
  • 1
  • 1
CQM
  • 42,592
  • 75
  • 224
  • 366
  • 1
    If the JS has errors is should show up in adb logcat, with tag "Web Console" or "WebCore". Do you see any JS errors on your pages? – NoBugs Aug 19 '11 at 00:54

4 Answers4

4

I also have Samsung Galaxy Tab and Android 3.0 with jQuery javascript webpage and it works. Be sure your page is working in Crome browser and that you don't have javascript errors. There are known issues with some CSS3 styling (e.g. images disappearing) but jQuery should work. If you try to communicate with javascript be sure you do it after the page is loaded. Be seure also all files are in the right directory :). Also sometimes the content is cached so try to delete it (or delete the app).

Please provide the source code of your webpage so we can check.

Sample webview:

webView = (WebView) findViewById(R.id.webview);

WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setPluginsEnabled(true);
webSettings.setLoadsImagesAutomatically(true);
webSettings.setSupportZoom(false);

webView.setScrollBarStyle(WebView.SCROLLBARS_INSIDE_OVERLAY);
webView.setWebViewClient(new WebViewClient()
{
    @Override
    public void onPageFinished(WebView view, String url) 
    {
        // page loaded...
        super.onPageFinished(view, url);
    }
});
webView.setWebChromeClient(new WebChromeClient()
{
    @Override
    public boolean onJsAlert(WebView view, String url, String message,JsResult result) 
    {
        Log.e("alert triggered", message);
        return false;         
    }
});
webView.loadUrl("http://mypage/mypage.html");

I hope it helps.

UPDATE1: I tested your code on Samsung Galaxy tab. I changed

<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.2.min.js"></script>

line. The page is loaded, I can see the content with picture. So... the code is working as expected. I noticed that sometimes the content is not displayed as it should be. It seams that the zooming is the problem:

<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, user-scalable=no" />

and the calculation inside $(document).ready() is false!

Btw... what you are looking for is the ViewPager with WebViews.

UPDATE2: Note also when loading webpage as file:/// you have to have JS files in the same directory (no external URLs).

xpepermint
  • 35,055
  • 30
  • 109
  • 163
  • Okay, I've narrowed it down to just a few lines `$('body').css({height : height+'px', width : Math.floor(width*0.98)+'px' }); $('.text').css({height : height+'px', width : Math.floor(width*0.98)+'px' }); $('#firstpage').css({height : height+'px', width : Math.floor(width*0.98)+'px' }); $('body').prepend(''); ` without these, the entire things loads fine, but these lines are vital so I'll be looking into a better way to do the same thing (it puts the page into columns dynamically) – CQM Aug 15 '11 at 22:20
  • Hey... can you please provide a URL? Have you checked it in Crome? Do you get any errors? How do you load the jQuery (where)? – xpepermint Aug 16 '11 at 08:43
  • The URL is provided at the pastebin, you will have to test it on your own machine. The JQuery is loaded locally from the assets folder, Ive confirmed this works because the swipe functions do work. Have checked in Chrome, no errors – CQM Aug 16 '11 at 14:51
  • what do you mean the calculation inside document ready is false? which one? ALSO, where exactly does the meta tag go? above or below the script tag (I'm not getting different results). Can you elaborate on ViewPager with webviews??? – CQM Aug 17 '11 at 18:10
4

The answer is that the javascript needs to be in functions within the HTML page <script>sections and then needs to be injected with webview.loadUrl("javascript:yourJavascriptFunction()") after webview.setWebviewClient(new WebviewClient(){ public void onPageFinishedLoading(){ ...//js injections here });

CQM
  • 42,592
  • 75
  • 224
  • 366
2

I encountered the same problem quite some time ago - my final solution was to ditch jquery and just use plain JS. Things were constantly breaking while they worked fine when viewed from the normal Android-browser.

If those are the only lines that break the code, try reproducing the same functionality of those lines with pure JS. The Android's native webview has a pretty good support for all the latest JS goodies,

so...

$('body').css({height : height+'px', width : Math.floor(width*0.98)+'px' });
$('.text').css({height : height+'px', width : Math.floor(width*0.98)+'px' }); 
$('#firstpage').css({height : height+'px', width : Math.floor(width*0.98)+'px' }); 
$('body').prepend('<style>.text{-moz-column-count:'+numCols+';-webkit-column-count:'+numCols+';}</style>'); 

would be...

var doc = document,
    body = doc.getElementsByTagName('body')[0],
    bodyStyle = body.style,
    firstPage = doc.getElementById('firstpage'),
    firstPageStyle = firstPage.style,

    head = doc.getElementsByTagName('head')[0],
    style = doc.createElement('style'),
    rules = doc.createTextNode('.text{-webkit-column-count:'+numCols+';}');

bodyStyle.height = height + 'px';
bodyStyle.width = Math.floor(width * 0.98) + 'px';

firstPageStyle.height = height + 'px';
bodyStyle.width = Math.floor(width * 0.98) + 'px';

style.type = 'text/css';

if( style.styleSheet )
    style.styleSheet.cssText = rules.nodeValue;
else 
    style.appendChild( rules );

head.appendChild( style );

Just make sure that the above code runs after all the elements used have loaded (after DOM ready state, or before the closing of the tag )

ps. Also since you're using Android's webkit - why is there need for -moz-column-count?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Pantelis
  • 6,086
  • 1
  • 18
  • 21
  • Can you elaborate on how exactly this syntax should work? It all fails on `jslint.com` . My original code has `$(document).ready(function(){....});` and I believe your js version goes within this function, but if I am switching to completely js then I think my function "declaration" would be different now – CQM Aug 17 '11 at 18:09
  • $(document).ready(function(){....}); pretty much ensures that the code enclosed within the anonymus callback of the ready function, will run after tha DOM has loaded. The same effect can be achieved by adding your scripts before the closing of the body tag. The code I shared should work 100% correctly enclosed within document ready, as long as the "width" variabled are set, because those are the only "missing" values. I just translated the jQuery code you posted to regular JS. – Pantelis Aug 17 '11 at 21:21
  • As for jslint, "Problem at line 22 character 5: Expected exactly one space between 'else' and 'style'." and "Problem at line 21 character 1: Expected 'else' at column 5, not column 1." Are for the most parts simple identation errors easily correctable. The only "hazard" is the "width" variable which I believe is already declared in your existing code so there should be no problem there : ) – Pantelis Aug 17 '11 at 21:23
1

I'm not entirely sure if this is the cause of your problem but you should be calling loadUrl after you set up the WebView

Edit

If this isn't the problem, you might consider posting

  • the simplest SSCCE that you find doesn't work but which you feel should
  • the make/model of your device and the version of Android you're working with
no.good.at.coding
  • 20,221
  • 2
  • 60
  • 51
  • @RD Without your actual code it's hard for anyone to take a shot at answering. Also, posting the make/model of the device you're working with might turn up suggestions from someone who has run into a device specific issue before. – no.good.at.coding Aug 13 '11 at 03:03
  • Samsung galaxy tab, but preferabbly all Honeycomb 3.0+ devices – CQM Aug 13 '11 at 06:10