2011年4月27日 星期三

git 學習(一) 和 CVS 和 Subversion 的差異

從上個星期開始看 git 的文件,斷斷續續到今天才慢慢有一些心得,在這裡記錄一下。先推薦http://progit.chunzi.me/zh 這個網站,不得不說,人多的地方有空翻譯的人也多一些。雖然有些翻得奇怪的地方,不過不影響對 git 的了解。

作為一個版本管理系統, git 和一脈相承的 CVS 和 Subversion 不同,可能和時空背景不同有關係,硬碟空間的價錢變便宜。CVS 和 Subversion 使用的是節省空間的「記錄改變」,因而適合對可以比較的純文字,對於二進位的資料(如:圖檔)就無法處理。雖然省了硬碟空間,但是一旦版本多起來,計算最新版本所需要的時間也越長。因此  git 的出現,其中一個原因就是要解決這個問題。

2011年4月20日 星期三

學習的歷程

最近公司內引入 MVC 的開發方式,由於我有其它工作要進行,所以就把這個平常我處理的工作交給另一個同事。以往而言,都是先由一個人負責了解技術,再教給其它人,讓總共花費的時間的變得少一些。

在後來幾次討論中,讓我覺得意外的是,由同事口中的 MVC 架構和具有類似想法的物件導向設計模式(實際上一些角度來看,MVC 就是設計模式的一種實現),居然有不小的差異,聽到「物件導向」和 MVC 架構是相互衝突的結論,一時之間不知道應該如何回應,就順其發展吧!

2011年4月19日 星期二

phpcassa 初探

使用 NoSQL 的主要目的在於大量存取資料和負截平衡,查了 SimpleCassie 的官方網站,發現連線到 Cassandra 叢集的功能,還在待處理的列表之中。所以只好回頭去找一開始嘗試 Cassandra 時,看到的第一個 PHP 模組 phpcassa。

可能是 Cassandra 0.7.3 有 bug 或是其它的原因,總之第一次嘗試 phpcassa 的經驗是很讓人挫折的,這次不同的是,最基本我能夠肯定 Cassandra 和 phpcassa 也會用到的 Thrift 模組都是可運作的。這樣我就可以把重點放在 phpcassa 本身的語法或設定上。

2011年4月15日 星期五

初探 Cassandra

手邊工作告一段落,又回過頭來學習 Cassandra。

研究的主題是用來作為 Client 的 PHP 服務,一開始使用一個叫作「phpcassa」的東東,但是怎麼就是無法使用。後來發覺似乎是 Cassandra 服務本身有問題,所以只好暫時作罷。這次則是用官網最近才列出來另一個叫「SimpleCassie」的東東。

同事已經幫我把 Cassandra 服務架好,也編譯完 PHP 和 Cassandra 溝通所使用的「Thrift」模組。Thrift 是一個同樣由 Apache 協會提供,作為服務之間溝通的模式。Cassandra 提供設定讓人修改成 PHP 或是其它語言的版本。而無論是 phpcassa 和 SimpleCassie 都是建置在 Thrift 之上,兩者在程式層級上只是函數庫而已。

一開始把範例貼到測試站後,卻怎麼都不能執行,還出現服務版本過舊的問題。猜想可能是範例程式碼中用的 keyspace, column family 是不存在,導致出現其它錯誤,產生不相干的錯誤訊息。因此就把程式碼刪掉,一行一行加回去。這才確定我的猜想可能是正確。

SimpleCassie 並沒有提供什麼完善的說明文件,只有一個告訴人如何存取資料程式碼範例,看遍 100 多行的程式,就是沒有找到 keyspace 或是 column family 列表相關函數,這總不能叫我自己去猜一個剛架好的 Cassandra 由面有些什麼東西吧!

只好回頭去查 Cassandra 的管方文件,利用 Cassandra 套件所提供的工具 cassandra-cli ,連到同一台主機的 Cassandra 服務,照著 help 的說明,再參考官方文件對於資料結構的說明,倒是成功的作出一個 keyspace 和 column family 。

回到  PHP 之後就順利許多,加入、修改,以及讀出資料的功能都一一被試出來。和資料庫不同的是,讀出來的資料是一個 Object 而不是如關連資料庫直接取得裡面值,看來需要一些時間習慣。

測試中發現一個滿奇怪的現象,在命令列使用 cassandra-cli 所編輯過的資料,以 PHP 的 SimpleCassie 是無法修改、刪除,而被 cassandra-cli 刪除的資料,也無法由 SimpleCassie 使用同一個 key 值新增回來。但是兩者在現階段都沒有使用帳號登入,表示權限理論上應該一樣才是。這點就變成權限問題,有待之後把帳號、權限建立起來後才研究的部分。

2011年4月7日 星期四

Android 的程式基礎(四) - Manifest File

感覺上,Manifest 檔案有點像是 Java Servlet 的設定檔案,都是用來告訴系統自己的存在以及有哪些功能,應該被如何呼叫、啟動裡面的函數。

在 Android 的四種元素中,Activity、Service、Content Provider都是需要被定義在這個用 XML 格式寫成的設定檔中,否則系統是不承認的,結果就是無法被呼叫、執行。唯一的例外是 Broadcast receiver,它可以在程式執行途中被建立、註冊到系統上,使用一個叫作 registerReceiver() 的方法。

也就是說,必須在 Manifest 定義,否則無法使用 Intent 啟動 Activity 和 Service。

