JavaScript in Android - java

Is it possible to use JavaScript in Android?? if so, how? Please provide some examples.
Thanks.

I am way late to the party here, but I had this exact need. iOS 7 now includes JavaScriptCore
natively and it is really easy to use (despite limited documentation). The problem is that
I didn't want to use it unless I could also use something similar on Android. So I created the AndroidJSCore project. It allows you to use your JavaScript code natively in Android without requiring a bulky WebView and injection. You can also seamlessly make asynchronous
calls between Java and Javascript.
Update 27 Mar 17: AndroidJSCore has been deprecated in favor of LiquidCore. LiquidCore is based on V8 rather than JavascriptCore, but works essentially same. See the documentation on using LiquidCore as a raw Javascript engine.
From the documentation:
... to get started, you need to create a JavaScript JSContext. The execution of JS code
occurs within this context, and separate contexts are isolated virtual machines which
do not interact with each other.
JSContext context = new JSContext();
This context is itself a JavaScript object. And as such, you can get and set its properties.
Since this is the global JavaScript object, these properties will be in the top-level
context for all subsequent code in the environment.
context.property("a", 5);
JSValue aValue = context.property("a");
double a = aValue.toNumber();
DecimalFormat df = new DecimalFormat(".#");
System.out.println(df.format(a)); // 5.0
You can also run JavaScript code in the context:
context.evaluateScript("a = 10");
JSValue newAValue = context.property("a");
System.out.println(df.format(newAValue.toNumber())); // 10.0
String script =
"function factorial(x) { var f = 1; for(; x > 1; x--) f *= x; return f; }\n" +
"var fact_a = factorial(a);\n";
context.evaluateScript(script);
JSValue fact_a = context.property("fact_a");
System.out.println(df.format(fact_a.toNumber())); // 3628800.0
You can also write functions in Java, but expose them to JavaScript:
JSFunction factorial = new JSFunction(context,"factorial") {
public Integer factorial(Integer x) {
int factorial = 1;
for (; x > 1; x--) {
factorial *= x;
}
return factorial;
}
};
This creates a JavaScript function that will call the Java method factorial when
called from JavaScript. It can then be passed to the JavaScript VM:
context.property("factorial", factorial);
context.evaluateScript("var f = factorial(10);")
JSValue f = context.property("f");
System.out.println(df.format(f.toNumber())); // 3628800.0

Do you mean something like making a native app using Javascript? I know there are tools like Titanium Mobile that let you make native apps using web tools/languages.
You could also make Web Apps. There are loads of resources and tutorials out there for that. Just search "Android Web App tutorial" or something similar.

Yes you can, just create a wrap up code that points to html page and includes your javascript and css.
There are different libraries that can help you with this:
http://www.phonegap.com/
http://www.sencha.com/products/touch/
http://jquerymobile.com/

Just posting this for posterity but React Native is a great solution in this space. You can write a complete app in JS using native views under the hood, or embed a JS component inside an existing Java app. https://reactnative.dev/

Related

embedded Nashorn - sandboxing execution

I would like to get a clear answer on how to Sandbox execution Nashorn within a Java Application.
I have seen 'similar questions' (which I will refer to) but ultimately none of the answer seem to address my concerns.
Let me start with definitions.
Assume we start with this:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
engine.put("map",new HashMap());
engine.eval(jsCode); // jsCode can access 'map' only.
By "Sandboxing" I mean ensure that the JavaScript must not access any java object except the one added in the scope.
so the following evals should be fine.
engine.eval("map.toString()");
engine.eval("map.size()");
engine.eval("map.put('name','jeff'); ");
engine.eval("map.getClass()");
But the following evals will not:
engine.eval("var m = new java.util.HashMap();"); // <-- stop accessing Java
engine.eval("map.getClass().forName('java.io.File'); "); // stop. it's trying to be sneaky
Finally, I am not concerned about this:
engine.eval("while(1) {;}"); // this is impossible to detect. Maybe it's possible for this simple case... but sneaky users could make it impossible to detect... anyway this is not what I am asking. I am only concerned on accessing java objects.
So by sandboxing I intend to prevent jsCode to access java objects that I don't define.
I saw that this might be a potential solution:
jdk.nashorn.api.scripting.NashornScriptEngineFactory factory = new jdk.nashorn.api.scripting.NashornScriptEngineFactory();
ScriptEngine engine = factory.getScriptEngine(new jdk.nashorn.api.scripting.ClassFilter() {
public boolean exposeToScripts(String s) {
return false;
}
});
but is it 'safe' to access a package beginning with jdk.* directly ?
Another approach I saw is even more mysterious:
final ScriptEngine engine =
new NashornScriptEngineFactory().getScriptEngine(new String[] { "--no-java" });
I saw that one here:
Safely re-using sandboxed Nashorn containers
Can somebody let me know ?
You can use jdk.nashorn.api.scripting.* API if that would help in your application. javadoc for the same is here -> https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/
And yes, --no-java is the option for preventing java package access from script code.

run java in javascript

