I have a WebView in which users can log in to my online service by using other online services.
Logging in works fine on Desktop and the Android Chrome browser, but when I use the WebView in my App, I get a callback stack size exceeded error.
Uncaught RangeError: Maximum call stack size exceeded, source: THE_CALL_BACK_URL
The Webview adds a www prefix to the url, which could probably lead to the URL not being recognized by the OAuth service. Buw how do I remove the www prefixing?
Or could this be cause by something else?
Code:
WebSettings webSettings = webView.getSettings();
webSettings.setJavascriptEnabled(true);
webView.setWebViewClient(new WebVieCient() {
#Override
public boolean onRecievedError(); // Stump for brevity
#Override
public boolean shouldOverrideUrlLoading() // Stump for brevity
// This function handles internal links in WebView and opens external links in standard browser.
// (The function responds to the callback link as an internal link and opens it in the WebView)
EDIT
I have removed the www Prefix and i still get the Maximum call stack error
Related
I'm currently developping an android app for a tablet and I want to cover the use case : "if there is no internet connection, I want the app to run as normal".
I used a webview to load a survey in the app so once installed inside our stores, I won't have to install a new version each time we need a new makeover or add questions.
To cover the case where there is no connection, I save a webArchive that I load if there is no wifi when I need to load the webpage.
private void setMainView() {
mainview = (WebView) findViewById(R.id.wvMain);
WebSettings webSettings = mainview.getSettings();
webSettings.setLightTouchEnabled(true);
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
JavaScriptInterface myJavaScriptInterface = new JavaScriptInterface(this);
mainview.addJavascriptInterface(myJavaScriptInterface, "AndroidFunction");
if (DetectConnection.checkInternetConnection(this)){
mainview.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
File webpage = new File(context.getExternalFilesDir(Environment.DIRECTORY_DCIM).getAbsolutePath()+ File.separator +"home.mht");
mainview.saveWebArchive(webpage.toString());
editor.putString(BuildConfig.HOME_PAGE_WEB_ARCHIVE_FILE,webpage.toString() );
editor.commit();
}
});
mainview.loadUrl(BuildConfig.SERVER_URL + BuildConfig.HOME_PAGE);
}
else{
String filename = getSharedPreferences(BuildConfig.PREFERENCES_NAME, 0).getString(BuildConfig.HOME_PAGE_WEB_ARCHIVE_FILE,null);
mainview.setWebChromeClient(new WebChromeClient());
mainview.loadUrl("file:///"+filename);
}
}
The only problem is that the webarchive froze as soon as it is loaded. I tried many thing to make it works but the solution is escaping me.
When I set my application to plane mode and I reload the app, I see the home page fine but the click events don't work. My Android Javascript interface is also not working as I tested to send Toast to debug when the app is finished loading so I'm guessing the javascript is not working in my webarchive or maybe the webarchive is not including the CSS and Javascript that are from other website such as W3.css and JQuery?
Maybe if I used a local version of these asset they will be included in the webarchive.
Any suggestions would be welcome.
Thanks
I ended up using the cache of my webview instead of loading a web archive.
I first added a cache.appcache a the root of my webpage linking my main page to it.
<html manifest="cache.appcache">
At the root (wwww/http_doc) I added this file :
CACHE MANIFEST
/home
/thank-you
/css/w3.css
/js/jquery-3.3.1.min.js
/images/happy1.png
/images/happy2.png
/favicon.ico
#NETWORK
NETWORK:
/home
/thank-you
#FALLBACK
FALLBACK:
/home /offline.html
/thank-you /offline_thankyou.html
The fallback section allowed to have a html file to fall to if the network is available. I then activated the cache of my webview :
WebSettings webSettings = mainview.getSettings();
webSettings.setAppCacheEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
webSettings.setAppCachePath(
getApplicationContext().getCacheDir().getAbsolutePath());
And now each time, I modified the file "cache.appcache" and reload the application, it take a copy of the current "offline.html" files and reload a working site according to the cache. A good thing I had a very static website to load from so it's 100% functionnal without an internet connection.
I have list of tweets being displayed in my listview. I have setup a listener on my listview which should take the user to the specific tweet.
The listener on my list is as follow:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(TweetActivity.this, WebActivity.class);
intent.putExtra("url", String.valueOf(twitterBaseURL+tweetResult.get(i).getId()));
startActivity(intent);
}
});
Inside my web activity class, I am doing something as follow:
String url = getIntent().getExtras().getString("url");
WebView webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new WebViewClient());
webView.getSettings().setDomStorageEnabled(true);
webView.loadUrl(url);
In the web view it does not load the page like it does in google chrome on a mobile. I think the javascript does not load properly.
UPDATE 1:
I was testing this on an android device with API 21. Inside my android studio I have a virtual device with an API 23. In API 23 this loads everything properly. I created another virtual device with API 21 and tested to double check so the problem is with the API levels. This code works in API 23 to load the url properly inside the web view but does not in API 21?
Enabling JavaScript
JavaScript is disabled in a WebView by default. You can enable it through the WebSettings attached to your WebView. You can retrieve WebSettings with getSettings(), then enable JavaScript with setJavaScriptEnabled().
For example:
WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.loadUrl("file:///android_assets/your_page.html");
Take a look at this, although the issue talking about is react-native.
The last point mentioned there is about try running on a real Android device. And indeed sometimes Android emulator does not work as expected.
So I suggest testing your code on the real android device with API 21 first
I'm building an app that is dependend on WebViews to render HTML-files in the assets folder. These files contain Javascript. The app works perfectly on my own device, including all the Javascript. But the Android emulator from Android Studio executes only some of the Javascript, on some of the pages. And the device from one of the testers shows blank pages instead of the HTML-files. And the device from another one of our testers also doesn't execute all the Javascript properly.
So, I'm not really sure what to do here. All pages are loaded with the exact same WebView-method and most of the Javascript is also similar. I can't debug or release an app that behaves differently on each device.
The code to load the WebViews:
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.addJavascriptInterface(new WebAppInterface(this), "Android");
WebSettings webSettings = myWebView.getSettings();
CookieManager.getInstance().setAcceptCookie(true);
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccessFromFileURLs(true);
webSettings.setAllowUniversalAccessFromFileURLs(true);
webSettings.setAllowFileAccess(true);
webSettings.setAllowContentAccess(true);
webSettings.setDomStorageEnabled(true);
webSettings.setLoadWithOverviewMode(true);
myWebView.setWebChromeClient(new WebChromeClient() {
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
}
});
myWebView.loadUrl("file:///android_asset/www/file.html");
myWebView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
view.loadUrl(request.toString());
return true;
}
});
Once again, the app works perfectly on my own Android device. Even after I reinstalled it. I just don't see why it wouldn't work on other devices. Does someone have a solution or explaination?
I advice you to use the WebView Remote Debugging,so that you can see the source code that running in the WebView of your html fileļ¼and then you can click the web page in you Chrome Browser to see how the page react.
That is the way I took when I met some problem in webview.
all you need to do is just run the following code
if (Build.VERSION.SDK_INT >= 19){
WebView.setWebContentsDebuggingEnabled(true);
}
or you can find more detail about remote-debugging
I have a WebView in an app that loads a specific web page.
On that web page is a button that uses JavaScript to call a method within the Android activity to reload the URL in the WebView (effectively resetting the web app to its default state).
I've got all of the JavaScript interface to Android bit working thanks to a few threads here and I can pop up a Toast to show that the app is about to reload, but I'm getting an error with the WebView.loadUrl() call as follows.
java.lang.RuntimeException: java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. (Expected Looper Looper (main, tid 1) {1d015c84} called on Looper (JavaBridge, tid 122148) {33703881}, FYI main Looper is Looper (main, tid 1) {1d015c84})
I'm guessing that this is because the method that is doing the reload is not within the onCreate method for this activity which does all of the other WebView stuff but I'm not sure if this really is the problem and how to resolve it if it is - as the method that reloads the URL needs to be within the JavascripInterface class to be reachable from within the web-page.
Loading a page in a WebView componenet (or reloading) needs to be done on the UI thread for some reason, so simply wrapping the reload call in runOnUiThread resolves this issue.
#JavascriptInterface
public void reloadSite(){
Toast.makeText(mContext, getString(R.string.reloadingWebApp), Toast.LENGTH_LONG).show();
runOnUiThread(new Runnable() {
#Override
public void run() {
mWebView = (WebView) findViewById(R.id.activity_main_webview);
mWebView.loadUrl(getString(R.string.web_app_url));
}
});
}
I'm trying to debug an Android app that makes heavy use of WebViews to display web pages from within the app.
The problem is simple - when I load the page, there's an anchor on one page that when clicked gives me a 404. The problem, it does this only when running the page from within the app's WebView. If I load the page in a desktop browser, or from within Chrome or from within the Android Browser on the mobile, I load the page just fine.
More confusingly, there's another anchor on the same page with the same basic architecture that's working just fine.
The URL for the anchor is being set via JQuery:
var url = ...;
$('#submitButton').attr('href', url);
When I load the page on a desktop browser, I can see the URL that the anchor points to, and it's correct. When I run the page within an app's WebView, I cannot see the URL that the anchor points to, so when it fails, I don't know why.
I'm currently running the website with VS2013 and IIS Express, with bindings and firewalls set so I can access it off my machine. I'm building the app in Android Studio 1.1.0, and am running the app within a GenyMotion emulator.
Is there any way I can examine the DOM of a web page loaded into a webview, so I can see exactly what URL we're trying to load? Or any way I can debug the javascript that is constructing that URL?
Is there any way I can examine the DOM of a web page loaded into a webview, >so I can see exactly what URL we're trying to load? Or any way I can debug >the javascript that is constructing that URL?
Yes, but maybe not with your current tools.
If you do however have an android device connected to your computer, you can actually easily debug the webviews with chrome on your computer.
See the following for more details :
https://developer.chrome.com/devtools/docs/remote-debugging
It is possible to configure a WebView so that console.log() messages show up in LogCat. You need to set a WebChromeClient on the WebView, then implement onConsoleMessage() in your client. From http://developer.android.com/guide/webapps/debugging.html:
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebChromeClient(new WebChromeClient() {
public void onConsoleMessage(String message, int lineNumber, String sourceID) {
Log.d("MyApplication", message + " -- From line "
+ lineNumber + " of "
+ sourceID);
}
});
That got me far enough to figure out what my problem was - the javascript that initialized the link depended upon LocalStorage, and LocalStorage and SessionStorage aren't enabled, in WebViews, by default. You need to enable it with a call to setDomStorageEnabled(). (You also need to enable javascript, but I'd already been doing that):
WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings settings = myWebView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);