除了定義 Activity 之外,Manifest 也定義這個應用程式需要的系統的配置,像是程式需要有相機鏡頭或是藍牙連線功能,或是最低的 API Level 也就是這個程式最低需要的 Android 第幾版,如︰2.2 版之後機器。每一個釋出的版本,都有對應的一個 API Level 編號,像是 2.2 對應到 API Level 8。

由此看得出, Android 是設計向下相容的。不過支援度如何,就有待之後的驗證了。像是最新蜂巢3.x 能不能完整支援  2.x 版的程式,個人抱著懷疑的態度。

Manifest所定義的資料, Android 系統只把它作為一個「額外的資訊」,只有 Market 才會讀取它,讓搜尋的過程中不會出現不符使用者裝置的應用軟體被裝入。所以,如果直接拿 apk 安裝的話,應該就不會作阻擋的動作。

Manifest 的另一個功能,則是定義 Intent filter(意圖過濾?),也就是之前文章中提到的問題。藉由定義的字串(如︰send 表示發出郵件)表示功能需求,讓自己的應用程式也可以去「處理」這件事情。當 Android 發現有兩個以上程式可以處理,就會出現選單讓使用者進行選擇。一個常見的例子為︰當使用者安裝其它瀏覽器後,當使用者發出「瀏覽網頁」的意圖(Intent)時,系統就會列出既有的和新裝入的瀏覽器讓使用者選擇。

2011年4月6日 星期三

Android 的程式基礎(三)-Intent

在中文裡被翻譯成「意圖」,雖然覺得很彆扭,但是也想不到什麼更好的詞。

Android 程式組成四種元素(Activity、Service、Content Provider、Broadcast receiver)中,除了Content Provider 之外,其它三種都是經由 Intent 所啟動的。以這個規則來猜測,應用程式選單也是一個 Android 程式,列出大部分(不敢說是全部)可以被 Intent 啟動的程式,再代替使用者建立並發出 Intent。

因為不同的元素是繼承於各自的基底類別,所以啟動的方式也不一樣。像是 Activity 使用 Intent.startActivity() 啟動其它程式,或者呼叫 Intent.startActivityForResult() 啟動並等待被啟動的程式回傳訊息(例︰要求相機程式拍完相片,把相片資訊傳回來)。而 Service 除了可以經有 Intent 啟動(startService) 也可以和運作中的 Service 連結(bindService)。

至於 Broadcast receiver 到目前為止還沒能搞清楚它的運作方式,等到基礎文件看完後再去研究好了。

Intent 可以視為一種「要求訊息」,除了用來告訴 Android 系統啟動某程式/服務外,也可以帶有訊息,利用 URI 的方式,像是呼叫手機的播號程式會帶有要播打的號碼,發信程式會帶有目標 Email Address。除了這類訊息之外,在其它書上的例子中還看到可以把要傳遞的資料「打包」一併傳過去,這樣才能傳遞多個或是非文字(二進位)的資料。打包也是等到之後研究到再作筆記。

另外還不了解的,則是 Intent 要如何去綁定,最基本以套件加類別名稱的作法在其它書本上已經看到過。不過怎麼作出像「開啟瀏覽器」這樣可以讓系統彈出選單,詢問要使用哪一種瀏覽器的結果。就不知道了,只能猜出應該是同一個 Intent 訊息中,綁上二個以上的程式,系統無法決定要啟動哪一個的時候就跳出視窗詢問。

不知道像是瀏覽器這類的 Intent 訊息是系統已經定義好的那幾種,還是可以自訂新的種類。等到深入研究的時候應該就會知道了吧!

2011年4月1日 星期五

Android 的程式基礎(二) - 基本元件

和 Java 的 servlet 想法類似,程式不具有 main() 函數作為入口,而是繼承特有的類別,利用物件導向的多型原則,由另外的啟動器來把程式執行起來。HttpServlet 就是 Java Servlet 所可以繼承的其中一個類別,繼承這個類別的,都可以視為一個 servlet 程式。

同樣的,繼承 Android 所認可的類別,就可以被 Android 視為合格的程式,並在特定的時間被呼叫、啟動。而 Android 所認可的類別有 4 種︰
1. Activities︰在中文被翻成很奇怪的「機動程式」,主要用在於一般提供使用者操作介面的程式,繼承 Activity 類別

2. Services︰能在背景執行的程式,不受程式切換而停止。像是音樂播放功能需要放在 Services 類型的程式,這樣才能一面作其它事情,一面聽音樂。繼承 Service 類別

3. Content providers︰提供內容,在物件導向裡,會把資料存取的功能,獨立型成一組類別,讓其它程式只需要知道向它要求或是存入資料,不需要理會背後的實作方式。Content provider 可以和許多不同的媒體溝通,像是 SQLite,網路甚至是其它提供存取權限的程式。繼承 ContentProvider 類別

4. Broadcast receivers︰用來接受事件的類別,例如想要寫一個整理簡訊的應用程式,而捕捉收到簡訊事件就需要靠這種類別。可能和的 Service 合用,讓接受事件的行為在背景運作。繼承 BroadcastReceiver 類別

延續上一篇的內容,由於每一支 Android 程式都是在一個執行緒中(也許應該叫線程 process),所以不單單是沒有 main() 函數,程式之間也不能進行直接呼叫,也因此 Android 提供一個叫作「Intent(意圖)」這個我同樣覺得翻得滿怪的東西,利用告訴系統「想要開某某程式的『想法』」,系統確認有權限後就會代為處理開啟。

就其它書上的說法,意圖不單單只有開啟程式的作用而已,還包含其它的功能。不過目前功能還不到,就留到之後的文章描述吧!