Media_httpdistillerys_xgees

Taken at 高鐵星巴克 Starbucks

上次做的僅止於setText這個簡單的動作, 那像是處理click這類的怎做?

先拿click來做範例, 在Android中, 如果要替一個view加上處理click動作要利用到View.setOnClickListener, 但setOnClickListener的參數是onClickListener, 這是一個java interface, 在Rhino中如何實作一個Java interface?

首先, 不要被Rhino的文件給騙了, 那有問題(還花了我一個晚上看 :( ), Rhino的source codes裡有個example目錄, 裡面有隻SwingApplication.js, 答案就在這邊

因此, onClick就會像是這樣:

var button1 = findview(R.id(‘button1’));

button1.setOnClickListener(function(view, methodName)
{
     if (methodName == “onClick”) {
         log(“MyScript”, “clicked”);
} });

在這function內, 必須要自己判斷methodName來知道是哪個method被呼叫到, 應該是所有的java interface都可以用這樣去實作

OK, 這樣…很醜…繼續改進

More about 公開

這本書前陣子已經熬夜看完了, 想寫這篇一直沒寫, 最早剛出中文版時本來就想看了, 但被厚厚的一本嚇到, 但真的看的時候, 外表只是嚇人的, 整本內容雖多, 但看完還是大呼不不過癮呀!

雖然我網球看的不多, 不過正好他的時代, 我也多多少少有看了一些, 以前就有點蠻喜歡他的特立獨行(我自己也有點特立獨行吧, 總喜歡這類的人), 雖然對上Sampras他總是佔下風, 但他的職業生涯可是比Sampras更長, 成就也不低呀

本想說一個網球選手自己寫的自傳有可能會很沈悶, 但阿格西這本讀來完全不會枯燥, 完全看的出他直率坦蕩的個性, 每字每句毫不修飾, 好像想到啥就講啥, 愛恨分明, 喜歡誰不喜歡誰都明講, 毫不掩飾, 但整本讀起來就是很流暢, 實在看不出他接受的教育並不多

他就像是大多數的天才一樣, 自負, 自信高, 也因為本身的才能跟盛名差點招致毀滅, 但他不會完全倚靠他的天份, 而是想辦法打倒再站起來, 不斷的突破, 直到不能動為止, 雖然, 看得出來, 他真的很不喜歡網球, 其實根本就已經無關喜不喜歡了, 網球已經是他的一部分了

看完這本自傳後, 我只有一個感覺…我真喜歡這傢伙…還真想擁有他那一點點的狂妄呀~~~

More about 時間軸

剛剛把時間軸也給K完了

這本時間迴旋的續作, 讓我有點失望, 比起時間迴旋來說差了不少, 整個故事主軸圍繞著追尋, 追尋失蹤的父親, 追尋假想智慧生物, 但最後的結果卻總覺得有點薄弱

但整體構築出來的世界觀不如時間迴旋來得大, 也不如時間迴旋來的有想像空間

如時間迴旋一樣, 除了原本科幻的故事以外, 也同時陪襯了男女主角的愛情故事, 我喜歡在時間迴旋中, 泰勒與黛安若有似無卻又強烈的牽絆, 雖然花費了很長的時間才修成正果, 但實在讓我蠻羨慕的, 而在時間軸中, 麗絲和特克之間, 就有點讓我覺得有點莫名其妙, 也沒啥很強烈的感覺, 最後雖是一個別離的悲劇下場, 但怎樣就沒啥感覺, 不過愛情故事應該不是重點才對.. :P

雖說遜於時間迴旋不少, 但還算是不錯看的一部小說, 只是沒特別的好看而已…

好久沒玩些好玩的了….先來點小菜….(POC = Prove of concept, 只是剛好有些想法, 所以來證明一下可不可行)

基本的想法是想用類似下面的javascript來寫出Android Activity(當然, 要延伸成其他的應該也沒問題)

https://gist.github.com/950551.js?file=gistfile1

這一個script有幾個簡單的組成 : 

  1. getcontentview : 用來指定這個activity所要用的main layout ID
  2. oncreate : 在Activity oncreate時被呼叫
  3. onresume : 在Activity onresume時被呼叫
  4. onpause : 在Activity onpause時被呼叫
  5. 基本延伸函數 : 
    • log: 等同於Log.d
    • findview: 等同於findViewById
    • R.layout(“layoutname”): 等同於R.layout.layoutname (同樣的R.id(“”)也是…)

因為要在原本Android Java的平台上跑Javascript, 所以需要一個Javascript engine做為一個平台, 這邊選用的是Mozilla Rhino

Rhino可以幾乎無痛的在Android上使用, 當然SL4A有更多的script engine的選擇, 但SL4A的方向不同, 我是想弄一個也可以寫一般的Android program的script

初始化Javascript engine

第一個版本, 只是拿來實驗的, 所以script先放在asset裡面, 這一段會初始化基本的script engine, 然後從asset目錄裡面載入"init.js"

首先要先初始化一個Context instance, 所有的script執行都是要透過這個Context的, 不用後可以透過.exit()來釋放資源

jsContext.setOptimizationLevel(-1);

setOptimizationLevel(-1)這段很重要, 沒設成-1的話是無法在Android上跑的, 原因是Rhino會把javascript編譯成java bytecode以增加執行效率, 但這bytecode是標準的java bytecode而非Android dalvik的bytecode, 設成-1的話, Rhino會改用Intepreter來跑, 而非先compile

Host objects 和 Host functions

ScriptableObject.putProperty(jsScope, “R”, RObj);

ScriptableObject.putProperty(jsScope, “log”, new Log());

ScriptableObject.putProperty(jsScope, “findview”, new FindViewById(this));

這一段包裝了一個host object和兩個host functions讓script使用(亦即是前述的5)

我把R包裝成另一個Object供javascript使用(因為我還沒找到如何讓Rhino使用static fields), 這包裝叫Rwrapper.java:

只是把R用reflection包裝一下而已

至於javascript function的部份, 其實也不難, 只要implement Function.call就可以了, 這邊實作了兩個(繼承自BaseFunction), Log.java和FindViewById.java

Log.java:

FindViewById.java:

不管是Object或是Function, 其實都是被當做objects來看待, 所以只要利用ScriptableObject.putProperty放到目前的scope去就可以給script取用了

目前看來, 這想法可行, 而且還蠻容易的, 缺乏的只是一些包裝而已, 甚至直接對view做操作也是可行的, 有空(會有空嗎?) 再來玩深入點.. :P