WebViewClient.onRenderProcessGone() not called on crashing WebView first - android

I have an app that can have multiple WebViews at the same time. Every once in a while the app crashes with a native error
SIGTRAP: Trace/breakpoint trap
at 0x7a587dd494(/data/app/com.android.chrome-7kzKsZs3wawWfQ1TQ0h58w==/base.apk!/lib/arm64-v8a/libmonochrome.so:25011348)
I was able to track it down to a WebView renderer issue which i can simulate by loading a faulty javascript like webView.evaluateJavascript("javascript:(function() { txt = \"a\"; while(1){ txt += \"a\"; } })();", null);.
I am now trying to figure out what page causes the problem in the production app. For that I am overriding WebViewClient.onRenderProcessGone() and want to log the loaded URL at that point. The problem that I have is that, since I have multiple WebViews, I cannot be sure that onRenderProcessGone() is called first on the one that actually caused the crash.
From the WebViewClient doc: Multiple WebView instances may be associated with a single render process. onRenderProcessGone will be called for each WebView that was affected.
My question is, in WebViewClient.onRenderProcessGone(), how can I know which WebView/WebViewClient has caused the crash?

This question got answered in the android-webview-dev google group. Unfortunately there is currently no way to know which webview has crashed.

Related

Android WebView App displays white screen after clicking a link

Masters,
I have a question. I've been building an Android App using WebView. Inside the app are links that navigates to external pages(I don't have any control with the WebSite that is loaded inside webview). I have an issue when I clicked a link and logCat returns : I/chromium: [INFO:CONSOLE(10)] "Uncaught TypeError: Cannot read property 'appendChild' of null" App displays white screen only. Have you experienced this issue before? Are there any possible solutions? TIA
To clarify the extent of the problem
What you currently have problem is with
Inside the app are links that navigates to external pages.
I have an
issue when I clicked a link and logCat returns
As you haven't shared your code both for webview(Android) or html code.
As I am faced similar type of problem, So these are method which solved my problems
Method 1:
public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
view.loadUrl(urlNewString); // you are using siteView here instead of view
return true;
}
Method 2: use http in url
Make sure the url starts with http://.
Without http it will just show white screen.

Best practice on enable/disable webview in Android

Would like to ask for some advice on what's best way to implement on enabling and disabling the web view on Android?
I have this app wherein it can open urls within (by using web views) which then popups up and covers 80% of the UI, when the user navigates to another page of the app it should hide/close the web view but can be re-opened again when needed.
Here's a snippet of the code
private WebViewInterface webViewInterface = new WebViewInterface() {
#Override
public void onOpenURL(String url) {
navBrowserWV.setVisibility(View.VISIBLE);
navBrowserWV.getSettings().setJavaScriptEnabled(true);
navBrowserWV.setWebViewClient(new WebViewClient() {
#Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error){
handler.proceed();
}
});
navBrowserWV.loadUrl(url);
}
};
then this is how I close it
private void closeWebView() {
Log.d(LOGTAG, "closing webview...");
// Destroy WebView if it exists
if (this.navBrowserWV != null) {
this.navBrowserWV.stopLoading();
this.navBrowserWV.loadUrl("about:blank");
this.navBrowserWV.clearHistory();
this.navBrowserWV.clearCache(true);
this.navBrowserWV.pauseTimers();
this.navBrowserWV.setVisibility(View.GONE);
}
}
The problem with this implementation is that it displays the page properly at first but when I close it and then open the web view again with a url, it does not load the page anymore just a white background (no errors on the logger btw).
Would like to ask for help on how to resolve this one. Thanks
Finally, after a long time of digging up answers on the internet I found this old post regarding killing Android webview [link].
There's no real way to kill the WebView (it will always run in your process and you can't do anything about it ATM). So you only have to tell the WebView to load a bogus page, for me I did:
this.navBrowserWV.loadUrl("about:blank");
And it works now!
Quote from the website
4.1 .getSettings().setJavaScriptEnabled() Inhalt
Well, you would think that disabling JavaScript in the WebView’s settings would have an instant effect, in short: it does not. Only after reloading the page would there be no javascript any more, and this is not nice by design, since the page is still more or less well rendered.
4.2 .stopLoading() Inhalt
Since XHR „loads“ something from another server, you might think that calling „webview.stopLoading()“ would have an effect. In short: it does not. Works only on ressources contained within the HTML-file. Pity, is it not… Well, maybe not, since there is no „startLoading()“ method to resume XHR after resuming the activity anyway.
4.3 .destroy() Inhalt
As a last resort one might think about „destroy()“ing that thing, and true enough, the WebView itself is not accessible after that. Its threads however continue to exist as zombies somewhere in the vast RAM space and also continue to send XHR requests…
4.4 .pauseTimers() / resumeTimers() Inhalt
In short: Nope, does not work. I even don’t know what these methods are good for if not for controlling JavaScript timers. There aren’t any in plain HTML, AFAIK.
Update: When it comes to timers only, these functions seem to work on 2.3.5 and upwards, however, when there is no timer active at the time of calling the function, all in vain. With my use case: When pausing the app while there is an XHR active (instead of the running timer that schedules the next XHR call), nothing happens and the next timer continues unhindered.
I hope this will help someone who has the same problem as mine.

Images randomly break in PhoneGap/WebView on Android 4.4

