The onLoadResource function sporadically generates not found errors - android

I have a webview application that uses hooks to execute native java code (ie populate a local db) and to catch these hooks I use the onLoadResource function.
It works as expected, but about 10% of the time I get server log errors of the hook being fired and its clogging up my logs with "not found" errors.
So it basically works like this:
User loads their webview app
In the app they click on of the hooks (http://domain.com/hook/datatopass)
The onLoadResource does its processing and forwards the user to
another page (http://domain.com/home)
The majority of the time it works, but sporadically I get the "ERROR [http://domain.com/hook/datatopass] not found" error.
From what I can tell the user doesn't see any error pages, they get forwarded to the correct place - but I don't know why the onLoadResource doesn't catch every request before it logs an error. Anyone know how to avoid these errors being thrown, and why this is happening?

It seems for me that a Timeout occurs - sometimes.
Have you tried to set the timeout time higher ?
Or have you tried to show an ProgressDialog like below to locate the problem?
public void onLoadResource(WebView view, String url) {
// Check to see if there is a progress dialog
if (progressDialog == null) {
// If no progress dialog, make one and set message
progressDialog = new ProgressDialog(activity);
progressDialog.setMessage("Loading please wait...");
progressDialog.show();
// Hide the webview while loading
webview.setEnabled(false);
}
}

Related

Android WebView with AngularJS application route changes not being detected in shouldOverrideUrlLoading

I have been working on a hybrid android application. Currently a WebView in our application is pointing to an AngularJS 1.5.7 application. When the user hits a button inside of the application that changes the route I was expecting the shouldOverrideUrlLoading function to be called inside of my WebViewClient. However, this is not the case. It looks like shouldOverrideUrlLoading does not get hit on Angualar route changes.
This being the case I have gone down the following rabbit holes:
onPageFinished - Overriding this function in the WebViewClient works, however, it is not being called until after the new route is getting hit. Which is adding to the application loading time and creating a choppy experience. ` #Override
public void onPageFinished(WebView view, String url) {
if (url.endsWith("/#/")) {
signOut();
} else if (url.endsWith("/login")) {
// TODO: show some sort of failure message?
Log.i("Login Route", "The webview just attempted to go to the login route.");
signOut();
} else if (url.endsWith("/security")) {
Intent intent = new Intent(getApplicationContext(), SecurityActivity.class);
startActivity(intent);
}
}`
shouldInterceptRequest - Overriding this function allows you to watch for requests. However, by the time the requests go out from the AngularJS application the web view is showing a new route once again providing a choppy user experience.
onLoadResource - same
JavaScriptInterface - Currently I have set up a JavaScript interface to watch for window.location changes. This seems to catch the route changes quicker than any of the above options, however, there is still a glimpse quick flicker of the web page I do not want to do go to. You can find how to do Javascript bridging on this post
Any suggestions would be greatly appreciated! Thanks.

displaying runtime errors in android/ios installed app

I've been trying to get errors to display in a text field within the app for ease of error reporting from users.
I've had some success using this code I found on stackoverflow. It's used at the top level of the app but it's not working on device:
//start code
this.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, errorHandler);
function globalErrorHandler(event:UncaughtErrorEvent):void
{
var message:String;
//check for runtime error
if (event.error is Error)
message = (event.error as Error).getStackTrace();
//handle other errors
else if (event.error is ErrorEvent)
message = (event.error as ErrorEvent).text;
else
message = event.error.toString();
//do something with message (eg display it in textfield)
myTextfield.text = message;
}
//end code
At first this wouldn't work on the device and I thought it was because upon the error, when developing on the pc, flashplayer would display the actionscript popup with the error. Which you would need to click "dismiss all" or close and then the globalErrorHandler was called after and then the error written to the textfield. I thought this is what was keeping it from showing up on the device. However, by adding event.preventDefault() I was able to suppress the actionscript popup when developing on the desktop and the error was written to the textfield successfully. This was not the case however on the andriod device. It still just hangs on the error. It's as if the default error event cannot be suppressed on android.
Thanks for your time. Any help appreciated!
EDIT 22/09/2017: I was able to see the error on device finally. It had to do with while on desktop publishing the error would be shown. However, on device the behavior was different and something was covering the textfield, by bring it to the front on error I was able to see it. However, I still see that some errors deeper in the class hierarchy are not being caught.
In our project we have it simpler (and it is working):
stage.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onUncaughtError);
private function onUncaughtError(e:UncaughtErrorEvent):void
{
// Console is basically a TextField for debug/diagnosis output.
if (e.error) Console.error(e.error.getStackTrace());
e.preventDefault();
}
The other thing you should probably check is whether your TextField actually displays any text at all for there might be text embedding issues, unrelated to the error handling routine.
UPD: Loading SWFs so it doesn't mix with the parent.
var request:URLRequest = new URLRequest(path);
var context:LoaderContext = new LoaderContext;
context.applicationDomain = ApplicationDomain.currentDomain;
var loader:Loader = new Loader;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
loader.load(request, context);

Android 4.4 giving ERR_CACHE_MISS error in onReceivedError for WebView back

