_From @Alphapage on July 9, 2015 20:7_
Hello,
I use a webview and I want to show a toast between two html pages to inform the user about an action.
With java, you need to add @javascriptInterface annotation to enable the function.
How can I do with Nativescript for android ?
Thanks in advance for your help.
_Copied from original issue: NativeScript/NativeScript#414_
You should use the WebView events loadStartedEvent, loadFinishedEvent (http://docs.nativescript.org/ApiReference/ui/web-view/WebView.html)
and then use the Toast class of Android framework to show the message
https://developer.android.com/guide/topics/ui/notifiers/toasts.html
@enchev @Alphapage
_Feedback needed_
I did a working prototype that allows you to specify Java annotations from JavaScript. Let's see the concrete scenario. We want to call NativeScript from a WebView control using addJavascriptInterface method. To accomplish this we need three things
NativeScript runtime can already create new types via extend function. That's we can subclass a Java class in JavaScript. For example
var MyObject = java.lang.Object.extend({
hashCode: function() {
return 123;
},
sayHello: function() {
return "Hello!";
}
});
Basically, this will create a Java proxy class similar the to following one:
public class MyObject extends java.lang.Object {
public int hashCode() {
return (int)com.tns.Platform.callJSMethod(this, "hashCode", null);
}
}
However, the generated Java proxy will declare only the methods what are overwritten in JavaScript (so it can pass the control flow). Thus the generated Java proxy will not expose sayHello method.
I added one more parameter to the current extend syntax in the following way.
var MyObject = java.lang.Object.extend("MyObject", {
hashCode: function() {
return 123;
},
sayHello: function() {
return "Hello!";
}
}, {
annotations: [ /* list of annotations that will be applied on MyObject class */ ],
exposedMethods: [ /* list of JavaScript methods that will be exposed in Java proxy class */ ]
});
In order to define a Java method all we need is it's signature. For the purpose of this prototype I use the standard JNI notation which is well known among the Java developers and widely used by Java tools. In our case we can encode sayHello methods as
var exposedMethod = { "signature": "sayHello()Ljava/lang/String;" }
In order to apply the corresponding Java annotations we can add annotations property as follows
var exposedMethod = {
"signature": "sayHello()Ljava/lang/String;" },
"annotations": [ /* list of annotations applied on sayHello method */ ]
};
We can use a single annotation format for both class and method annotation scenarios. Basically, to describe an annotation we need its name and its parameters if any. I selected the following annotation format
var annotation = {
"className": <JNI string for the annotation class>
"props": [ /* array or key/values */]
};
In our case, we can full describe sayHello method as follows
var jsiAnnotation = { "className":"Landroid/webkit/JavascriptInterface;", "props":[] };
var MyObject = java.lang.Object.extend("WebViewInterOp", {
sayHello: function() {
return "Hello NativeScript (extended in JavaScript)!";
}
}, {
"annotations": [ /* list class annotations */ ],
"exposedMethods": [ { "signature": "sayHello()Ljava/lang/String;", "annotations": [ jsiAnnotation ] } ]
});
In TypeScript, we can use decorators in order to make the syntax more succinct
class MyObject extends java.lang.Object {
constructor() {
super();
return __native(this);
}
hashCode() {
return 123;
}
@ExposeWithSignature("sayHello()Ljava/lang/String;", [ { "className": "Landroid/webkit/JavascriptInterface;", "props": [] }])
sayHello(): string {
return "Hello NativeScript (extended in TypeScript)!"
}
}
Here we use a single ExposeWithSignature decorator that follows the same pattern
@ExposeWithSignature("sayHello()Ljava/lang/String;", [ { "className": "Landroid/webkit/JavascriptInterface;", "props": [] }])
The transpiled code will be the same as in the JavaScript case.
The current prototype does not implement setting annotation properties though the infrastructure is already in place. Also, at the moment all annotations are treated as visible to the Java runtime though this also can be configuration option.
This is the first iteration for the feature and the suggested syntax is not set in stone so please feel free to comment and propose other options.
we're closing this because of the lack in interest, but don't hesitate to drop us a line and we'll open the issue, if it's still relevant.
Can we open this issue, looks I saw good prototype that can work, if it is not that hard to add, it will be great addition, as main compelling reason to use Nativescript over others others, is that it is the least one requiring playing with native platform eclipse or xcode so if it is possible now that we got version 5.0 it will be nice addition
@AhmedAzzabi what is your scenario?
In case your scenario is WebView/NativeScript integration, I would suggest to avoid it and think about other options if possible. While such integration is possible, it comes with a cumbersome memory model and you have to think about the life of the involved JS objects. As you can see for the last 3 years there were no requests for this functionality and it makes sense to focus on other tasks. In case your scenario is critical, I would suggest to use com.tns.Platform.callJSMethod(..) and write the Java proxies yourself even though it is not an elegant solution.
P.S. I am no longer with Telerik and NativeScript team so take my comment as a personal opinion.
I agree looks an edge case, I'm interested what other alternatives you would suggest for webview/nativescript, here is my scenario: my app get some data from websites but these websites use javascript so content can't be obtained by using http.getString, I need to emulate browser, for now I'm using plugin webview interface but just wondering if there are alternatives
Hello guys,
How can I use Android Annotations from NativeScript? like this: http://greenrobot.org/files/eventbus/javadoc/3.0/ (Annotation Type Subscribe)
For example, within an extended class of java.lang.Object
Any help is really appreciated!