星期二, 2月 26, 2013

jruby中java的implements interface



好久沒有更新了,這次遇到的問題是ruby。
因為這邊沒有markdown,就直接放gist連結。
效果有點不好,所以就直接貼這邊,也可以參考放在gist的說明
有任何更動就只會在gist上更動囉。



jruby中java的implements interface

on jruby-1.6.8


implement interface的作法

如果在jruby想操作java的interface,如Runnable
直接include但不override需要的method,在還沒有執行前都是不會出現錯誤的
jruby-1.6.8 :075 > class MyRunnable
jruby-1.6.8 :076?>   include java.lang.Runnable
jruby-1.6.8 :077?> end
 => MyRunnable 
jruby-1.6.8 :078 > t = java.lang.Thread.new MyRunnable.new
 => #<Java::JavaLang::Thread:0x7a0aae8a> 
但是到執行的時候,因為沒有override method,就會出現沒有method的錯誤
jruby-1.6.8 :079 > t.start
Exception in thread "Thread-9"  => nil 
org.jruby.exceptions.RaiseException: (NoMethodError) undefined method `run' for #<MyRunnable:0x470794d4>
只要加入必要的method就好
jruby-1.6.8 :087 > class MyRunnable
jruby-1.6.8 :088?>   include java.lang.Runnable
jruby-1.6.8 :089?>   
jruby-1.6.8 :090 >     def run
jruby-1.6.8 :091?>        puts 'on run'
jruby-1.6.8 :092?>     end
jruby-1.6.8 :093?>   end
 => nil 
jruby-1.6.8 :094 > t = java.lang.Thread.new MyRunnable.new
 => #<Java::JavaLang::Thread:0x461d318f> 
jruby-1.6.8 :095 > t.start
on run
 => nil 

另外也有類似java裡anonymous inner class的用法。

在所有java的interface,都有impl這個method,且只有interface有,class沒有。
在interface沒有找到必要的method時,就會呼叫impl,有點像是missing_method。
jruby-1.6.8 :096 > r = java.lang.Runnable.impl do |method, evt|
jruby-1.6.8 :097 >     puts 'method: '+method.to_s
jruby-1.6.8 :098?>     puts 'evt: '+evt.to_s
jruby-1.6.8 :099?>   end
 => #<#<Class:0x5ad3c69c>:0x519549e> 
jruby-1.6.8 :100 > t = java.lang.Thread.new r
 => #<Java::JavaLang::Thread:0x35a271f5> 
jruby-1.6.8 :101 > t.start
 => nil 
method: run
evt: 


該怎麼用就見仁見智了
如有理解有誤的地方請務必聯絡我,一起學習!

星期一, 3月 12, 2012

[Android] AsyncTask、HandlerThread原理分析


寫Android時難免會遇到UI要回應使用者的動作,同時還要執行一些計算
通常的解決辦法是使用HandlerThread和AsyncTask

AsyncTaskHandlerThread當官見自就可以google出很多使用方法
不過最近看到比較特別的是這篇: Android應用程序線程消息循環模型分析
比較深入的介紹這些事件驅動的原理

雖然HandlerThread和AsyncTask看網路上的一些例子就會用了
但有機會我想還是多了解一點比較好吧

[紀錄] Android Out Of Memory


詳細請見: [Android]Android Out Of Memory(OOM) 的詳細研究

這篇主要是講大量的圖片檔案轉換成Bitmap物件時,出現Out Of Memory Exception的問題
不過其實也可以延伸思考「Android的記憶體分配」

以下節錄一小段:
通過一些瞭解,得知如下:
優化Dalvik虛擬機的堆記憶體分配

對於Android平臺來說,其託管層使用的Dalvik Java VM從目前的表現來看還有很多地方可以優化處理,比如我們在開發一些大型遊戲或耗資源的應用中可能考慮手動干涉GC處理,使用 dalvik.system.VMRuntime類提供的setTargetHeapUtilization方法可以增強程式堆記憶體的處理效率。當然具體原理我們可以參考開源工程,這裡我們僅說下使用方法: private final static float TARGET_HEAP_UTILIZATION = 0.75f; 在程式onCreate時就可以調用 VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 即可。
Android堆記憶體也可自己定義大小

對於一些Android專案,影響性能瓶頸的主要是Android自己記憶體管理機制問題,目前手機廠商對RAM都比較吝嗇,對於軟體的流暢性來說RAM對性能的影響十分敏感,除了 優化Dalvik虛擬機的堆記憶體分配外,我們還可以強制定義自己軟體的對記憶體大小,我們使用Dalvik提供的 dalvik.system.VMRuntime類來設置最小堆記憶體為例:

//設置最小heap記憶體為6MB大小。當然對於記憶體吃緊來說還可以通過手動干涉GC去處理
private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;
VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);

[紀錄] 在Android中使用ormlite


可以參考:
Android中使用ormlite實現持久化--HelloOrmLite
Android中使用Ormlite實現持久化(二)--持久化類的詳細配置

另外補充:
DAO設計模式

星期二, 3月 06, 2012

一個高品質的js統計圖製作: highchartsjs

highcharts js: http://www.highcharts.com/
highchartjs 讓你只要寫一些簡單的javascript,就可以在你的網頁上做出漂亮的圖表
圖表涵蓋了各種常用的類型,如長條圖、圓餅圖等
特別的是它還可以用動畫展示,真的是非常花俏
有興趣的話點網址進去看看就知道多花俏了XD

它的範例及API也很豐富完善,基本需求通常只要改改範例就可以完成
不過要注意的是,若用免費版本,圖表下方會有一個他們的logo
就看介不介意囉


其他的 javascript chart library:
http://wowtree.com/tree.php?aid=864


htaccess使用


很多範例及flag的用法
http://www.cccspace.net/b/htaccess.html

使用實例,可以複製過來直接改
http://www.zzbaike.com/wiki/Htaccess%E4%BD%BF%E7%94%A8%E5%AE%9E%E4%BE%8B#.E7.A6.81.E6.AD.A2.E6.98.BE.E7.A4.BA.E7.9B.AE.E5.BD.95.E5.88.97.E8.A1.A8

星期一, 3月 05, 2012

[javascript] 物件存取特性


一般有在寫javascript的話,都會知道要取一個如下物件
var obj = { a: '123', b: '456' }
的a值,應該要這麼用:
console.log( obj.a );

但是,其實還有另外一個方法,就是使用類似陣列的動態存取
console.log( obj['a'] );
這是一個很方便的特性,假設你要取的物件屬性是不一定的, 我們假設是一個變數。

這時候,如果不知道可以用動態存取方法的話,你就只能這麼寫:
var attr = 'a';
var value = eval('obj.'+attr);
用eval的話,在效能和安全性的考慮上就可能不是這麼的好。

改變一下作法,若是這麼寫:
var attr = 'a';
var value = obj[attr];
這樣不就簡潔又美觀了呢?

在用json的時候,也可以很方便的這麼用
var value = json['key'] || defaultVal;
是不是很棒呢!

星期日, 1月 22, 2012

用python擷取MSN訊息

為了做無線網路的期末專題,寫了個小程式來抓MSN的訊息..
別問我這跟無線網路有什麼關係.. 因為我也不知道

我是使用python+pcap來做,這邊就介紹一下是怎麼做的

測試環境:
Windows 7
Windows Live Message (MSN) version 2009 (Build 14.0.8117.416)

環境要求:
Python 2.6 
Pcap version 1.1 for win32-py2.6
WinPcap 4.1.2
Appserv 2.5.10


其中pcap是Python的WinPcap API,再找要用哪個lib的時候也是考慮了很久
這個lib看起來許久沒更新了,資料也是很久以前的
但這個似乎是最簡便的,資料也比較多,最後在時間壓力下還是用他了


以下是pcac一些參考的資料,不過其實都大同小異
用法並不困難
http://devbbs.doit.com.cn/thread-11317-1-1.html
http://www.iteye.com/topic/372874
http://python.6.n6.nabble.com/CPyUG-85013-pcap-dpkt-python-td2854242.html
http://blog.sina.com.cn/s/blog_4b5039210100gnlu.html


原理
MSN是用1863port,以TCP的方式傳送、接收資料。我們用wireshark找到這點後,用python監聽1863port,並用regex濾出我們想要的訊息(登入訊息及談話內容)。最後存入遠端網頁(測試時是本機),模擬MSN被惡意軟體監聽的情況。

程式碼

星期日, 1月 15, 2012

A star algorithm

A*常用在找「地圖路線」或是「電玩內的NPC移動路徑
原因是因為,跟許多演算法比起來,A*會從現有找到的路挑最好的出來(Best-First),並且猜測接下來最好的路是哪一條(Greedy)

也就是說,A*是一種結合Best-First和Greedy的聰明演算法

評估方法如下: (節錄自: http://blog.minstrel.idv.tw/2004/12/star-algorithm.html)
f(n) = g(n) + h(n)

g(n): 從啟始點到目前節點的距離
h(n): 預測目前節點到結束點的距離(此為 A* 演算法的主要評價公式)
f(n): 目前結點的評價分數

其中, h(n) 主導著A* 演算法的表現方式. 有以下幾種情形:
1. h(n)=0: A* 演算法這時等同 Dijkstra演算法, 並且保證能找到最短路徑
2. h(n)<目前節點到結束點的距離: A* 演算法保證找到最短路徑, h(n)越小, 搜尋深度越深
3. h(n)=目前節點到結束點的距離: A* 演算法僅會尋找最佳路徑, 並且能快速找到結果
4. h(n)>目前節點到結束點的距離: 不保證能找到最短路徑, 但計算比較快
5. h(n)與g(n)高度相關: A* 演算法此時成為 BFS (Best-First Search)


A*的優點從以下圖可明顯看出 :



A*的搜尋範圍明顯的比Dijkstra小


但是也有一點缺點:


A*有可能沒辦法找到最好的路徑

星期日, 12月 25, 2011

Windows Desktop Gadget 開發


因為某些原因,最近學了一點Windows Desktop Gadget開發
* Windows Desktop Gadget也就是俗稱的桌面小工具


開發途中發現國內的資料似乎不太多,我想應該是不太熱門吧
在還沒開始玩前,其實我的桌面也不會擺小工具 
後來發現還蠻多人有再用小工具的.. 我見識太淺薄了XD



首先

對Gadget完全沒概念的話,可以看看這邊
裡面有關於小工具的整體架構說明及背景知識


接下來
有點背景知識之後,可以看一點Gadget API

Gadgets for Windows Sidebar - Gadget Object Reference
Gadgets for Windows Sidebar - System Object Reference

因為Gadget基本上是用html/js/css撰寫,只是多了一點可以用的api
到這邊,你可以試著組組看你想要的東西

當然,你可以用你熟悉的jquery或是其他javascript library

不過要注意一點:
這邊有個小問題 (應該是bug)不支援直接套用click事件
正確一點的說法是,如果這個dom element原本沒有onclick事件的話,是不能直接加入的

舉例來說:


$('#myDiv').click(function(){  doSomething(); });
只寫這樣是不行的,點下去仍然不會觸發doSomething
必須在#myDiv上加入onclick這個attr才可以

<div id="myDiv" onclick="" ></div>
onclick是空的也沒關係,總之要有就對了

但是mouseover, mouseout等就沒這個問題,我也不知道為什麼
或許真的是bug XD

為你的小工具加上背景
要做出美觀的小工具,一個漂亮的背景是不可少的 雖然我偷懶沒用

這篇文章是中文文章,講的是加入背景的方法,還蠻詳細的
當然不可少的是Gadget API: Background Object

這邊先提一個常遇到的問題:
兩個透明圖疊在一起的時候,會出現紫色的破圖 (Pink Problem)
這個問題就我查到的資料看來,應該沒有比較好的解法
算是一個bug,要不就是用美工避開,或是可用 gbackground元素的addImageObject加入圖片
這樣就不會有這個問題
詳細的說明可以看:Gadget開發實戰總結 2 (I See Pink Problem)


或許有人會想用css3pie或IE的Filter..等方法
做出CSS3的box-shadow(陰影)、border-radius(圓角)這些效果
這些的確是做得出來
但是一樣要注意透明的部分(陰影、圓角處),也會出現紫色破圖的問題


在小工具內使用AJAX
這邊大概是我弄最久的地方,雖然最後還是失敗了
直說的話,就是基本上還是沒辦法cross domain的,除非有要的服務提供Rest based API (參考)


我甚至還自己用ActiveX寫了Ajax來測試,確定是不行的 (如果有人試成功的話麻煩跟我說)
不過後來發現用jQuery.ajax其實功能是一樣的,不過要設定強制跨域


為此我還去找了Ajax的readyState狀態碼含意HTTP的連接狀態碼含意
不然說實在的,只用library都不知道底層做了什麼XD

以下這兩個網址是用另一個方法取網路上的資料,也可以看看
Gadget開發實戰總結 1 (Gadget調用WebService)


英文:
介紹及資源:http://christ-offer.blogspot.com/2011/02/windows-7-gadget-development.html
範例:http://www.codeproject.com/KB/gadgets/DailyDilbert.aspx
很不錯的書,可以用Ctrl+F找關鍵字:http://www.innovatewithgadgets.com/



星期六, 12月 24, 2011

[Windows Gadget] Now.in Player / Now.in 桌面播放器


Now.in是個很不錯的電台網站,提供很多不同種類的電台供大家收聽
平常我都會把網址餵給撥放器播,最近這兩天就思考到一個問題

我要怎麼知道現在正在播放的歌名呢?

我就想著,不然就來寫個小程式吧!
google了一下,發現windows gadget好像非常適合拿來做這種工作
放在桌面上小小的,很適合當播放器

於是就生出了這個東西。

雖然最後還是沒達成本來的目的啦.. 
一開始以為windows gadget可以cross domain取資料的
後來發現還是要用rest based api(jsonp)才可以,不過Now.in當然是沒提供這種服務XD

真要的話就得自己架server來parse了
而且最近也沒時間,就先把這個未完成品放著,晚點再說囉
還有期末考阿..QQ 莫名其妙就花了兩天在玩這個 


暫時的未完成品是長這樣:



雖然看起來是簡單的小程式
但是不太熟一邊google的情況下,也花了一點時間
不過也算是學到另一種好玩的東西啦!
寫起來跟寫網頁感覺差不多,都是用html/js/css,只是有些特別的語法和怪問題晚點再說
這也表示可以用jquery  ..!



下一篇是開發Gadget的心得,敬請期待!


使用object embed插入音樂 - 參數設定及js控制方法


雖然很不幸的,這是IE only的東西
但是有時候也不得不用阿..

這邊有很詳細的object參數,javascript的用法則在這邊


參數:
簡單列幾個重要的:
<object id="player" codebase="http://www.apple.com/qtactivex/qtplugin.cab"  classid="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6"  type="application/x-oleobject" width="1" height="1">
        <param name="SRC" value="b.rm"><!--文件路徑,根據需要調整-->
        <param name="AUTOSTART" value="1"> <!--自動播放-->
        <param name="LOOP" value="1"><!--循環播放-->
        <param name="volume" value="50"><!--默認聲音大小0%-100%,50則為50%-->
</object> 


javascript:
以下的player表示object的DOM Element

player.controls.play();     /*   開始撥放   */
player.controls.pause();  /*   暫停撥放   */
player.controls.stop();    /*   停止撥放   */
player.controls.next();    /*   下一首音樂   */

player.URL = url;   /* 將音樂的來源設為url,這個動作會馬上執行,不需要先stop在play */


  *注意:此方法只適用於IE

超酷的CSS3 Animate及Shadow


超酷的CSS3 Animate:
demo: http://daneden.me/animate/#cta 
github: https://github.com/daneden/animate.css

順便也介紹一下一個用CSS3+jquery做出的陰影plugin
demo: http://syddev.com/jquery.shadow/
github: https://github.com/sydlawrence/jQuery-Shadow




[jquery] 強制使用跨域(cross domain) Ajax


很簡單,就只有一行code

$.support.cors = true;

不過別以為這樣就真的可以無視瀏覽器限制XD
只是當你有特別為cross domain設定時,這個才有用

不然還是會噴錯誤的!

[Android] 使用自訂的SQLite出現錯誤


Android想使用自己放在SDCard的SQLite Database時,有可能會有無法讀取的情況
這時候可以試著檢查一下資料庫內有沒有android_metadata這個資料表

因為若是在程式內開SQLite Database時,android_metadata會自動建立
但是用自己的就有可能沒注意到這個小地方


可以用以下兩個指令建立:
CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'en_US')
INSERT INTO "android_metadata" VALUES (zh_TW')


若是想要將放進SDCard的資料庫移到程式自己的空間的話
可以參考以下連結:  Using your own SQLite database in Android applications

星期日, 12月 11, 2011

DAO vs ORM

看到一篇有趣的文章
比較了 model, orm, dao和active record

個人覺得寫得不錯,將他翻成繁中記錄在此

  --

在做web開發中,經常會碰到這樣幾個概念:

  • Model
  • DAO,data access object,數據訪問對象
  • ORM,object-relational mapping,對象關係映射
  • Active Record

這些概念都是和數據相關的,然而他們之間有怎樣的區別呢?

首先來看Model,模型。模型是MVC中的概念,指的是數據和改變數據的操作(業務邏輯)。模型通常指代現實生活中的某樣實體。以訂單為例,每個訂單都包含許多數據,如客戶、價格、明細等等,這些數據都叫做訂單這個模型的屬性,此外,和訂單相關的一些列操作,比如當購買時,你可能需要先檢查庫存,給與一定的優惠,再更新賬戶餘額和積分等等,這些就叫做業務邏輯,也是模型的一部分,從代碼上來講,是要放在模型中的。

當模型執行完業務邏輯後,我們便要把模型中的數據保存到數據庫中。如果我們直接把和數據庫相關的代碼放在模型裡,會使得以後的維護相當的麻煩。在我之前的一個項目中,我們用戶的增長相當快,導致一台數據庫無法支撐所有的訪問,不得不使用分庫來解決問題。然而前人把SQL語句直接寫在了模型這一層裡,這導致分庫相當的麻煩,我們只能先把這些SQL語句抽出來,才能把分庫進行下去。我們把這些抽出來的SQL代碼放到單獨的一層,這一層便是DAL,Data Access Layer,數據訪問層,它由許多DAO組成,目的便是把和數據庫相關的代碼封裝起來,這樣當我們執行分庫時,便只用調整DAO的代碼了,模型根本不用關心它使用的數據是放在A庫還是B庫。

DAO其實是來源於J2EE的一個設計模式,當初的目的也是使得企業更換數據庫時,不用影響模型層的代碼。

與DAO類似,ORM也是一種封裝數據訪問的概念。然而ORM不像DAO只是一種軟件設計的指導原則,強調的是系統應該層次分明。ORM更像是一種工具,有著成熟的產品,比如JAVA界非常有名的Hibernate,以及很多PHP框架裡自帶的ORM庫。他們的好處在於能將你程序中的數據對象自動地轉化為關係型數據庫中對應的表和列,數據對象間的引用也可以通過這個工具轉化為表之間的join,而Hibernate甚至提供一套他們自己的數據查詢語言HQL來解決複雜的查詢問題。

使用ORM的好處就是使得你的開發幾乎不用接觸到SQL語句。創建一張表,聲明一個對應的類,然後你就只用和這個類的實例進行交互了,至於這個對象裡的數據該怎麼存儲又該怎麼獲取,通通不用關心。

Active Record則是隨著ruby on rails的流行而火起來的一種ORM模式,它是把負責持久化的代碼也集成到數據對象中,即這個數據對象知道怎樣把自己存到數據庫裡。這與以往的ORM有不同,傳統的ORM會把數據對象和負責持久化的代碼分開,數據對象只是一個單純包含數據的結構體,在模型層和ORM層中傳遞。而在Active Record中,模型層集成了ORM的功能,他們既代表實體,包含業務邏輯,又是數據對象,並負責把自己存儲到數據庫中,當然,存儲的這一部分代碼是早已在模型的父類中實現好了的,屬於框架的一部分,模型只需簡單的調用父類的方法來完成持久化而已。


 --


引用這裡的說法:「DAO層是軟件開發演變過程中對於分層概念的產物,目的是更清晰合理的管理軟件開發過程過的代碼和邏輯;而ORM是對數據操作思想的一種改變,不再是面對關係數據庫中的表,而是統一視作對象。」

 --

其他參考:
如何規劃? - DAO模式與ORM概念




星期六, 10月 01, 2011

javascript/jquery剖析網址 - parseUri(parseUrl)

這個parseUri是我修改Steven Levithan而成的

為了看起來整齊點,我將parseUri包在jquery下
不過其實並沒有用到jquery的東西,大家覺得用不順手可以自己改改


javascript中使用print_r

有用過print_r的php開發者都知道他的好用XD
這邊實現了js的print_r : http://phpjs.org/functions/print_r:493

其實這個網站(http://phpjs.org/functions/index)也有很多其他的函式
有興趣可以晃晃!

星期二, 9月 13, 2011

flask初體驗

寫了一個用到flask的小專案
用python寫web果然一樣簡潔,還蠻喜歡的

今天google到的一個小成果是:
http://flask.flyzen.com/   - flask官網的中文翻譯XD (只有Quick Start部分)

英文看不懂可以去翻翻~


另外有一個必須記錄的地方..
url_for裡面的值不是@app.route(OOXX)裡面的OOXX
而是對應的 def XXOO 的XXOO

詳細看這邊:
http://stackoverflow.com/questions/3683108/flask-error-werkzeug-routing-builderror




Compass

用了只能說.. cool!


簡單紀錄一下安裝方法:
首先,先確定你有安裝ruby,有ruby之後開cmd打
get install compass

安裝完成XD


接著看一下參考資料
http://marlonyao.iteye.com/blog/652103
http://miau715.blogspot.com/2011/04/compassapp.html
http://www.i-design.tw/archives/170


compass有蠻多套件可使用的,這邊介紹一下 fancy-buttons
網站上的影片可以知道fancy-buttons可以做到怎麼樣的程度
打一段code就有這麼棒的效果實在很方便呀!

安裝
gem install fancy-buttons

要建立compass專案的方法是
compass create 專案名

加入fancy-buttons的話則要用
compass -f fancy-buttons -r fancy-buttons 專案名

最後,到 ruby資料夾/bin 找compass開啟 (不是compass.bat)
加入
require 'compass-colors' 
require 'fancy-buttons'

因為fancy-button需要compass-colors這個套件
所以記得要先
gem install compass-colors

在寫scss的時候,可在專案目錄下用
compass watch

這樣可在你的scss變動時,自動產生對應的css,非常方便!
( 不過不知道為什麼 compass -w 是沒用的 )