I am making a function that compares two pictures if they are the same. I have this code:
var rez = null;
rez = compareImages();
alert(rez);
boolean
function compareImages() {
BufferedImage bi1 = java.ImageIO.read(new File("C:\\MyFiles\\pic1.png")),
bi2 = java.ImageIO.read(new File("C:\\MyFiles\\pic2.png"));
Raster r1 = bi1.getData(),
r2 = bi2.getData();
DataBuffer db1 = r1.getDataBuffer(),
db2 = r2.getDataBuffer();
int size1 = db1.getSize(),
size2 = db2.getSize();
// checking if the files sizes are the same
if (size1 != size2)
return false;
// pixel by pixel check up
for (int i = 0; i < size1; i++)
if (db1.getElem(i) != db2.getElem(i))
return false;
return true;
}
Now I want to run this code in .js file but when I do I get an error, missing ";" error. So how do I make this function javascript compatible ?
Thanks.
Unfortunately Javacript and Java are completely seperate languages, and the only thing which they have in common in the name, therefore this is impossible.
If you want to learn about doing something similar in javascript then take a look at the File API's: https://developer.mozilla.org/en-US/docs/DOM/File_APIs
You can't run Java code in JavaScript. You can either compile your Java code as an applet and embed that in you page, or you just rewrite your code in JS. If you use the html5 canvas and the getImageData() function, this should be doable. That way you can easily interact with your code from JavaScript.
It is somewhat possible to use Java classes and APIs in code that you write in JavaScript with Mozilla Rhino.
Rhino is simply a JS interpret written in Java that is bundled with the JDK. It basically allows you to use the Java APIs with JS syntax, but on the other hand, there is no DOM API available and you can't run such scripts in a Web browser. They are run by the JVM.

Easy way to include Rhino shell methods in scripts or to load other js scripts?

I'm trying to use the Rhino shell methods such as load, print, etc. My question is SIMILAR to this one, however, I DO NOT have access to the actual java code without hacking apart the framework itself (accela automation FWIW). I'd like to be able to easily add on other .js scripts such as jQuery. But the big caveat is that I only have access to the javascript scripts - not the actual java context. That being said - I can (of course) do the typical Rhino things such as call on java classes, objects, etc.
Has anyone done this or have any good ideas how I would go about it?
Seems this is what I was looking for:
var manager = new Packages.javax.script.ScriptEngineManager();
var engine = manager.getEngineByName( "js" );
var scriptFile = "/pathToScript/scriptFileName.js";
var eval = engine.eval( new Packages.java.io.FileReader( new Packages.java.io.File( " + scriptFile + " ) ) );

Call a java method from javascript in ie8 and chrome

I have been wondering if there is a way to make the following javascript functions work in IE8 and Chrome:
var funct = function()
{
var ppt = new java.awt.Point(200,100);
alert(ppt.x);
}
This thing works only in Firefox. Is there a way to enable global Java packages in IE 8 and Chrome?
Not quite answering your question - but you might find GWT (http://code.google.com/webtoolkit/) helpful.
It lets you write web applications in Java, which gets 'compiled' into javascript to be run inside any modern browser. It only supports a subset of the standard Java libraries - in particular it doesn't support java.awt.
Well, here it is. IE 8 and Chrome do not allow for global java packages:
i.e you cant use java.lang.String, or java.atw.Point directly in your javascript. However, if you have an applet, you can easily expose such classes through your applet. For example, if you import java.awt.Point in your applet and have a method like this:
public Point createPoint(int x,int y);
You should be able now from your javascript to access the applet and just call its method like this:
(javascript code)
var applet = document.getElementById("applettie");
var Point = applet.createPoint(20,30);
//now you have the Point object
Cheers

how to use java to get a js file and execute it and then get the result

How can I use java to get a js file located on a web server, then execute the function in the js file and get the result and use the result in java.
Can you guys give me some code snippet? Great thanks.
You can use the scripting engine built into Java:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public static void main(String[] args) throws Exception {
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
Object result = engine.eval("my-java-script-code")
System.out.println("Result returned by Javascript is: " + result);
}
Here is a more elaborate example.
There's three steps to this process:
Fetch the JS file from the server.
Execute some JS function from the file.
Extract the result.
The first step is fairly simple, there are lots of HTTP libraries in Java that will do this - you effectively want to emulate the simple functionality of something like wget or curl. The exact manner in which you do this will vary depending on what format you want the JS file in for the next step, but the process to get hold of the byte stream is straightforward.
The second step will require executing the JS in a Javascript engine. Java itself cannot interpret Javascript, so you'd need to obtain an engine to run it in - Rhino is a common choice for this. Since you'd need to run this outside of Java, you'll likely have to spawn a process for execution in Rhino using ProcessBuilder. Additionally, depending on the format of the Javascript you might need to create your own "wrapper" javascript that functions like a main class in Java and calls the method in question.
Finally you need to get the result out - obviously you don't have direct access to JavaScript objects from your Java program. The easiest way is going to be for the JS program to print the result to standard out (possibly serialising as something like JSON depending on the complexity of the object), which is being streamed directly to your Java app due to the way you launched the Rhino process. This could be another job for your JS wrapper script, if any. Otherwise, if the JS function has observable side effects (creates a file/modifies a database) then you'll be able to query those directly from Java.
Job done.
I hope you realise this question is far too vague to get full answers. Asking the public to design an entire system goes beyond the point where you'll get useful, actionable responses.
There are plenty of examples on the web of how to download a file from a URL.
Suns version of the JDK and JRE includes the Mozilla Rhino scripting engine.
Assuming you have stored the contents of the javascript file in a string called 'script', you can execute scripts as follows
String result = null;
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
try {
jsEngine.eval(script);
result = jsEngine.get("result")
} catch (ScriptException ex) {
ex.printStackTrace();
}
The result will be extracted from the engine and stored in the 'result' variable.
The is a tutorial on scripting in Java that might be useful.

Categories