I have a webview in my Layout. By default, a search form is opened in it. On search, a listing section appears below the search form. If any link in the list is clicked, the details page opened. Now I want to controlled the back navigation for the webview. I placed this code in Activity.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.d("TYPE", TYPE);
WebView myWebView = null;
if (TYPE.equalsIgnoreCase("REPORT_ACTIVITY"))
myWebView = reportView;
if (TYPE.equalsIgnoreCase("FEEDBACK_ACTIVITY"))
myWebView = feedbackView;
if (myWebView != null)
// Check if the key event was the Back button and if there's history
if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) {
myWebView.goBack();
return true;
}
// If it wasn't the Back key or there's no web page history, bubble up
// to the default
// system behavior (probably exit the activity)
return super.onKeyDown(keyCode, event);
}
private WebViewClient webViewClient = new WebViewClient() {
public void onPageStarted(WebView view, String url, Bitmap favicon) {
Log.d("onPageStarted", "onPageStarted");
loadProgressBarBox.setVisibility(View.VISIBLE);
//view.setVisibility(View.GONE);
}
public void onPageFinished(WebView view, String url) {
Log.d("onPageFinished", "onPageFinished");
loadProgressBarBox.setVisibility(View.GONE);
}
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
Log.d("Error", "Error code: " + errorCode + "/" + description);
}
}
I have also set a WebViewClient with the WebView. When I going back using back button it is working fine for any version 4.4. But when I am trying in Android 4.4, it is coming back fine from details page to listing page. But as soon as I am trying to go back again, its throwing error code -1 and ERR_CACHE_MISS in description. No page is displayed.
09-04 06:59:05.666: D/Error(1102): Error code: -1/net::ERR_CACHE_MISS
How to solve this problem in Android 4.4?
This error actually stems from outside of your application in most cases (occasionally it's just a missing INTERNET permission, but that doesn't sound like the case here).
I was typing out an explanation, but found a much more straightforward example that doubles as an explanation in this answer to another question. Here's the relevant bits, re-hashed a little:
Joe fills in an order form with his credit card information
The server processes that information and returns a confirmation/receipt page that's marked with no-cache in the header, meaning it will always be requested from the server.
Joe goes to another page.
Joe clicks back because he wants to double check something, taking him to the confirmation page.
The problem arises from that last step. The confirmation page was marked with no-cache, so it has to be requested from the server again. But to show the same page correctly, the same data that was passed the first time needs to get sent again.
This results in Joe getting billed twice, since a new request is being made with the same information as last time. Joe will not be a happy camper when he finds two charges on his account and an extra pair of tents on his doorstep.
It seems this situation was common enough that it is now a standard error across most browsers, and apparently, newer versions of Android. The error actually originates from Chromium, which is why you'll see the same error in Google Chrome, and why you only see it in 4.4 (which introduced a new version of the WebView based on Chromium).
In fact, you have actually probably seen it before, it's the message that shows up in most browsers warning you with something along the lines of "To refresh this page, the browser will have to resend data...yada yada yada".
This is Android 4.4's way warning you of what's going on. How to fix it really depends on what you're connecting to, but if you search for this situation, you'll find that it's fairly common, and has fixes. The exact trigger of the error is actually when the request can't be serviced from cache (in this case, no-cache is causing that).
Depending on the nature of the request, maybe no-cache isn't actually needed.
But from your application's perspective, the main problem is, onReceiveError is a sort of "last resort" for the WebView. Errors you get there have propagated from underlying system. And once you end up there, you can't continue the page load as it stands. So you don't have a chance to allow that resend, and you can't give the user that option, unlike, say Google Chrome does.
I ran into the same issue because in my manifest folder I had the Internet permission capitalized:
I had (error)
<uses-permission android:name="ANDROID.PERMISSION.INTERNET"/>
Should have (no error)
<uses-permission android:name="android.permission.INTERNET"/>
Use
if (Build.VERSION.SDK_INT >= 19) {
mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
}
It will fix ERR_CACHE_MISS in the WebView.
Maybe you will need to change it to SDK_INT == 19 after some Lollipop WebView updates, but it works for now.
this permission in your andriodManifest.xml file
<uses-permission android:name="android.permission.INTERNET"/>

android phonegap custom "Web page not found"

Problem:
I'm trying to avoid the "web page not found", or at least to display a customized error page.
Context:
I use the cordova trick:
if (navigator.network.connection.type == Connection.NONE)
{
window.location="offline/index.html";
}
else
{
window.location="http://myurl.com";
}
But in my tablet, if there's no connection, I have the ugly "WebPage not found".
There's maybe something wrong in my code, but in all case I would like to find a way to avoid this page and to show my own.
I will be very happy if somebody here can tell me where to give a look.
Stef
PS : the "Page Not found" appears when the website is down. It's not related to the event offline. You can have internet, and the server can be down. In that case, I want to display my own error page. Thanks!
There is an event offline available in Cordova. You could add event listeners to this and do required changes in its callback. If you are using deviceready event it will be called only once when your app is done loading. But if you add offline & online listeners you can alert user each time network goes down/up.
document.addEventListener("offline", onOffline, false);
function onOffline() {
// Handle the offline event
}
http://docs.phonegap.com/en/2.9.0/cordova_events_events.md.html#offline

Android - Downloading data from the internet >> catch connection errors

In my app i connect to a server, which responds with an xml. I parse it with the SAX Parser, and get the data.
The question is:
What is the best way to handle connection issues?
(At this moment if there is no internet connection available the app simply continues showing the ProgressDialog i implemented)
So you basically do (Pseudo code)
ProgessDialog pd = new ProgressDialog(this).show();
Sax.parseStuff();
pd.dismiss();
In this case, wrap the parsing stuff and cancel the dialog on Exception
ProgessDialog pd = new ProgressDialog(this).show();
try {
Sax.parseStuff();
}
finally {
pd.dismiss(); // or cancel
}
You can also do a try { .. } catch (XYZException e ; pd.cancel(); throw e) if you want to process the Exception in a different layer of your app.
As well as following the suggestion of Heiko Rupp, you can also check for the availability of a network connection prior to performing your download. See my post on the subject.

Categories

Resources