<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8771301318819126292</id><updated>2011-09-06T01:43:39.787-07:00</updated><category term='DroidScript'/><category term='JavaScript'/><category term='Android'/><title type='text'>DroidScript</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>18</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-2011410163568800191</id><published>2010-05-01T08:15:00.001-07:00</published><updated>2010-05-01T10:51:22.142-07:00</updated><title type='text'>DroidZine Comic</title><content type='html'>&lt;pre&gt;DROIDZINE_BEGIN&lt;br /&gt;page(&lt;br /&gt;    title("PMOCT: R1 P9"),&lt;br /&gt;    author("~annarowlye"),&lt;br /&gt;    image(&lt;br /&gt;"http://fc08.deviantart.net/fs70/f/2010/120/8/f/PMOCT__R1_P9_by_annarowlye.jpg"),&lt;br /&gt;    panel1(&lt;br /&gt;        box(0, 0, 292, 278),&lt;br /&gt;        moves(right(2), down(4))),&lt;br /&gt;    panel2(&lt;br /&gt;        box(292, 0, 252, 279),&lt;br /&gt;        moves(left(1), right(3), down(4))),&lt;br /&gt;    panel3(&lt;br /&gt;        box(538, 0, 262, 271),&lt;br /&gt;        moves(left(2), right(4), down(4))),&lt;br /&gt;    panel4(&lt;br /&gt;        box(0, 281, 408, 443),&lt;br /&gt;        moves(left(3), right(5), down(6))),&lt;br /&gt;    panel5(&lt;br /&gt;        box(406, 282, 396, 439),&lt;br /&gt;        moves(left(4), right(6), down(7))),&lt;br /&gt;    panel6(&lt;br /&gt;        box(4, 725, 390, 496),&lt;br /&gt;        moves(left(5), right(7), up(4))),&lt;br /&gt;    panel7(&lt;br /&gt;        box(404, 731, 396, 489), &lt;br /&gt;        moves(left(6), up(5))))&lt;br /&gt;DROIDZINE_END&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-2011410163568800191?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/2011410163568800191/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/05/droidzine-comic.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/2011410163568800191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/2011410163568800191'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/05/droidzine-comic.html' title='DroidZine Comic'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-6429445769760131360</id><published>2010-04-27T15:12:00.000-07:00</published><updated>2010-04-27T15:34:33.512-07:00</updated><title type='text'>A self generating Android program</title><content type='html'>&lt;p&gt;This is a more or less insane DroidScript program I prepared as a demo for a seminar on dynamic languages. The program generates a main activity with a list from which you can launch 10000 generated activities. The theme I had in mind was "Fortune Cards", but all I had time to do was a coloured oval. If I get some more time I will improve the program.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I recommend that you try with a smaller number if you want to run the program, say 100. I wanted to show that it is possible to create a really big program in JavaScript on Android in terms of the size of the scrolling list and the number of activities, and still get good performance.&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;var DroidScriptFileHandler = Packages.comikit.droidscript.DroidScriptFileHandler;&lt;br /&gt;var Intent = Packages.android.content.Intent;&lt;br /&gt;&lt;br /&gt;function createAppScript()&lt;br /&gt;{&lt;br /&gt;    return """function onCreate(bundle)&lt;br /&gt;    {&lt;br /&gt;        var lang = Packages.java.lang;&lt;br /&gt;        var android = Packages.android;&lt;br /&gt;        var widget = Packages.android.widget;&lt;br /&gt;&lt;br /&gt;        var listView = new widget.ListView(Activity);&lt;br /&gt;        &lt;br /&gt;        var numberOfCards = 10000;&lt;br /&gt;        var cards = lang.reflect.Array.newInstance(lang.String, numberOfCards);&lt;br /&gt;        for (var i = 0; i &lt; numberOfCards; ++i)&lt;br /&gt;        {&lt;br /&gt;            cards[i] = "Card " + (i + 1);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        var arrayAdapter =&lt;br /&gt;            new widget.ArrayAdapter(Activity,&lt;br /&gt;               android.R.layout.simple_list_item_1,&lt;br /&gt;               cards);&lt;br /&gt;&lt;br /&gt;        listView.setAdapter(arrayAdapter);&lt;br /&gt;        &lt;br /&gt;        listView.setOnItemClickListener(function(parent, view, position, id) {&lt;br /&gt;            var Intent = Packages.android.content.Intent;&lt;br /&gt;            var DroidScriptFileHandler = Packages.comikit.droidscript.DroidScriptFileHandler;&lt;br /&gt;            var script = DroidScriptFileHandler.create().readStringFromFileOrUrl(&lt;br /&gt;                "droidscript/generated/Card" + position + ".js");&lt;br /&gt;            var intent = new Intent();&lt;br /&gt;            intent.setClassName(Activity, "comikit.droidscript.DroidScriptActivity");&lt;br /&gt;            intent.putExtra("Script", script);&lt;br /&gt;            Activity.startActivity(intent);&lt;br /&gt;        });&lt;br /&gt;&lt;br /&gt;        Activity.setContentView(listView);&lt;br /&gt;    }&lt;br /&gt;    """;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function createCardScript()&lt;br /&gt;{&lt;br /&gt;    function random255() { return Math.random() * 255; }&lt;br /&gt;        &lt;br /&gt;    var script = """function onCreate(bundle)&lt;br /&gt;    {&lt;br /&gt;        var lang = Packages.java.lang;&lt;br /&gt;        var android = Packages.android;&lt;br /&gt;        var widget = Packages.android.widget;&lt;br /&gt;        var Morph = Packages.comikit.droidscript.Morph;&lt;br /&gt;        var Paint = Packages.android.graphics.Paint;&lt;br /&gt;        var Color = Packages.android.graphics.Color;&lt;br /&gt;        var RectF = Packages.android.graphics.RectF;&lt;br /&gt;                &lt;br /&gt;        var morph = new Morph(Activity);&lt;br /&gt;        var width = 100;&lt;br /&gt;        var height = 100;&lt;br /&gt;        &lt;br /&gt;        morph.setOnDrawListener(function(canvas)&lt;br /&gt;        {""";&lt;br /&gt;     &lt;br /&gt;     var red = random255();&lt;br /&gt;     var green = random255();&lt;br /&gt;     var blue = random255();&lt;br /&gt;     &lt;br /&gt;     script += """&lt;br /&gt;         var brushColor = Color.rgb(""" &lt;br /&gt;            + red + ", " + green + ", " + blue + """);&lt;br /&gt;         var paint = new Paint();&lt;br /&gt;         paint.setColor(brushColor);&lt;br /&gt;         paint.setStyle(Paint.Style.FILL);&lt;br /&gt;         paint.setAntiAlias(true);&lt;br /&gt;         canvas.drawOval(&lt;br /&gt;             new RectF(&lt;br /&gt;                 0,&lt;br /&gt;                 0,&lt;br /&gt;                 width,&lt;br /&gt;                 height),&lt;br /&gt;                 paint);""";&lt;br /&gt;                &lt;br /&gt;     script += """});&lt;br /&gt;        &lt;br /&gt;        morph.setOnSizeChangedListener(function(w, h, oldw, oldh)&lt;br /&gt;        {&lt;br /&gt;            width = w;&lt;br /&gt;            height = h;&lt;br /&gt;            morph.invalidate();&lt;br /&gt;        });&lt;br /&gt;        &lt;br /&gt;        Activity.setContentView(morph);&lt;br /&gt;    }""";&lt;br /&gt;    &lt;br /&gt;    return script;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function launch(script)&lt;br /&gt;{&lt;br /&gt;    var intent = new Intent();&lt;br /&gt;    intent.setClassName(Activity, "comikit.droidscript.DroidScriptActivity");&lt;br /&gt;    intent.putExtra("Script", script);&lt;br /&gt;    Activity.startActivity(intent);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Create directory&lt;br /&gt;var directory = "droidscript/generated/";&lt;br /&gt;var fileHandler = DroidScriptFileHandler.create();&lt;br /&gt;fileHandler.externalStorageCreateDirectory("droidscript/generated/");&lt;br /&gt;    &lt;br /&gt;// Generate main script&lt;br /&gt;fileHandler.writeStringToFile(directory + "CardApp.js", createAppScript());&lt;br /&gt;&lt;br /&gt;// Generate card scripts&lt;br /&gt;for (var i = 0; i &lt; 10000; ++i)&lt;br /&gt;{&lt;br /&gt;    fileHandler.writeStringToFile(&lt;br /&gt;        directory + "Card" + i + ".js", createCardScript());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;// I suggest you first run the above code in the editor at &lt;a href="http://droidscript.se"&gt;droidscript.se&lt;/a&gt;, &lt;br /&gt;// then launch the app. And I strongly recommend to try a smaller number &lt;br /&gt;// of "cards", say 100.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;// Launch app&lt;br /&gt;launch(DroidScriptFileHandler.create().readStringFromFileOrUrl(&lt;br /&gt;    "droidscript/generated/CardApp.js"));&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-6429445769760131360?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/6429445769760131360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/04/self-generating-android-program.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/6429445769760131360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/6429445769760131360'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/04/self-generating-android-program.html' title='A self generating Android program'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-1123530985547450963</id><published>2010-04-23T15:10:00.000-07:00</published><updated>2010-04-23T15:10:01.598-07:00</updated><title type='text'>Deploying DroidScript Apps</title><content type='html'>Have made a first test on how to deploy a DroidScript program as a "native" Android application. The app is a demo that illustrates how comic strip formats on Android. Download info can be found at: &lt;a href="http://comikit.se/"&gt;http://comikit.se&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Will get back with instructions on how the app is built. All files, both JavaScript files and images are included in the app as assets. A tiny Java activity starts the main script.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-1123530985547450963?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/1123530985547450963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/04/deploying-droidscript-apps.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/1123530985547450963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/1123530985547450963'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/04/deploying-droidscript-apps.html' title='Deploying DroidScript Apps'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-5524898072646018271</id><published>2010-04-11T09:09:00.000-07:00</published><updated>2010-04-11T09:10:32.406-07:00</updated><title type='text'>Multiline strings and using DroidScript with WebKit</title><content type='html'>After a walk in the sun, I have uploaded yet a new DroidScript version, have made various enhancements, including multiline strings. JavaScript does not have multiline strings, so I have added that to DroidScript. The syntax is similar to Python, with three quotes to begin and terminate a multiline string.&lt;br /&gt;&lt;br /&gt;Below is an example that uses this feature. The example shows how to make a DroidScript app that opens a WebView (a WebKit browser) and displays an HTML document encoded as a multiline string. The example also shows how to use addJavascriptInterface to import Java objects into the WebView, and how to make calls from JavaScript in the HTML document to DroidScript. The JavaScript in the HTML document is executed by the WebKit JavaScript engine, and does not have direct access to the Android class library. The JavaScript code that gets evaluated by DroidScript executes on Rhino, and can therefore use the Android API directly.&lt;br /&gt;&lt;br /&gt;The short link to this script is: http://bit.ly/bL1heJ&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;DROIDSCRIPT_BEGIN&lt;br /&gt;function onCreate(bubble)&lt;br /&gt;{&lt;br /&gt;    var WebView = Packages.android.webkit.WebView;&lt;br /&gt;&lt;br /&gt;    var webview = new WebView(Activity);&lt;br /&gt;    webview.getSettings().setJavaScriptEnabled(true);&lt;br /&gt;    webview.addJavascriptInterface(Activity, &amp;quot;activity&amp;quot;);&lt;br /&gt;    Activity.setContentView(webview);    &lt;br /&gt;    &lt;br /&gt;    var content =&lt;br /&gt;    &amp;quot;&amp;quot;&amp;quot;&amp;lt;html&amp;gt;&lt;br /&gt;        &amp;lt;body&amp;gt;&lt;br /&gt;            &amp;lt;script&amp;gt;&lt;br /&gt;            function showToast(message) {&lt;br /&gt;                activity.eval(&lt;br /&gt;                    &amp;quot;var Toast = Packages.android.widget.Toast;&amp;quot; +&lt;br /&gt;                    &amp;quot;Toast.makeText(Activity, '&amp;quot; + message + &amp;quot;', &amp;quot; +&lt;br /&gt;                    &amp;quot;Toast.LENGTH_SHORT).show();&amp;quot;); }&lt;br /&gt;            &amp;lt;/script&amp;gt;&lt;br /&gt;            &amp;lt;h1&amp;gt;Take the pill&amp;lt;/h1&amp;gt;&lt;br /&gt;            &amp;lt;input &lt;br /&gt;                type=&amp;quot;button&amp;quot; &lt;br /&gt;                value=&amp;quot;Take pill&amp;quot; &lt;br /&gt;                onclick=&amp;quot;showToast('You have taken the red pill!')&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;/body&amp;gt;&lt;br /&gt;    &amp;lt;/html&amp;gt;&amp;quot;&amp;quot;&amp;quot;;&lt;br /&gt;    &lt;br /&gt;    webview.loadData(content, &amp;quot;text/html&amp;quot;, &amp;quot;utf-8&amp;quot;);&lt;br /&gt;}&lt;br /&gt;DROIDSCRIPT_END&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-5524898072646018271?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/5524898072646018271/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/04/multiline-strings-and-using-droidscript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/5524898072646018271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/5524898072646018271'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/04/multiline-strings-and-using-droidscript.html' title='Multiline strings and using DroidScript with WebKit'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-6571214155975436014</id><published>2010-04-11T03:52:00.000-07:00</published><updated>2010-04-11T04:11:10.604-07:00</updated><title type='text'>Now it is easy to distribute DroidScript scripts</title><content type='html'>I have uploaded a new version of DroidScript that has a feature for easily distributing DroidScript scripts. With a new pair of tags, you can publish scripts on any web page (like this blog) and open and run them from the DroidScript app on your Android device.&lt;br /&gt;&lt;br /&gt;It is as easy as opening a web page, and that said, this is also an easy way of distributing malicious code. &lt;br /&gt;&lt;br /&gt;BE VERY CAREFUL WITH WHAT YOU DOWNLOAD!&lt;br /&gt;&lt;br /&gt;I will say this again, because it is important:&lt;br /&gt;&lt;br /&gt;BE VERY CAREFUL WITH WHAT YOU DOWNLOAD!&lt;br /&gt;&lt;br /&gt;At present, DroidScript has the following permissions:&lt;br /&gt;&lt;br /&gt;android.permission.INTERNET&lt;br /&gt;android.permission.WRITE_EXTERNAL_STORAGE&lt;br /&gt;android.permission.CAMERA&lt;br /&gt;android.permission.ACCESS_FINE_LOCATION&lt;br /&gt;&lt;br /&gt;So a script could erase your files, mess with your camera, and so on.&lt;br /&gt;&lt;br /&gt;That said, I think this is a really cool feature, and it shows how powerful dynamic languages are when it comes to ease of distributing and running programs. And with improved security handling, the risks of distributing scripts could be reduced.&lt;br /&gt;&lt;br /&gt;I do like the openness of the web, and native apps are sadly not open for inspection and modification by the user. With DroidScript, the script is always available for preview and modification in the editor on the device before you decide to run it. Still, it is a big security risk to be open, but so much more fun. It is like life, a life without risk taking is no life. &lt;br /&gt;&lt;br /&gt;DroidScript is an ongoing experiment, and it is possible to package a program in alternative ways. You could, for instance, embed DroidScript in a native Android app, store JavaScript files in the application space (as resources or files), and no one would be able to tamper with the scripts or download new scripts, and the user would not even notice that the app is written in JavaScript.&lt;br /&gt;&lt;br /&gt;Now for an example:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;DROIDSCRIPT_BEGIN&lt;br /&gt;function onCreate(bubble)&lt;br /&gt;{&lt;br /&gt;    var Button = Packages.android.widget.Button;&lt;br /&gt;    var Color = Packages.android.graphics.Color;&lt;br /&gt;    var Typeface = Packages.android.graphics.Typeface;&lt;br /&gt;&lt;br /&gt;    var numberOfClicks = 0;&lt;br /&gt;    var font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);&lt;br /&gt;    var button = new Button(Activity);&lt;br /&gt;    button.setText("Hello World!");&lt;br /&gt;    button.setTypeface(font);&lt;br /&gt;    button.setTextSize(26);&lt;br /&gt;    button.setBackgroundColor(Color.rgb(0, 0, 64));&lt;br /&gt;    button.setTextColor(Color.rgb(255, 255, 255));&lt;br /&gt;    button.setOnClickListener(function () {&lt;br /&gt;        ++numberOfClicks;&lt;br /&gt;        button.setText(&lt;br /&gt;            "You Clicked Me" +&lt;br /&gt;            (1 == numberOfClicks ? "!" : &lt;br /&gt;                " " + numberOfClicks + " Times!")); })&lt;br /&gt;    Activity.setContentView(button);&lt;br /&gt;}&lt;br /&gt;DROIDSCRIPT_END&lt;/code&gt;&lt;/pre&gt;How to run the above program:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Download the latest DroidScript app (instructions are found &lt;a href="http://droidscript.blogspot.com/2010/03/droidscript-getting-started.html"&gt;here&lt;/a&gt;)&amp;nbsp;&lt;/li&gt;&lt;li&gt;Start the app and select "Open script" in the options menu&lt;/li&gt;&lt;li&gt;Enter the short url to this page: http://bit.ly/9kFqEi &lt;/li&gt;&lt;li&gt;Then press "Run Activity" &lt;/li&gt;&lt;/ul&gt;(The short url is quicker to type on the device)&lt;br /&gt;&lt;br /&gt;DroidScript will find the code between the tags and filter out the rest of the web page. This makes it very easy to publish scripts embedded on blogs and other web pages. You can of course also put your script in a plain text file and upload that to the web, then you will not need the begin and end tags.&lt;br /&gt;&lt;br /&gt;Since a script can open images over the internet, and open other scripts, it is possible to create truly dynamic applications that have the capabilities of native Android applications and the dynamic flow and instant access of web pages.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-6571214155975436014?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/6571214155975436014/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/04/now-it-is-easy-to-distribute.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/6571214155975436014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/6571214155975436014'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/04/now-it-is-easy-to-distribute.html' title='Now it is easy to distribute DroidScript scripts'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-7872027185128868835</id><published>2010-04-11T02:19:00.000-07:00</published><updated>2010-04-14T12:55:56.284-07:00</updated><title type='text'>Android CameraPreview sample in JavaScript</title><content type='html'>Here is a DroidScript program that displays preview images from the camera. I have taken the &lt;a href="http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html"&gt;CameraPreview&lt;/a&gt; sample program and rewritten it in JavaScript.&lt;br /&gt;&lt;br /&gt;Beware! This program runs fine on Motorola Droid :-) but crashes on Nexus One :-( &lt;br /&gt;&lt;br /&gt;Update: @JonasBeckman hinted that uncommenting camera.setParameters(parameters); when running on Nexus One does the trick. I tested and it works fine! :-)&lt;br /&gt;&lt;br /&gt;To run this program, open the DroidScript app, and select the "Open script" menu item, and enter the short url to this blog post: http://bit.ly/aB2fik&lt;br /&gt;&lt;br /&gt;DroidScript will recognise the DROIDSCRIPT&amp;#95;BEGIN and DROIDSCRIPT&amp;#95;END tags and extract the code between the tags. Then press the "Run Activity" button to run the program. &lt;br /&gt;&lt;br /&gt;Note that these tags can occur only once on a page. If there are multiple occurrences, the text between the first pair will be used. Therefore, I have escaped the underscore character in the tags above, so that they will not be interpreted as containing DroidScript code.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;DROIDSCRIPT_BEGIN&lt;br /&gt;var Camera = Packages.android.hardware.Camera;&lt;br /&gt;var SurfaceHolder = Packages.android.view.SurfaceHolder;&lt;br /&gt;var SurfaceView = Packages.android.view.SurfaceView;&lt;br /&gt;var Window = Packages.android.view.Window;&lt;br /&gt;&lt;br /&gt;function onCreate(bundle)&lt;br /&gt;{&lt;br /&gt;    Activity.requestWindowFeature(Window.FEATURE_NO_TITLE);&lt;br /&gt;    var preview = createPreviewSurface();&lt;br /&gt;    Activity.setContentView(preview.getSurfaceView());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function createPreviewSurface()&lt;br /&gt;{&lt;br /&gt;    var camera = null;&lt;br /&gt;    var surface = new SurfaceView(Activity);&lt;br /&gt;    &lt;br /&gt;    var object = {&lt;br /&gt;        &lt;br /&gt;        getSurfaceView : function() {&lt;br /&gt;            return surface; },&lt;br /&gt;            &lt;br /&gt;        surfaceCreated : function(holder) {&lt;br /&gt;            camera = Camera.open();&lt;br /&gt;            try {&lt;br /&gt;                camera.setPreviewDisplay(holder); }&lt;br /&gt;            catch (exception) {&lt;br /&gt;                camera.release();&lt;br /&gt;                camera = null; } },&lt;br /&gt;                &lt;br /&gt;        surfaceDestroyed : function(holder) {&lt;br /&gt;            camera.stopPreview();&lt;br /&gt;            camera.release();&lt;br /&gt;            camera = null; },&lt;br /&gt;            &lt;br /&gt;        surfaceChanged : function(holder, format, w, h) {&lt;br /&gt;            var parameters = camera.getParameters();&lt;br /&gt;            parameters.setPreviewSize(w, h);&lt;br /&gt;            // Causes camera to fail on Nexus One&lt;br /&gt;            //camera.setParameters(parameters);&lt;br /&gt;            camera.startPreview(); }&lt;br /&gt;    };&lt;br /&gt; &lt;br /&gt;    var callback = createInstance(&lt;br /&gt;        Packages.android.view.SurfaceHolder.Callback, &lt;br /&gt;        object);&lt;br /&gt;    surface.getHolder().addCallback(callback);&lt;br /&gt;    surface.getHolder().setType(&lt;br /&gt;        SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);&lt;br /&gt;&lt;br /&gt;    return object;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Create an instance of a Java interface.&lt;br /&gt;//   javaInterface - the interface type&lt;br /&gt;//   object - JS object that will receive messages&lt;br /&gt;//     sent to the instance&lt;br /&gt;function createInstance(javaInterface, object)&lt;br /&gt;{&lt;br /&gt;    // Convert a Java array to a JavaScript array&lt;br /&gt;    function javaArrayToJsArray(javaArray)&lt;br /&gt;    {&lt;br /&gt;        var jsArray = [];&lt;br /&gt;        for (var i = 0; i &amp;lt; javaArray.length; ++i) {&lt;br /&gt;            jsArray[i] = javaArray[i];&lt;br /&gt;        }&lt;br /&gt;        return jsArray;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    var lang = Packages.java.lang;&lt;br /&gt;    var interfaces = &lt;br /&gt;        lang.reflect.Array.newInstance(lang.Class, 1);&lt;br /&gt;    interfaces[0] = javaInterface;&lt;br /&gt;    var obj = lang.reflect.Proxy.newProxyInstance(&lt;br /&gt;        lang.ClassLoader.getSystemClassLoader(),&lt;br /&gt;        interfaces,&lt;br /&gt;        // Note, args is a Java array.&lt;br /&gt;        function(proxy, method, args) {&lt;br /&gt;            // Convert Java array to JavaScript array&lt;br /&gt;            return object[method.getName()].apply(&lt;br /&gt;                null,&lt;br /&gt;                javaArrayToJsArray(args));&lt;br /&gt;        });&lt;br /&gt;    return obj;&lt;br /&gt;}&lt;br /&gt;DROIDSCRIPT_END&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-7872027185128868835?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/7872027185128868835/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/04/android-camerapreview-sample-in.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/7872027185128868835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/7872027185128868835'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/04/android-camerapreview-sample-in.html' title='Android CameraPreview sample in JavaScript'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-2308679280940021826</id><published>2010-04-05T11:17:00.000-07:00</published><updated>2010-04-05T11:17:05.513-07:00</updated><title type='text'>Version 4 of DroidScript</title><content type='html'>Uploaded version 4 of DroidScript today, including new example programs! (I use plain sequential version numbers; version 4 is very much in an early experimental stage!) Download info can be found here: &lt;a href="http://droidscript.blogspot.com/2010/03/droidscript-getting-started.html"&gt;http://droidscript.blogspot.com/2010/03/droidscript-getting-started.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you already have DroidScript installed, you need to manually update the JavaScript files on the SD-card. One method is to delete the JavaScript files in the droidscript folder on the SD-card; if they are missing when the app started, they will be downloaded automatically. An easier method is to open DroidScript, press the menu button on the device, and select "Update". That will download and overwrite the JavaScript files in the droidscript folder with the latest versions. Then restart DroidScript.&lt;br /&gt;&lt;br /&gt;This whole process can of course be improved. One idea is to make DroidScript check the update server for a new version number, and update the JavaScript code if needed. Admittedly, it is a bit of a hazzle to keep track of updating the actual app and the JavaScript files on the SD-card. But there is also a reason for making manual updates; the user might have modified the JavaScript code, and may wish to save the modifications before updating.&lt;br /&gt;&lt;br /&gt;The motivation for putting JavaScript files on the SD-card is highest possible transparency. A user always has access to the content of the card, and can easily inspect and edit the JavaScript code if she wishes. This way, DroidScript is much more malleable and exploration-friendly, compared to putting the code hidden away in the application's private space. The drawback is that files might be messed up, and if you swap SD-cards the files are not there anymore (buy then they will be dynamically downloaded).&lt;br /&gt;&lt;br /&gt;New in this version is improved error handling, a new view class for writing graphical applications, and more examples programs.&lt;br /&gt;&lt;br /&gt;Errors are now trapped in a more robust way, and the application does no longer shut down in case of runtime JavaScript errors. The notification bar is used to display JavaScript errors. It is a big advantage that notifications are decoupled from the application, so if the application becomes faulty, it is still possible to retrieve the error message form the notification bar. Errors are also logged to the logcat output.&lt;br /&gt;&lt;br /&gt;A problem with scripting Java from JavaScript on Android is that there is no support for generating Dalvik byte code, and this is needed for subclassing. This means that subclassing of Java classes in JavaScript is not possible. Since the Android API relies heavily on subclassing in certain areas, this sort of spoils the party. Subclassing View to create your own view class with custom drawing, is impossible, for example. However, a nice solution is to make a subclass of View in Java that has pluggable listeners for drawing and other events that normally would be handled through subclassing. This way, we also get a much nice design that allows for runtime configuration of for example the drawing behaviour (subclassing is one nasty compile-time bound relation that I would be happy to avoid and replace by delegation).&lt;br /&gt;&lt;br /&gt;The new DroidScript version includes a Java class called Morph that has pluggable listeners for drawing and interaction behaviours, which makes it possible to write JavaScript apps with custom graphical rendering, such as games and painting programs. The name "Morph" means "Shape" and is taken from Self/Squeak; but the DroidScript Morph is nowhere nearly as powerful as a Squeak morph, but it might be one day :-)&lt;br /&gt;&lt;br /&gt;There are two new example programs included with the version of DroidScript, a program that displays random colours when the screen is pressed, and a painting program. The speed of the painting program shows that JavaScript applications can run at satisfactory speed on Android (at least on a Nexus One).&lt;br /&gt;&lt;br /&gt;Here is the source code of the example programs:&lt;br /&gt;&lt;a href="http://github.com/divineprog/droidscript/blob/master/javascript/Colors.js"&gt;http://github.com/divineprog/droidscript/blob/master/javascript/Colors.js&lt;/a&gt; &lt;br /&gt;&lt;a href="http://github.com/divineprog/droidscript/blob/master/javascript/Paint.js"&gt;http://github.com/divineprog/droidscript/blob/master/javascript/Paint.js&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The example programs are included in the latest version of DroidScript, so you can run them directly on the device, and you can also copy and paste them into the DroidScript Live Editor and run them from there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-2308679280940021826?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/2308679280940021826/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/04/version-4-of-droidscript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/2308679280940021826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/2308679280940021826'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/04/version-4-of-droidscript.html' title='Version 4 of DroidScript'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-7684434919189213062</id><published>2010-03-28T06:49:00.000-07:00</published><updated>2010-04-11T03:23:18.271-07:00</updated><title type='text'>Getting Started with DroidScript</title><content type='html'>DroidScript is a tool for programming Android applications in JavaScript. &lt;br /&gt;&lt;br /&gt;Start by installing the DroidScript app on your device. Scan this QR-code to install the app (use Barcode Scanner by ZXing, which is available at Android Market):&lt;br /&gt;&lt;br /&gt;&lt;img alt="qrcode" src="http://qrcode.kaywa.com/img.php?s=5&amp;amp;d=http%3A%2F%2Fdroidscript.se%2FDroidScript.apk" /&gt;&lt;br /&gt;&lt;br /&gt;Alternatively, download using this link (works in the browser on the device):&lt;br /&gt;&lt;a href="http://droidscript.se/DroidScript.apk"&gt;http://droidscript.se/DroidScript.apk&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can edit and run scripts on the device from a web browser with the DroidScript Live Editor: &lt;a href="http://droidscript.se/" target="_blank"&gt;http://droidscript.se&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The Live Editor contains some sample code and instructions to get you started.&lt;br /&gt;&lt;br /&gt;You can also edit scripts directly on the device, but this is not yet fully developed; the editor is very primitive and you cannot save scripts, for example.&lt;br /&gt;&lt;br /&gt;If you want to constribute to the project or browse the source code for the DroidScript app, the code is at GitHub: &lt;a href="http://github.com/divineprog/droidscript/" target="_blank"&gt;http://github.com/divineprog/droidscript&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;When you update the DroidScript app, you will also need to update the associated script files. Do this by seleting "Update" in the options menu. Then restart the DroidScript app.&lt;br /&gt;&lt;br /&gt;Contact info:&lt;br /&gt;Email: mikael.kindborg at gmail&lt;br /&gt;Twitter: &lt;a href="http://twitter.com/divineprog" target="_blank"&gt;http://twitter.com/divineprog&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-7684434919189213062?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/7684434919189213062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/03/droidscript-getting-started.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/7684434919189213062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/7684434919189213062'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/03/droidscript-getting-started.html' title='Getting Started with DroidScript'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-7872707111504240235</id><published>2010-03-21T14:18:00.000-07:00</published><updated>2010-04-04T04:22:00.582-07:00</updated><title type='text'>Custom ListAdapter in JavaScript on Android using a Java Proxy</title><content type='html'>At present, it is a big hazzle to program Android in purely interpreted languages, like JavaScript on the Mozilla Rhino engine. The catch is of course that Dalvik byte code generation is not (yet) implemented by any dynamic language engine, including Rhino. Still, it is possible to do all sorts of cool things with JavaScript on Android.&lt;br /&gt;&lt;br /&gt;Today (which means Sunday, and in Stockholm is has been snowing!), I have been working on using Java Proxy as a way to dynamically implement interfaces in JavaScript. My need for this arose from wanting to implement a custom ListAdapter for use with a ListView (see previous post for some more background to the issues involved). It would be possible to implement everything that is needed in Java, but it is much more fun to stretch the limits of what is possible to do in JavaScript. And it is a great learning experience. &lt;br /&gt;&lt;br /&gt;The interactive web based DroidScript editor has been invaluable when experimenting with JavaScript on Android. I have my phone next to the computer, edit and run code from Firefox on the computer, and interact with the result on the phone. This is a quite nice way to work. Error handling still leaves much more to wish for in DroidScript. It is sometimes tricky to find errors, and hooking up with a USB cable and using logcat is a big help to track down exceptions. Good, readable error reporting is an important area to improve upon. But, since you typically evaluate small pieces of code when developing incrementally, it is usually easy to spot errors. &lt;br /&gt;&lt;br /&gt;The following is a complete example that can run from the DroidScript editor. Make sure the DroidScript server is running on the device, paste the code into the editor, select it, and then click "Run as Activity". &lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;function onCreate(bundle)&lt;br /&gt;{&lt;br /&gt;    var lang = Packages.java.lang;&lt;br /&gt;    var android = Packages.android;&lt;br /&gt;    var widget = Packages.android.widget;&lt;br /&gt;    var Typeface = Packages.android.graphics.Typeface;&lt;br /&gt;    var Color = Packages.android.graphics.Color;&lt;br /&gt;    &lt;br /&gt;    var listView = new widget.ListView(Activity);&lt;br /&gt;    var fruits  = ["Lemon", "Peach", "Plum"];&lt;br /&gt;    &lt;br /&gt;    listView.setAdapter(createListViewArrayAdapter(&lt;br /&gt;        fruits,&lt;br /&gt;        function(position, convertView) {&lt;br /&gt;            var view = convertView;&lt;br /&gt;            if (null == convertView) {&lt;br /&gt;                view = new widget.TextView(Activity);&lt;br /&gt;                view.setPadding(25, 15, 25, 15);&lt;br /&gt;                var font = Typeface.create(&lt;br /&gt;                    Typeface.SANS_SERIF, &lt;br /&gt;                    Typeface.BOLD);&lt;br /&gt;                view.setTypeface(font);&lt;br /&gt;                view.setTextSize(26);&lt;br /&gt;                view.setBackgroundColor(Color.rgb(0, 0, 64));&lt;br /&gt;                view.setTextColor(Color.rgb(255, 255, 255));&lt;br /&gt;                // It is also possible to put actions on list items&lt;br /&gt;                //view.setOnClickListener(function () {&lt;br /&gt;                //    view.setText("You Clicked Me!"); })&lt;br /&gt;            }&lt;br /&gt;            view.setText(fruits[position]);&lt;br /&gt;            return view; }));&lt;br /&gt;    listView.setOnItemClickListener(function(parent, view, position, id) {&lt;br /&gt;        showMessage("You picked: " + fruits[position]); });&lt;br /&gt;    &lt;br /&gt;    Activity.setContentView(listView);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Display a Toast on the device&lt;br /&gt;function showMessage(message)&lt;br /&gt;{&lt;br /&gt;    var Toast = Packages.android.widget.Toast;&lt;br /&gt;    Toast.makeText(&lt;br /&gt;        Activity,&lt;br /&gt;        message,&lt;br /&gt;        Toast.LENGTH_LONG).show();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Convert a Java array to a JavaScript array&lt;br /&gt;function javaArrayToJsArray(javaArray)&lt;br /&gt;{&lt;br /&gt;    var jsArray = [];&lt;br /&gt;    for (i = 0; i &amp;lt; javaArray.length; ++i) {&lt;br /&gt;        jsArray[i] = javaArray[i];&lt;br /&gt;    }&lt;br /&gt;    return jsArray;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Create an instance of a Java interface&lt;br /&gt;// javaInterface - the interface type&lt;br /&gt;// handler - object that will be sent messages to the instance&lt;br /&gt;function createInstance(javaInterface, handler)&lt;br /&gt;{&lt;br /&gt;    var lang = Packages.java.lang;&lt;br /&gt;    var interfaces = lang.reflect.Array.newInstance(lang.Class, 1);&lt;br /&gt;    interfaces[0] = javaInterface;&lt;br /&gt;    var obj = lang.reflect.Proxy.newProxyInstance(&lt;br /&gt;        lang.ClassLoader.getSystemClassLoader(),&lt;br /&gt;        interfaces,&lt;br /&gt;        // Note, args is a Java array.&lt;br /&gt;        function(proxy, method, args) {&lt;br /&gt;            // Convert Java array to JavaScript array&lt;br /&gt;            return handler[method.getName()].apply(&lt;br /&gt;                null,&lt;br /&gt;                javaArrayToJsArray(args));&lt;br /&gt;        });&lt;br /&gt;    return obj;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Creates a custom ListAdapter&lt;br /&gt;// items - a JavaScript array&lt;br /&gt;// viewFun - a function called to handle the creation &lt;br /&gt;// of views for the elements in the list&lt;br /&gt;function createListViewArrayAdapter(items, viewFun)&lt;br /&gt;{&lt;br /&gt;    var lang = Packages.java.lang;&lt;br /&gt;    var widget = Packages.android.widget;&lt;br /&gt;    var observer;&lt;br /&gt;    &lt;br /&gt;    var handler = {&lt;br /&gt;        areAllItemsEnabled : function() {&lt;br /&gt;            return lang.Boolean.TRUE; },&lt;br /&gt;        isEnabled : function(position) {&lt;br /&gt;            return lang.Boolean.TRUE; },&lt;br /&gt;        getCount : function() {&lt;br /&gt;            return lang.Integer.valueOf(items.length); },&lt;br /&gt;        getItem : function(position) {&lt;br /&gt;            return items[position]; },&lt;br /&gt;        getItemId : function(position) {&lt;br /&gt;            return lang.Long.valueOf(position); },&lt;br /&gt;        getItemViewType : function(position) {&lt;br /&gt;            return lang.Integer.valueOf(0); },&lt;br /&gt;        getView : function(position, convertView, parent) {&lt;br /&gt;            return viewFun(position, convertView); },&lt;br /&gt;        getViewTypeCount : function(position) {&lt;br /&gt;            return lang.Integer.valueOf(1); },&lt;br /&gt;        hasStableIds : function(position) {&lt;br /&gt;            return true; },&lt;br /&gt;        isEmpty : function(position) {&lt;br /&gt;            return 0 == items.length; },&lt;br /&gt;        // We can only have one observer!&lt;br /&gt;        registerDataSetObserver : function(theObserver) {&lt;br /&gt;            observer = theObserver; },&lt;br /&gt;        unregisterDataSetObserver : function(theObserver) {&lt;br /&gt;            observer = null; },&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;    return createInstance(Packages.android.widget.ListAdapter, handler);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-7872707111504240235?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/7872707111504240235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/03/custom-listadapter-in-using-java-proxy.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/7872707111504240235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/7872707111504240235'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/03/custom-listadapter-in-using-java-proxy.html' title='Custom ListAdapter in JavaScript on Android using a Java Proxy'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-2522063416792924128</id><published>2010-03-21T06:49:00.000-07:00</published><updated>2010-03-21T14:38:33.397-07:00</updated><title type='text'>How to make a simple ListView</title><content type='html'>I have been frustrated about the fact that all of the handy adapter classes used with ListView take a resource id for the view to be used to present list items. When scripting Android, you typically do not create the layout using XML, rather you create widgets programatically. Why not put in a constructor that accepts a view factory rather than a resource id? (Note that it is perfectly possible to create a DSL for defining user interfaces in a declarative way in JavaScript, to replace XML definitions. By the way, anyone knows if there is a way to dynamically manipulate and update XML definitions on the device?). &lt;br /&gt;&lt;br /&gt;Now, while experimenting with creating a custom ListAdapter in JavaScript, I discovered that there are predefined resources that can be used to specify the type of list view item. Very handy! (Still miss a constructor that accepts a view factory!)&lt;br /&gt;&lt;br /&gt;Here is an example of how to create a sample application that displays a simple list view. Start the server in the DroidScript app, go to http://droidscript.se and enter the ip-address of the device, then paste the function below into the editor, select it, and click "Run as Activity", which will run the selected code as a new activity.&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;function onCreate(bundle)&lt;br /&gt;{&lt;br /&gt;    var lang = Packages.java.lang;&lt;br /&gt;    var android = Packages.android;&lt;br /&gt;    var widget = Packages.android.widget;&lt;br /&gt;&lt;br /&gt;    var listView = new widget.ListView(Activity);&lt;br /&gt;&lt;br /&gt;    var fruits = lang.reflect.Array.newInstance(lang.String, 3);&lt;br /&gt;    fruits[0] = &amp;quot;Lemon&amp;quot;;&lt;br /&gt;    fruits[1] = &amp;quot;Peach&amp;quot;;&lt;br /&gt;    fruits[2] = &amp;quot;Plum&amp;quot;;&lt;br /&gt;&lt;br /&gt;    var arrayAdapter =&lt;br /&gt;        new widget.ArrayAdapter(Activity,&lt;br /&gt;           android.R.layout.simple_list_item_1,&lt;br /&gt;           fruits);&lt;br /&gt;&lt;br /&gt;    listView.setAdapter(arrayAdapter);&lt;br /&gt;&lt;br /&gt;    Activity.setContentView(listView);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-2522063416792924128?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/2522063416792924128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/03/how-to-make-simple-listview.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/2522063416792924128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/2522063416792924128'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/03/how-to-make-simple-listview.html' title='How to make a simple ListView'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-7596774007858618843</id><published>2010-03-14T13:59:00.000-07:00</published><updated>2010-03-14T13:59:41.874-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DroidScript'/><title type='text'>DroidScript for Android 1.6</title><content type='html'>I have changed the version requirements so that DroidScript now should work with Android 1.6. Get the new version at &lt;a href="http://droidscript.se/"&gt;http://droidscript.se&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Also made some updates of the repository at &lt;a href="http://github.com/divineprog/droidscript"&gt;http://github.com/divineprog/droidscript&lt;/a&gt;, the README-file is now up-to-date.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-7596774007858618843?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/7596774007858618843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/03/droidscript-for-android-16.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/7596774007858618843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/7596774007858618843'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/03/droidscript-for-android-16.html' title='DroidScript for Android 1.6'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-32101498364287970</id><published>2010-02-26T15:00:00.000-08:00</published><updated>2010-02-27T03:10:57.656-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='DroidScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>An example on the use of closures in JavaScript on Android</title><content type='html'>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.&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;function createButton() {&lt;br /&gt;    var n = 1;&lt;br /&gt;    var Graphics = Packages.android.graphics;&lt;br /&gt;    var font = Graphics.Typeface.create(&lt;br /&gt;        Graphics.Typeface.SANS_SERIF,&lt;br /&gt;        Graphics.Typeface.BOLD);&lt;br /&gt;    var button = new Packages.android.widget.Button(Activity);&lt;br /&gt;    button.setTypeface(font);&lt;br /&gt;    button.setTextSize(26);&lt;br /&gt;    button.setBackgroundColor(Graphics.Color.rgb(0, 0, 64));&lt;br /&gt;    button.setTextColor(Graphics.Color.rgb(255, 255, 255));&lt;br /&gt;    button.setText(&amp;quot;How many times can you click me?&amp;quot;);&lt;br /&gt;    button.setOnClickListener(function () {&lt;br /&gt;        button.setText(&amp;quot;You clicked me &amp;quot; + n + &amp;quot; times!&amp;quot;);&lt;br /&gt;        n = n + 1;&lt;br /&gt;    });&lt;br /&gt;    return button;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var layout = new Packages.android.widget.LinearLayout(Activity);&lt;br /&gt;layout.setOrientation(Widget.LinearLayout.VERTICAL);&lt;br /&gt;layout.addView(createButton());&lt;br /&gt;layout.addView(createButton());&lt;br /&gt;layout.addView(createButton());&lt;br /&gt;Activity.setContentView(layout);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-32101498364287970?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/32101498364287970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/02/example-on-use-of-closures-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/32101498364287970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/32101498364287970'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/02/example-on-use-of-closures-in.html' title='An example on the use of closures in JavaScript on Android'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-8239564042447436053</id><published>2010-02-21T13:41:00.000-08:00</published><updated>2010-02-27T03:28:10.303-08:00</updated><title type='text'>More code examples</title><content type='html'>There is a new update of DroidScript available at &lt;a href="http://droidscript.se/"&gt;http://droidscript.se&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I have also included the following code examples in the editor:&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;// Toast example program. Select this code and click Run.&lt;br /&gt;var Toast = Packages.android.widget.Toast;&lt;br /&gt;Toast.makeText(&lt;br /&gt;    Activity,&lt;br /&gt;    &amp;quot;Hello World!&amp;quot;,&lt;br /&gt;    Toast.LENGTH_SHORT).show();&lt;br /&gt;   &lt;br /&gt;// Select this code and click Run. It will create a button in&lt;br /&gt;// the server activity.&lt;br /&gt;var Widget = Packages.android.widget;&lt;br /&gt;var button = new Widget.Button(Activity);&lt;br /&gt;button.setText(&amp;quot;Hello World!&amp;quot;);&lt;br /&gt;button.setOnClickListener(function () {&lt;br /&gt;    button.setText(&amp;quot;You Clicked Me!&amp;quot;); })&lt;br /&gt;Activity.setContentView(button);&lt;br /&gt;&lt;br /&gt;// You can also run code as a new Activity. Select this code&lt;br /&gt;// and click &amp;quot;Run as Activity&amp;quot;. A new DroidScript activity will&lt;br /&gt;// be created, and the onCreate function is called.&lt;br /&gt;function onCreate(icicle)&lt;br /&gt;{&lt;br /&gt;    var Widget = Packages.android.widget;&lt;br /&gt;    var Graphics = Packages.android.graphics;&lt;br /&gt;    var font = Graphics.Typeface.create(&lt;br /&gt;        Graphics.Typeface.SANS_SERIF,&lt;br /&gt;        Graphics.Typeface.BOLD);&lt;br /&gt;    var button = new Widget.Button(Activity);&lt;br /&gt;    button.setText(&amp;quot;Hello World!&amp;quot;);&lt;br /&gt;    button.setTypeface(font);&lt;br /&gt;    button.setTextSize(26);&lt;br /&gt;    button.setBackgroundColor(Graphics.Color.rgb(0, 0, 64));&lt;br /&gt;    button.setTextColor(Graphics.Color.rgb(255, 255, 255));&lt;br /&gt;    button.setOnClickListener(function () {&lt;br /&gt;        button.setText(&amp;quot;You Clicked Me!&amp;quot;); })&lt;br /&gt;    Activity.setContentView(button);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-8239564042447436053?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/8239564042447436053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/02/more-code-examples.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/8239564042447436053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/8239564042447436053'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/02/more-code-examples.html' title='More code examples'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-5261089532553694292</id><published>2010-02-21T12:26:00.000-08:00</published><updated>2010-02-27T03:31:09.599-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DroidScript'/><title type='text'>DroidScript GET requests</title><content type='html'>Besides using the editor at &lt;a href="http://droidscript.se/"&gt;http://droidscript.se&lt;/a&gt; you can also enter urls directly in the brower. There are some encoding issues, but its an entertaining demonstration.&lt;br /&gt;&lt;br /&gt;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):&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;http://192.168.0.100:4042/eval/2*3&lt;br /&gt;http://192.168.0.100:4042/eval/2%2B3&lt;br /&gt;http://192.168.0.100:4042/eval/function twice(n) { return n * 2; }&lt;br /&gt;http://192.168.0.100:4042/eval/twice(33)&lt;br /&gt;http://192.168.0.100:4042/hello&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-5261089532553694292?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/5261089532553694292/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/02/droidscript-get-requests.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/5261089532553694292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/5261089532553694292'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/02/droidscript-get-requests.html' title='DroidScript GET requests'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-3131946472586469007</id><published>2010-02-20T16:59:00.000-08:00</published><updated>2010-02-20T17:03:38.095-08:00</updated><title type='text'>Java proxy classes in JavaScript on Android</title><content type='html'>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!&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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 ;-)&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;span class="js-keyword"&gt;var &lt;/span&gt;&lt;span class="js-variable"&gt;Lang &lt;/span&gt;&lt;span class="js-operator"&gt;= &lt;/span&gt;&lt;span class="js-variable"&gt;Packages&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;java&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;lang&lt;/span&gt;&lt;span class="js-punctuation"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="js-keyword"&gt;var &lt;/span&gt;&lt;span class="js-variable"&gt;proxy &lt;/span&gt;&lt;span class="js-operator"&gt;= &lt;/span&gt;&lt;span class="js-variable"&gt;Lang&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;reflect&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;Proxy&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;getProxyClass&lt;/span&gt;&lt;span class="js-punctuation"&gt;(&lt;/span&gt;&lt;br /&gt;&lt;span class="whitespace"&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class="js-variable"&gt;Lang&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;ClassLoader&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;getSystemClassLoader&lt;/span&gt;&lt;span class="js-punctuation"&gt;(&lt;/span&gt;&lt;span class="js-punctuation"&gt;)&lt;/span&gt;&lt;span class="js-punctuation"&gt;, &lt;/span&gt;&lt;br /&gt;&lt;span class="whitespace"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class="js-variable"&gt;Packages&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;android&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;view&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;View&lt;/span&gt;&lt;span class="js-punctuation"&gt;.&lt;/span&gt;&lt;span class="js-property"&gt;OnClickListener&lt;/span&gt;&lt;span class="js-punctuation"&gt;)&lt;/span&gt;&lt;span class="js-punctuation"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span class="js-punctuation"&gt;And here we have our proxy class! Will continue&lt;/span&gt;&lt;span class="js-punctuation"&gt; to research this&lt;/span&gt;&lt;span class="js-punctuation"&gt; tomorrow and during the week.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="js-punctuation"&gt;Sleep well :-)&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-3131946472586469007?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/3131946472586469007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/02/java-proxy-classes-in-javascript-on.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/3131946472586469007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/3131946472586469007'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/02/java-proxy-classes-in-javascript-on.html' title='Java proxy classes in JavaScript on Android'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-959044172265103131</id><published>2010-02-20T14:40:00.000-08:00</published><updated>2010-02-20T14:40:47.205-08:00</updated><title type='text'>DroidScript - Live JavaScript on Android</title><content type='html'>I have spent the day with getting the DroidScript web based editor up and running. It is available here: &lt;a href="http://droidscript.se/"&gt;http://droidscript.se&lt;/a&gt; (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.&lt;br /&gt;&lt;br /&gt;The source code is on GitHub at &lt;a href="http://github.com/divineprog/droidscript"&gt;http://github.com/divineprog/droidscript&lt;/a&gt;. 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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 &lt;a href="http://www.mozilla.org/rhino/"&gt;Mozilla Rhino JavaScript engine&lt;/a&gt;, 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!)&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-959044172265103131?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/959044172265103131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/02/droidscript-live-javascript-on-android.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/959044172265103131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/959044172265103131'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/02/droidscript-live-javascript-on-android.html' title='DroidScript - Live JavaScript on Android'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-7374262764005029781</id><published>2010-02-14T23:06:00.000-08:00</published><updated>2010-02-14T23:07:01.646-08:00</updated><title type='text'>First version of DroidScript - JavaScript for Android</title><content type='html'>The first version of DroidScript is now on GitHub: &lt;a href="http://github.com/divineprog/droidscript" target="_blank"&gt;http://github.com/divineprog/droidscript&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-7374262764005029781?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/7374262764005029781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/02/first-version-of-droidscript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/7374262764005029781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/7374262764005029781'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/02/first-version-of-droidscript.html' title='First version of DroidScript - JavaScript for Android'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771301318819126292.post-9132055476280922710</id><published>2010-02-06T06:59:00.000-08:00</published><updated>2010-02-06T06:59:29.661-08:00</updated><title type='text'>DroidScript - new name for RhinoDroid</title><content type='html'>I have decided to use the name DroidScript for the JavaScript Android tool I am developing. For now, I am blogging at &lt;a href="http://divineprogrammer.blogspot.com/"&gt;divineprogrammer.blogspot.com&lt;/a&gt;, and twitter at @divineprog&lt;br /&gt;&lt;br /&gt;I will use this blog to publish DroidScript documentation, code examples, and other related stuff.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;div activeid="-1" expanded="0" id="divCleekiAttrib" menubottom="0" menuleft="0" menuright="0" menutop="0" style="display: none;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771301318819126292-9132055476280922710?l=droidscript.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://droidscript.blogspot.com/feeds/9132055476280922710/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://droidscript.blogspot.com/2010/02/droidscript-new-name-for-rhinodroid.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/9132055476280922710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771301318819126292/posts/default/9132055476280922710'/><link rel='alternate' type='text/html' href='http://droidscript.blogspot.com/2010/02/droidscript-new-name-for-rhinodroid.html' title='DroidScript - new name for RhinoDroid'/><author><name>Mikael Kindborg</name><uri>http://www.blogger.com/profile/02029733364118645140</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_gK2d-jVFRG4/SxRDqFppGOI/AAAAAAAAAAM/hEp92ddd3hk/S220/sommaren+2009+222.JPG'/></author><thr:total>0</thr:total></entry></feed>