I am experiencing a strange bug in PhoneGap on Android 4.4, for which I couldn't find any solution online. In my app, I am loading a lot of different images from a remote server, and as the user navigates back and forth, new images are loaded on each page (4 at a time, to be specific, through jQuery-generated html). After having navigated back and forth for a little while, some images will randomly not show up and instead show the typical "broken image" icon.
Now, here comes the strange part: I have been following the instructions at jQuery/JavaScript to replace broken images and done a few tests of my own. In conclusion, the naturalWidth and naturalHeight parameters report the right sizes of the images, and complete reports true for all images. Therefore, the solutions mentioned in the above SO thread don't work at all. Changing the image src doesn't help, either with or without a setTimeout (I tried adding the current timestamp as a parameter to the image path as well).
Did anyone else encounter this issue at all, or am I going crazy here? :)
EDIT: By the way, no error is ever reported. Therefore, no error handler is called when loading the image, making it useless to solve the problem with the already suggested methods (see the link above).
This is how i handle error images,
<img src="images/imageName.jpg" onError="onErrorFunc(this);" alt=" " />
function onErrorFunc(elem){
var imgUrl = "https://alternative-image";
elem.onerror = function (){
elem.src='images/noimage.jpg';
}
elem.src=imgUrl;
}
Hope it helps!

Disable page forwarding in Android webview

I have a webview that shows ads (not my ads), the problem is when user clicks the "x" button to exit the ad, the ad still directs them to a site. What I wonder is since I can't control the ads, can I instead Disable page directing/forwarding inside webview? that means even if user clicks a link inside my webview nothing should happen.
You are looking for WebClient.shouldOverrideUrlLoading method.
webview.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading (WebView view, String url){
//True if the host application wants to leave the current WebView and handle the url itself, otherwise return false.
return true;
}
});
I tried using shouldOverrideUrlLoading, but it didn't work. It looks like that this method is called only once when the html is loaded. After that, you click a link but the method is no more invoked.
I am also making a WebView embedding Youtube Player. Instead of forwarding ads redirect from the WebView, I prefer to open ads in a browser. So I override onLoadResource method:
#Override
public void onLoadResource(final WebView view, final String url) {
if(url.indexOf("googleadservices.")>-1){
view.getSettings().setJavaScriptEnabled(false);
view.stopLoading();
view.postDelayed(
new Runnable(){
#Override
public void run(){
Uri uri=Uri.parse(url);
Intent i=new Intent(Intent.ACTION_VIEW,uri);
i.setClassName("com.android.browser","com.android.browser.BrowserActivity");
startActivity(i);
}
}
,100
);
}
}
It worked. When I clicked the ads link, a new browser is opened in which ads site is displayed well, and the WebView was not redirected. When I push the return button, WebView show up again and I can continue watching video.
But there were still problems. If I repeat opening browser and returning to WebView for many times, the WebView might fail to block redirecting to the ads site. It is just redirected to the ads site. If I am lucky I could repeat opening and returning for 100 times. But sometimes It failed just when I repeat several times. I don't know why.
Does anyboday have any idea about how to improve it? Or is there another way to disable ads redirect?
You can build undetected webview build-id adblocker
I know it is too late for answering this question, however, for the sake of others who have the same question.
Well, you can build webview build-id adblocker, if you wish to prevent ads from loading, and provide smooth experience to the users, I am confident, because I have already implemented it in may app.
The Idea
Is to have a black list of all possible ad-serves domain name, then while webview load resources, you will prevent loading from black list domains. so it depends on how many ads-serves domain you have in the black list, fortunately, there is one website (pgl.yoyo.org/as/) which provide you with a very long list of ad-serves domai names, and listed them in many flavoures.
you can read this article for:
how to implement webview build-id adblocker
, you will build it %100 as long as you follow step by step instructions.
A summary of what we need to do:
Get the list of ad hostnames from pgl.yoyo.org.
Save the list somewhere, load it when application starts.
UseWebViewClient.shouldInterceptRequest(WebView, String) to intercept
requests.
Check if the request URL belongs to one of the hostnames in
the list and override it, returning a dummy resource instead of the
actual one, which is supposed to be ads

WebView throws Receiver not registered: android.widget.ZoomButtonsController

I see this exception sporadically raising up in my application (in the wild).
The WebView is used to display a jpg (using the zoom/scroll-capabilities of the Android version/the device instead reinventing the wheel and do all the reflection stuff).
I have no idea why this exception eventually could come up. Basically I can only think of an Android bug.
What I do (everything in GUI thread):
display a thumbnail as preview first
set getSettings().setBuiltInZoomControls(false)
when the regular picture is loaded, display that one instead
set getSettings().setBuiltInZoomControls(true)
Why setting ZoomControls on/off: The thumb should not be zoomable, as the WebView resets this on loadData as soon as the regular picture is available and displayed. Would be some bad user experience.
Example device this is happening:
HTC Desire#htc_wwe/htc_bravo/bravo/bravo:2.2/FRF91/226611:user/release-keys
I have exactly the same device/software and it never happend to me...
Any ideas?
Regards,
Oliver
I don't like to answer myself, but littleFluffyKitty did not (only in comment).
Solution is in How to safely turn WebView zooming on and off as needed
a) create your own WebView class
public class MyWebView extends WebView {
b) add in it's onDestroy() method:
getSettings().setBuiltInZoomControls(true);
That's it. Thanks to that, no more of those Exceptions show up.

Categories

Resources