what is relation between android WebView and WebViewClassic - android

I am having a problem in copy-paste on long click on text inside my class extending Android WebView.
I'm able to copy, but paste is not working.
While investigating, somewhere on net got suggestion to look into android.webkit.WebViewClassic.
In WebViewClassic, there's a method named pasteFromClipboard().
I think actual pasting of code happens in that method, but not sure.
So can anyone please tell me Am I right, i.e. whether investigating in WebViewClassic is worth for me?
If yes, please tell me what is relation between WebView and WebViewClassic, i.e. how long click in WebView goes to WebViewClassic.
And sorry, I cant expose my code or log.

WebViewClassic is the default WebViewProvider for WebView. From the implementation notes:
The WebView is a thin API class that delegates its public API to a backend WebViewProvider
class instance. WebView extends {#link AbsoluteLayout} for backward compatibility reasons.
Methods are delegated to the provider implementation: all public API methods introduced in this
file are fully delegated, whereas public and protected methods from the View base classes are
only delegated where a specific need exists for them to do so.
Basically, touch handling is forwarded from the WebView to a WebViewClassic instance. If you read through it's onTouchEvent implementation, and its inner WebViewInputDispatcher implementation PrivateHandler you can trace where the touch handling will lead to a call to pasteFromClipboard() on the WebViewClassic instance.
So yes, you are correct. When you tap the paste button on the PastePopupWindow, there will be a call to WebViewClassic's pasteFromClipboard(); method.

Related

Android Implementation of WebView (postURL)

I am researching the method WebView#postUrl in 4.3; the description says:
If url is not a network URL, it will be loaded with loadUrl(String)
instead.
How would I find the actual implementation code for both methods, because I do not understand the meaning of network URL. I have looked at the WebView code but that refers to another method which I cannot find the implementation of...
I am assuming the difference between the two methods is, one is POST and the other one is GET..., and, if this is the case, under which condition will Android switch between the two automatically as the description indicates.
Thanks,
Andreas

Get an ID value as a string from a webview

I would like to know how I can get a value from a webview.
For example, to load a value into the webview I use:
myWebView.loadUrl("www.example.com");
myWebView.loadUrl("javascript:document.getElementById('username').value='"+ user + "';");
Now I would like to read some text from a certain ID from a webpage.
Something like:
myWebView.loadUrl("www.example.com");
myWebView.getUrl("javascript:document.getElementById('username').toString(user);");
Is this possible?
Edit: Since KitKat (API 19), the WebView class provides the method evaluateJavascript that allows to execute javascript and get the return values.
For olders API, you can still bind javascript to your Android Java code (look here)
So, you will implement a Javascript interface class and add it to your WebView and then call something like
myWebView.loadUrl("javascript:MyJavascriptInterface.getValue(document.getElementById('username').value);");
This will call the method getValue (this is a custom function, it is up to you to rename it as you want) in your class that is used as a Javascript interface, and change MyJavascriptInterface with the name you specified in addJavascriptInterface.
Yes, you can. getElementById('username').Value

How to completely reset Android webview before load new request

I am using Android WebView to load some webpages. In my case, I have to insert some JavaScript codes before loaded webpages. Just like below:
//enable javascript
mWebView.getSettings().setJavaScriptEnabled(true);
//inject my js first.
//I can't inject the js onPageStarted() or onPageFinished() because I need to make sure the js
//is injected before html loaded.
mWebView.loadUrl("javascript:MyJsCode");
//load HTML
mWebView.loadUrl("http://example.com/demos/index.html");
The code works fine first time, but failed when run it more than one time. Because the HTML can't find my JS.
I think because the previous HTML is not clear completely, so mWebView.loadUrl("javascript:MyJsCode") inject MyJsCode to previous HTML instead of the new HTML.
So I thought if I could completely reset the WebView(to clear the previous HTML), will solve my issue.
I tried WebView.ClearView(), loadUrl("about:blank"), they all doesn't work.
Anyone suggestion?
Though this is a a tiny bit late, I offer the following. Perhaps it may be helpful . . .
Your question does not specifically mention using any of the callbacks in the WebChromeClient, but you do mention JS, so the following may help. In SDK level 16 and below, you can use the callbacks without specifically "clearing" them. However, starting with SDK level 17, I observe that you must act to clear the events -- specifically alert(), which, of course, results in onJSAlert() being fired in your WebChromeClient if you override it. In all the devices I have tested at SDK level 16 and below, you may blithely ignore the callback, and all will go to plan.
However, you will note that onJSAlert, when overridden, delivers a JSResult object in the last parameter, thus:
boolean onJsAlert(WebView view, String url, String message, JsResult result)
I observe that the JsResult object has two methods exposed, thus:
Public Methods
final void cancel()
Handle the result if the user cancelled the dialog.
final void confirm()
Handle a confirmation response from the user
Assuming that one returns true in the callback (indicating that the callback consumed the onJsAlert event), and assuming that you are using SDK 16 or before, then WebView.destroy() will do the expected things.
I observe, however, that SDK 17 (4.2.x) seems to want some further proof that the callback did, in face, handle the event. Failing to call result.cancel() or result.confirm(), will leave your WebView (or, more to the point, the WebViewCore) stuck permanently. Nothing I have tried will reawaken the WebViewCore, and, thereafter, nothing will load in any WebView, new or otherwise. (Attempted explanation: WebView is merely a wrapper class for WebViewProvider, which, in turn instruments a WebViewCore object. It's that last fellow, WebViewCore, that does all the work. Through wandering the source code, and through reflection, you can burrow your way into that object, if you are keen to do so. WebViewCore is a static, thus, there is exactly one WebViewCore for the whole of your application. Ergo, if your one-and-only WebViewCore gets stuck, no WebView in your application will work thereafter. Once it is stuck waiting, for example, for a JSResult method to be called, it will be stuck until the application is destroyed (i.e. even pausing/resuming the app has zero effect). Even calling destroy() on the WebViewCore directly, through access gained through reflection is ineffective. N.B. Calling destroy() on the WebView has the side-effect of calling destroy() on the WebViewCore but that, too, does nothing helpful).
So, the symptom is that
you create a WebView
some clever JS runs, perhaps calling alert()
you handle the alert() in your onJsAlert override method
you fail to call either result.confirm() or result.cancel()
you destroy the WebView
thereafter, no WebView in your application will load anything.
The good news is that if you are sure to "clear" the events in whatever callbacks you override by invoking the appropriate JsResult method, then the WebViewCore will not permanently stop, and your application will be happy.
I think there is no way to do this except re-new a WebView.

Overriding onTouchEvent with Flixel (Android port)

So I followed Mathew Casperson's Making Games on Android Tutorial and got a small game running a few days ago, now I am trying to switch the controls to touchscreen instead of the D-pad.
I am running into some problems and was wondering if anyone here could help me. Flixel doesn't have any built in touchscreen functions so I am overriding onTouchEvent(MotionEvent event) in my Activity (FlixelDemo.java in the tutorial) and hopefully getting the coordinates of the touch.
I then have a function in my Player.java that given the touch coordinates could tell me whether my player has been touched.
The problem I am having is trying to figure out how to get to/call that function (isCollision) from in the activity.
It seems that I can only override the onTouchEvent in FlixelDemo.java and that I can only use the isCollision function in GameState.java where I add the player.
How do I get the info from the overridden touch event to any of my other classes? Can anyone tell me what I am doing wrong or help me figure out a different way of implementing touch events?
Looking at the code, FlixelDemo is really just a container for org.flixel.FlxGameView (via the res/layout/main.xml file).
The onTouchEvent method can be applied to any View, so you can apply it to just the flixel viewport.
And in fact, that's probably what you want to do here: Add your handler directly to FlxGameView.java, and then let it call a method on the internal GameThread class.
It's already handling the other events this way. See FlxGameView.onKeyDown (and the associated FlxGameView.GameThread.doKeyDown) for a good example.

Robolectric Custom Shadow Object

OOTB, Robolectric does not support Locales that well. Therefore, if your app is dependent on locales (which a lot of apps are if they are i18n'nd properly) this can be a royal pain. Long story short, I created my own ShadowFooGeocoder and ShadowFooAddress that allow me to simulate the locale I want. They're basically re-implementations of the existing shadows.
However, when I bind my class as such: bindShadowClass(ShadowFooGeocoder.class), this works great. At runtime, the correct shadow is returned. The problem is that I want to set up the simulations on this object and I'm not sure how. shadowOf(instance) where instance is an injected GeoCoder returns ShadowGeoCoder. I've tried working directly with the ShadowWrangler, but that also returns a ShadowGeocoder.
How can I get at my shadowed class that I've bound through the bindShadowClass(...) call so I can set my expectations (simulations)?
Note: This is a repost of the same question on the Robolectric group here. I posted here because my success rate of getting anyone to answer questions on the group is fairly low. I'm hoping for a better result here.
What I've basically done here is extend ShadowGeocoder like this:
#SuppressWarnings({"UnusedDeclaration"})
#Implements(Geocoder.class)
public class ShadowFooBarGeocoder extends ShadowGeocoder {
// implementation stuff
}
Then I would bind it using the bindShadowClasss(...) and when I retreive the shadow via the static shadowOf(...) call I get back a "ShadowGeocoder" which is an instance of ShadowFooBarGeocoder. I then cast it to that type and perform whatever work I need to.

Categories

Resources