I have a Jquery Mobile 1.4 with Jquery 2.0 webpage which I serve in an Android Webview (Android 4+). All worked fine until I started to use SSE. The App periodically crashes due to a Signal 11 on the WebViewCoreThread.
This happens only when navigating from and to pages, and then randomly.
There is no stacktrace, just the Signal 11 at 0x00000000.
This is the javascript code:
if ( typeof (EventSource) !== "undefined") {
// sse
//console.log("sse");
chatnotificationsource = new EventSource("php/process_get_chat_notification.php");
chatnotificationsource.onmessage = function(event) {
var message = event.data;
console.log("got message " + message);
$("#chatnotification").show();
};
}
When I switch off the SSE code there is no problem, so it has clearly to do with the SSE call. I am using the following WebView initialisation.
#SuppressLint("SetJavaScriptEnabled")
protected void createWebView(int webViewId) {
webView = (WebView) findViewById(webViewId);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setPluginState(WebSettings.PluginState.ON);
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setRenderPriority(RenderPriority.HIGH);
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setAppCacheMaxSize(20 * 1024 * 1024); // 20MB
webView.getSettings().setAppCachePath(
getApplicationContext().getCacheDir().getAbsolutePath());
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setAppCacheEnabled(true);
// load online by default
webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
if (!connectionDetector.isConnectingToInternet()) {
// loading offline
webView.getSettings().setCacheMode(
WebSettings.LOAD_CACHE_ELSE_NETWORK);
}
// clients
webView.setWebViewClient(customWebViewClient);
webView.setWebChromeClient(customWebChromeClient);
}
I expect is has something to do with Android navigating to another page while the SSE call is running or "processing".
Thanks for your help,
Coenos
Moving away from SSE in combination with Android WebView fixes the issue. There is no WebView patch/update or workaround for this (yet).
Related
While building a SNS hybrid application, I noticed that the webview gets scrolled nearly twice the distance than the actual gesture distance. This does not happen always, but I could not figure out the condition for this issue. The content of the webview gets extended as I scroll down, so I am suspecting that it is happening when I interact with the webview while the webview itself is loading and the content of the webview is getting extended. The below is the settings of my webview.
ps. once this issue occurs, it does not go away even if you navigate to another page.
iWebViewClient = new IWebViewClient(onActivity);
iWebChromeClient = new IWebChromeClient(onActivity, mContainer, webView, pbar);
webView.setWebViewClient(iWebViewClient);
webView.setWebChromeClient(iWebChromeClient);
webView.setVerticalScrollBarEnabled(false);
// javascript interface
webView.addJavascriptInterface(new WebViewInterface(onActivity), "ApplicationInterface");
WebSettings webSettings = webView.getSettings();
// enable javascript and storage
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setAllowFileAccess(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); // allow new window to open
webSettings.setSupportMultipleWindows(true);
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
// enable css
WebView.setWebContentsDebuggingEnabled(true);
webSettings.setUseWideViewPort(true);
webSettings.setLoadWithOverviewMode(true);
// disable cache
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
// set useragent
String device = "Android " + Build.VERSION.RELEASE;
String appVersion = " " + BuildConfig.APPLICATION_ID + "/" + BuildConfig.VERSION_NAME;
String agentNew = webSettings.getUserAgentString() + appVersion + " (" + device + ")";
webSettings.setUserAgentString(agentNew);
if(initUrl != null){
webView.loadUrl(initUrl);
}else{
webView.loadUrl(HostUrls.webSite);
}
Turns out this only happens when my device is connected to chrome remote device inspection tool.
Once I connected my device to chrome inspection, the scroll speed doubled immediately and vice versa.
In one of the screens in my app, I load HTML string into a WebView, but for some reason, the WebView isn't able to load videos in divs, the video container shows error:
This video file cannot be played: error code 102003
This is an example of the HTML that is being loaded, and which the video in it fails to laod:
<html dir="rtl" lang=""><body><meta itemprop="thumbnailUrl" content="https://cdn.jwplayer.com/v2/media/8K9oJcsX/poster.jpg?width=720"/><meta itemprop="contentUrl" content="https://cdn.jwplayer.com/videos/8K9oJcsX-khorc1ya.mp4"/><div style="position:relative; overflow:hidden;"><script src="https://cdn.jwplayer.com/players/8K9oJcsX-4mQgHT7J.js"></script></div></div> <p>تابعي نصائح وأفكار دليل مطبخ سيدتي التي ستساعدك في الحصول على مائدة رمضانية فاخرة ومميزة حتى في أيام الحجر المنزلي.</p></body></html>
I have enabled javascript, added hardwareAcclerated=true added a chrome client and all the other things suggested on other questions.
val settings = webview.settings
settings.domStorageEnabled = true
settings.javaScriptEnabled = true
settings.pluginState = WebSettings.PluginState.ON
webview.webChromeClient = WebChromeClient()
webview.webViewClient = WebViewClient()
settings.setDomStorageEnabled(true);
settings.setAppCacheEnabled(true);
settings.setAppCachePath(getApplicationContext().getFilesDir().getAbsolutePath() + "/cache");
settings.setDatabaseEnabled(true);
settings.setDatabasePath(getApplicationContext().getFilesDir().getAbsolutePath() + "/databases");
settings.allowFileAccess = true
val formattedHtml = "<html dir=\"rtl\" lang=\"\"><body>" + tip.description + "</body></html>"
webview.loadDataWithBaseURL("", formattedHtml, "text/html", "UTF-8", "")
Just tried your video url in my webview and it worked. Here are my settings:
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
So I would guess you have to set setMediaPlaybackRequiresUserGesture to false.
The problem was that the base URL was missing, which is making JWPlayer (the video host) throw an error.
The correct way to do it is to add local android_asset base URL
tipInformation.loadDataWithBaseURL("file:///android_asset/", s, "text/html", "UTF-8", null)
I have the code for playing YouTube in WebView on Android.
It works well on new phones (Android 4.4, 5.1, 6, 7 OS) but when I tried it on Android 4.0.3 it opens the YouTube frame with controls and after clicking on button play in the midle the gray background is shown all the time.
The code:
private void initializeWebView() {
WebView webView = (WebView) findViewById(R.id.webView);
//webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
webView.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
webView.setBackgroundColor(getResources().getColor(R.color.semi_transparent_black_20percentage));
webView.getSettings().setBuiltInZoomControls(true);
//webView.getSettings().setDisplayZoomControls(false);
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
});
WebSettings webSetting = webView.getSettings();
webSetting.setJavaScriptEnabled(true);
webSetting.setDisplayZoomControls(false);
//webSetting.setLoadWithOverviewMode(true);
//webSetting.setUseWideViewPort(true);
int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
webView.setLayoutParams(new RelativeLayout.LayoutParams( screenWidth / 2, LayoutParams.MATCH_PARENT));
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
webView.getSettings().setPluginState(WebSettings.PluginState.ON);
webSetting.setJavaScriptEnabled(true);
webSetting.setBuiltInZoomControls(true);
webSetting.setAllowContentAccess(true);
webSetting.setEnableSmoothTransition(true);
webSetting.setLoadsImagesAutomatically(true);
webSetting.setLoadWithOverviewMode(true);
webSetting.setSupportZoom(false);
webSetting.setUseWideViewPort(true);
webSetting.setAppCacheEnabled(true);
webSetting.setSupportMultipleWindows(true);
webView.setVisibility(View.VISIBLE);
}
public void loadPageIntoWebView(String htmlFilename){
AssetManager mgr = getBaseContext().getAssets();
try {
String htmlContentInStringFormat = "";
WebView webView = (WebView) findViewById(R.id.webView);
String frameVideo = "<body>Video From YouTube<br><iframe width=\"420\" height=\"315\" src=\"https://www.youtube.com/embed/2a7f29Jvihc?wmode=transparent\" frameborder=\"0\" allowtransparency></iframe></body>";
htmlContentInStringFormat = frameVideo;
webView.loadDataWithBaseURL(null, htmlContentInStringFormat, "text/html", "utf-8", null);
} catch (Exception e) {
e.printStackTrace();
}
}
This code is working well and playing YouTube videos on newer phones (Android OS4.4-7).
What I should change to get it working on Android 4.0.3 as well ?
this is the photo showing the gray background without playing youtubevideo after clicking on the button play inthe middle of the screen:
Solved!
After I added the following line it works on Android 4.0.3 aswell:
webView.setWebChromeClient(new WebChromeClient() {});
It is not mandatory but I added the line before this line:
webView.setWebViewClient(new WebViewClient()
Hope that this solution will help other collegues working with Epson Moverio BT-200 smart glasses etc.
;-)
is it possible to load multiple WebPages(including html,images,JS,css ) to WebView cache with real ProgressBar ? I know it is possible to load one page in this way :
String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath();
URL = "https://stackoverflow.com"
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setLoadsImagesAutomatically(true);
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setAppCacheEnabled(true);
webView.getSettings().setAppCacheMaxSize(1024 * 1024 * 8);
webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
webView.getSettings().setAppCachePath(appCachePath);
if (isNetworkAvailable()) {
appCachePath = getApplicationContext().getCacheDir().getAbsolutePath();
webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
} else {
Log.e(TAG,"Load page from cache");
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ONLY);
}
and it will make possible offline loading of that page, but is it any way to create custom WebView where I will have chance to load multiple URL in array or list, like
List<String> urls = new ArrayList<>();
urls.add("https://stackoverflow.com");
urls.add("https://google.com");
urls.add("https://facebook.com");
webView.loadURL(ursl);
And also I need a total progressBar for loading of those WebPages. I know I can set WebChromeClient for webView like:
webView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
Log.d(TAG,"onProgressChanged" + progress);
}
}
but it will show progress of loading only one WebPage, when I need total progress of few pages.
I do not want to write my own WebPage grabber, and store it in internal Storage, because it takes a lot of time and probably will cause a lot of different bugs and mistakes.
Please, can you give me some ideas ?
is it possible to load multiple WebPages(including html,images,JS,css ) to WebView cache with real ProgressBar ?
Not Possible .
Visit Android Doc for reference .
This is my first post on stack overflow, so I'll try to respect conventions and be as clear as possible.
Introduction :
For this project I'm trying to doing a web app with a local web server. My project is divide in two parts :
Local web server which transmit request to a real web server (it is a solution to resolve the Same origin policy)
A android web app which is the view. It's where the problem occurred.
When I'm trying to communicate with the server, using ajax request, the error INVALID_STATE_ERR: DOM Exception 11 occurred. However when I'm doing it on a firefox (with Apache), I haven't this problem.
Local web server :
The web server only stock or transmit data between web app and web server.
Webapp :
Initialization
In my android activity I'm starting my web app like that :
webview = new WebView(this);
MyJavaScriptInterface myJavaScriptInterface = new MyJavaScriptInterface(this);
webview.addJavascriptInterface(myJavaScriptInterface, "AndroidFunction");
// set settings
webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setAppCacheEnabled(false);
webview.setHorizontalScrollBarEnabled(false);
webview.setVerticalScrollBarEnabled(false);
if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) // 16
{
// yourwebview, i use phonegap here
webview.getSettings().setAllowUniversalAccessFromFileURLs(true);
webview.getSettings().setAllowFileAccessFromFileURLs(true);
}
// start
uri = new URI("http://127.0.0.1:"+LocalServer.RECORDING_PORT+"/index.html");
webview.loadUrl(uri.toString());
Ajax
To save the data in my webapp I'm doing a basic XMLHttpRequest (also tried with JQuery but no message came out)
function saveObject(in_strAction, in_oData, fctCallback)
{
var l_strURL = 'http://127.0.0.1:8888/api/' + in_strAction;
var xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
try // line 46
{
console.log ("xmlhttp.readyState="+xmlhttp.readyState+" && xmlhttp.status="+xmlhttp.status);
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
fctCallback(xmlhttp.responseText);
}
}
}
xmlhttp.open("POST",l_strURL,true);
xmlhttp.send();
}
Responses
Answers received by the web app are json and headers are create by the web server.
Problem solved
The exception INVALID_STATE_ERR: DOM Exception 11 is up while reading an invalid status :
function saveObject(in_strAction, in_oData, fctCallback)
{
var l_strURL = 'http://127.0.0.1:8888/api/' + in_strAction;
var xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
try
{
// Don't read status here (on state 1 exception will be up)
console.log ("xmlhttp.readyState="+xmlhttp.readyState);
if (xmlhttp.readyState==4)
{
// Status can be read here.
console.log ("xmlhttp.status="+xmlhttp.status);
if (xmlhttp.status==200)
{
fctCallback(xmlhttp.responseText);
}
}
}
}
xmlhttp.open("POST",l_strURL,true);
xmlhttp.send();
}