2011年10月21日 星期五

[Android] javascript injection in WebView

上次寫了一篇"startActivityForResult and callback in WebView", 本篇則是上次這篇的延伸應用, 這是有人問我如何inject一整個javascript file到一個web page內(剛剛回顧了一下自己這篇, 發現我把它叫做javascript injection)

其實原理是一樣的, 在載入完原本的web page之後, 一樣透過URL來插入script:

mWebView.loadUrl("javascript:var js = document.createElement('script');js.type = 'text/javascript';js.src = 'http://my_host/1.js';document.getElementsByTagName('head')[0].appendChild(js);");

一樣是透過"javascript:"來inject, 不一樣的只是, 這次我要插入的是一整個js檔, 所以這串javascript的目的就是要建立一個新的script element, 並將它插入head裡, 這樣任務就達成了

但這方法的缺點是, 來源必須是一個url, 也就是要把script file放在server才可以, 如果script是來自應用程式本身, 比如說放在應用程式apk裡面, 或是放在data partition就不行了

在Honeycomb之前的版本, 我還沒想到一個比較好的解法, 但Honeycomb (API level 11, 含11)之後就有一個比較簡單的解法了

作法就是overwrite WebViewClient的shouldInterceptRequest,這似乎就是為了類似的用途而生的呀~~

這邊我將來自於apk asset目錄裡的檔案的url定義成"asset://", 因此, 想當然耳, 要導向的url就是這種, 作法也很簡單, 將asset的input stream包裝成WebResourceResponse就可以了, 這樣只要"js.src="後面的url是"asset://xxx.js", 這js的來源就是apk裡的asset

缺點是, 這方法只適用API level 11之後

延伸應用? 其實應該可以利用這個API做出一個lightweight版本的client side serlvet (這樣叫好像也不是很貼切, 反正就是不需要透過http去存取), 不過因為資訊只有url可以使用, 因此不能implement "POST"...

 

題外話, 這個我是在Ice cream sandwich的emulator上測試的, 不過真的要小抱怨一下, 開個emulator要開很久, 看篇漫畫結束後還沒跑完, 如果叫developer完全用emulator開發, 真的會抓狂吧....這樣開發者的開發意願也會降低吧.... = ="

[Android] If you can't remove it, at least you can still "disable" it

Android 4.0 Ice Cream Sandwich 有一個新功能是, 使用者可以停用(Disable)系統上預載的應用程式, 以往系統預載的應用程式是不能被刪除的, 現在, 新的版本多了一個按鈕讓你可以停用它:

Device-2011-10-22-001443
當你把預載應用程式的icon拖到App Info就可以看到一個Disable的按鈕, 按下去後, 你就不會在程式啟動介面上看到他了

這是中國人所謂的..."眼不見為淨"嗎?

被Disable掉的應用程式基本上並沒被移除, 它還是在你手機裡面, 並不會因此多出一些可使用空間, 只是你看他不爽, 以後就可以不用再看到他了....(呃, 不爽用就不要用不就好了)

這是新功能嗎? 對這介面上來說...這按鈕...是新的

PackageManager裡面有個叫做setApplicationEnabledSetting , 這用途就是用來作這種事的, 所以做這樣一個功能到底多複雜呢?

PackageManager pm = getPackageManager(); pm.setApplicationEnabledSetting("com.geekyouup.paug.awesomepager", PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);

就差不多上面那樣

當然啦, 是沒辦法隨便寫一個軟體去disable人家的應用程式的, 如果可以, 不就天下大亂了, 這API只能用在跟你的應用程式相同的uid的package

不過對於系統應用程式來說, 就沒這限制了吧

至於這API啥時有的?        Since API level "1"

 

Ok, So.....

 

We got a new feature..........

 

2011年10月20日 星期四

[筆記] Tabs on JQuery Mobile and Sencha touch

JQuery mobile跟Sencha touch都是蠻完整的mobile web framework, 兩者各有擅長, 比較起來以開發的角度我比較喜歡JQuery所標榜的"Write less, Do more"的哲學下的架構, 而不喜歡Sencha touch把一堆html寫到code裡面去, 但Sencha touch又有比較好的UI look and feel

以tab panel為例,

Sencha touch:

Photo_11-10-21_1_33_28
jQuery mobile:
Photo_11-10-21_12_25_52

這兩個作法大異其趣 

Sencha 的HTML 內容

裡面除了script以外根本就是空的, UI的創建放在app.js(以這範例而言)裡如下:

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

Tabs的內容在哪? items裡分別就是兩個tab, html直接以字串的形態寫在裡面, 老實說, 我覺得這很醜, 也容易出問題, 如果頁面的內容是相當複雜的, 這樣並不是很好

 

再看看jQuery Mobile的作法:

這份source code有點偷懶, 剪剪貼貼過來的, 不過其實就這麼一個html, 並不需要寫額外的javascript code, 乾淨多了  

如果也可以用類似的寫法寫Sencha touch的UI似乎應該會比較好一點, 像是這樣寫:

做了個實驗, 剛寫下這段code把上面那段轉成跟第一個範例一樣的畫面:

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

看來如果再多層包裝其實也不用醜醜的通通把UI hard code到js codes裡面去