function createButton() {
var n = 1;
var Graphics = Packages.android.graphics;
var font = Graphics.Typeface.create(
Graphics.Typeface.SANS_SERIF,
Graphics.Typeface.BOLD);
var button = new Packages.android.widget.Button(Activity);
button.setTypeface(font);
button.setTextSize(26);
button.setBackgroundColor(Graphics.Color.rgb(0, 0, 64));
button.setTextColor(Graphics.Color.rgb(255, 255, 255));
button.setText("How many times can you click me?");
button.setOnClickListener(function () {
button.setText("You clicked me " + n + " times!");
n = n + 1;
});
return button;
}
var layout = new Packages.android.widget.LinearLayout(Activity);
layout.setOrientation(Widget.LinearLayout.VERTICAL);
layout.addView(createButton());
layout.addView(createButton());
layout.addView(createButton());
Activity.setContentView(layout);
Friday, February 26, 2010
An example on the use of closures in JavaScript on Android
Here is a code example that illustrates the use of closures in JavaScript in an Android program. The variable n is introduced in the local scope of the function createButton, and is used in the closure for the button's click listener. Each button will have its own counter value, because each function invocation of createButton allocates its own space for the local variable n.
Sunday, February 21, 2010
More code examples
There is a new update of DroidScript available at http://droidscript.se
I have also included the following code examples in the editor:
I have also included the following code examples in the editor:
// Toast example program. Select this code and click Run.
var Toast = Packages.android.widget.Toast;
Toast.makeText(
Activity,
"Hello World!",
Toast.LENGTH_SHORT).show();
// Select this code and click Run. It will create a button in
// the server activity.
var Widget = Packages.android.widget;
var button = new Widget.Button(Activity);
button.setText("Hello World!");
button.setOnClickListener(function () {
button.setText("You Clicked Me!"); })
Activity.setContentView(button);
// You can also run code as a new Activity. Select this code
// and click "Run as Activity". A new DroidScript activity will
// be created, and the onCreate function is called.
function onCreate(icicle)
{
var Widget = Packages.android.widget;
var Graphics = Packages.android.graphics;
var font = Graphics.Typeface.create(
Graphics.Typeface.SANS_SERIF,
Graphics.Typeface.BOLD);
var button = new Widget.Button(Activity);
button.setText("Hello World!");
button.setTypeface(font);
button.setTextSize(26);
button.setBackgroundColor(Graphics.Color.rgb(0, 0, 64));
button.setTextColor(Graphics.Color.rgb(255, 255, 255));
button.setOnClickListener(function () {
button.setText("You Clicked Me!"); })
Activity.setContentView(button);
}
DroidScript GET requests
Besides using the editor at http://droidscript.se you can also enter urls directly in the brower. There are some encoding issues, but its an entertaining demonstration.
Start the DroidScript application on the device, press menu button, and select "Start server". The actual ip-address of the device is displayed on the screen; in the following examples it is 192.168.0.100. DroidScript listens on port 4042. Then open a web browser and enter the following urls (note that we must encode + as %2B):
Start the DroidScript application on the device, press menu button, and select "Start server". The actual ip-address of the device is displayed on the screen; in the following examples it is 192.168.0.100. DroidScript listens on port 4042. Then open a web browser and enter the following urls (note that we must encode + as %2B):
http://192.168.0.100:4042/eval/2*3
http://192.168.0.100:4042/eval/2%2B3
http://192.168.0.100:4042/eval/function twice(n) { return n * 2; }
http://192.168.0.100:4042/eval/twice(33)
http://192.168.0.100:4042/hello
Saturday, February 20, 2010
Java proxy classes in JavaScript on Android
The problem with running alternative (dynamic) languages on Android is that the Dalvik byte code format is different from the standard JVM format. Thus languages that do on-the-fly byte code generation won't work out of the box on Android. This also makes things more fun, since you can't just use the old and tired stuff you have always used. Room for new concepts!
Rhino, Mozilla's JavaScript engine, plays nicely on Android since it can run in interpreted-only-mode. Thus no need for generating Dalvik byte codes. But, to my great disappointment, it is not possible do subclassing in JavaScript on Android, because here byte code generation is required. It is not possible (as I understand it) to "hook into" the method call when Dalvik calls our Java object without having a proper Java class for the object.
Furthermore, it turns out that implementing interfaces cannot be done in Rhino without code generation. Interfaces that contain only one method, work fine, however. You just specify a JavaScript function object in place of the interface implementation. But with interfaces that have more than one method, you are toast (hehe, nice Android joke there). I have not yet got a good grasp of the inner workings of Rhino, but I am sure that this can be implemented using Java's Proxy classes, either in Rhino, or in the DroidScript app, or even in JavaScript.
I did some experimentation that kept me awake (it is now two a clock in the night here in Stockholm), and here is the result, in JavaScript. A particular tricky case was to make a proxy for an "inner" interface in JavaScript (whatever that is called in Java lingo). Of course, this could be done in Java and called from JavaScript, but it is more fun to use JavaScript all the way ;-)
And here we have our proxy class! Will continue to research this tomorrow and during the week.
Sleep well :-)
Rhino, Mozilla's JavaScript engine, plays nicely on Android since it can run in interpreted-only-mode. Thus no need for generating Dalvik byte codes. But, to my great disappointment, it is not possible do subclassing in JavaScript on Android, because here byte code generation is required. It is not possible (as I understand it) to "hook into" the method call when Dalvik calls our Java object without having a proper Java class for the object.
Furthermore, it turns out that implementing interfaces cannot be done in Rhino without code generation. Interfaces that contain only one method, work fine, however. You just specify a JavaScript function object in place of the interface implementation. But with interfaces that have more than one method, you are toast (hehe, nice Android joke there). I have not yet got a good grasp of the inner workings of Rhino, but I am sure that this can be implemented using Java's Proxy classes, either in Rhino, or in the DroidScript app, or even in JavaScript.
I did some experimentation that kept me awake (it is now two a clock in the night here in Stockholm), and here is the result, in JavaScript. A particular tricky case was to make a proxy for an "inner" interface in JavaScript (whatever that is called in Java lingo). Of course, this could be done in Java and called from JavaScript, but it is more fun to use JavaScript all the way ;-)
var Lang = Packages.java.lang;
var proxy = Lang.reflect.Proxy.getProxyClass(
Lang.ClassLoader.getSystemClassLoader(),
Packages.android.view.View.OnClickListener);
var proxy = Lang.reflect.Proxy.getProxyClass(
Lang.ClassLoader.getSystemClassLoader(),
Packages.android.view.View.OnClickListener);
And here we have our proxy class! Will continue to research this tomorrow and during the week.
Sleep well :-)
DroidScript - Live JavaScript on Android
I have spent the day with getting the DroidScript web based editor up and running. It is available here: http://droidscript.se (droidscript.org and droidscript.net will also work in the near future). The site has a QR-Code you can use for downloading and installing the app on your device.
The source code is on GitHub at http://github.com/divineprog/droidscript. The application consists of a core part written in Java, and the user interface which is written in JavaScript ("eat your own dog food!"). There are still many rough edges, but the project is great fun. I think this style of programming, directly on the device, has several benefits. It opens up for exploration, and incremental development. I envision that this style can be great fun for young people who want to learn to program on their Android device.
The JavaScript code of the app is in the droidscript directory on the sdcard. This means that you can edit these files and modify the program without having to install the Android SDK. Of course you can also write your own programs. Unfurtunately, it seems as if you cannot have the device connected and mounted via USB and at the same time have apps that access the sdcard. That would have been nice, because then you could have had the JavaScript code open in an editor on the computer and the program running while editing it. But the web based editor solve this problem.
The web based editor sends in requests to a tiny web server that is running on the device. It accepts PUT and GET requests with JavaScript as content. The code is evaluated by the Mozilla Rhino JavaScript engine, and the result is sent back to the web browser (including error messages). With this tool, it is possible to incrementally create the user interface and other components of a program. (I should make a YouTube video that shows how to do this!)
Next step is to implement missing parts and to make the app more stable and also to make error handling more roubust. Regarding other languages, besides JavaScript, it would be nice to make the interpreter pluggable. BeanShell, for example, would be rather easy to integrate into the program. Ruby would also be very nice to have.
The source code is on GitHub at http://github.com/divineprog/droidscript. The application consists of a core part written in Java, and the user interface which is written in JavaScript ("eat your own dog food!"). There are still many rough edges, but the project is great fun. I think this style of programming, directly on the device, has several benefits. It opens up for exploration, and incremental development. I envision that this style can be great fun for young people who want to learn to program on their Android device.
The JavaScript code of the app is in the droidscript directory on the sdcard. This means that you can edit these files and modify the program without having to install the Android SDK. Of course you can also write your own programs. Unfurtunately, it seems as if you cannot have the device connected and mounted via USB and at the same time have apps that access the sdcard. That would have been nice, because then you could have had the JavaScript code open in an editor on the computer and the program running while editing it. But the web based editor solve this problem.
The web based editor sends in requests to a tiny web server that is running on the device. It accepts PUT and GET requests with JavaScript as content. The code is evaluated by the Mozilla Rhino JavaScript engine, and the result is sent back to the web browser (including error messages). With this tool, it is possible to incrementally create the user interface and other components of a program. (I should make a YouTube video that shows how to do this!)
Next step is to implement missing parts and to make the app more stable and also to make error handling more roubust. Regarding other languages, besides JavaScript, it would be nice to make the interpreter pluggable. BeanShell, for example, would be rather easy to integrate into the program. Ruby would also be very nice to have.
Sunday, February 14, 2010
First version of DroidScript - JavaScript for Android
The first version of DroidScript is now on GitHub: http://github.com/divineprog/droidscript
Saturday, February 6, 2010
DroidScript - new name for RhinoDroid
I have decided to use the name DroidScript for the JavaScript Android tool I am developing. For now, I am blogging at divineprogrammer.blogspot.com, and twitter at @divineprog
I will use this blog to publish DroidScript documentation, code examples, and other related stuff.
DroidScript was previosly called RhinoDroid, as a tribute to the Rhino JavaScript interpreter/compiler developed by Mozilla, but I decided that DroidScript is a more on-the-spot name.
I will use this blog to publish DroidScript documentation, code examples, and other related stuff.
DroidScript was previosly called RhinoDroid, as a tribute to the Rhino JavaScript interpreter/compiler developed by Mozilla, but I decided that DroidScript is a more on-the-spot name.
Subscribe to:
Posts (Atom)