<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
   <title>Jollen&apos;s Blog</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/" />
   <link rel="self" type="application/atom+xml" href="https://www.jollen.org/blog/atom.xml" />
   <id>tag:www.jollen.org,2020:/blog//2</id>
   <updated>2018-04-11T17:59:37Z</updated>
   
   <generator uri="http://www.sixapart.com/movabletype/">Movable Type 3.32</generator>

<entry>
   <title>另一個挖礦時代來臨了？關於 ERC 891 代幣的二件事</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2018/04/erc-891-ico.html" />
   <id>tag:www.jollen.org,2018:/blog//2.876</id>
   
   <published>2018-04-11T12:55:17Z</published>
   <updated>2018-04-11T17:59:37Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 不久前（2018 年 1 月），Ethereum 才剛針對 ERC 20 提出的 ERC 827 擴充標準；近期，ERC-891 代幣標準橫空出世。即使 ERC 891 仍只是一個 EIP（Ethereum Improvement Proposal），但筆者認為這是一個相當值得關注的提案。 ![2018-04-11 6 56 07](https://user-images.githubusercontent.com/1126021/38612682-12376bb4-3dba-11e8-9269-46fda7881303.png) 第一、ERC 891 提案的重心，在於一個稱為 PPoW（Pseudo proof-of-work）的觀念。技術上，ERC 891 與 ERC 827 相同，都是 ERC 20 的延伸（Extension）；但 ERC 891...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2018/04/erc-891-ico.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="https://imgur.com/jCzAKdO.jpg">

不久前（2018 年 1 月），Ethereum 才剛針對 ERC 20 提出的 ERC 827 擴充標準；近期，ERC-891 代幣標準橫空出世。即使 ERC 891 仍只是一個 EIP（Ethereum Improvement Proposal），但筆者認為這是一個相當值得關注的提案。

![2018-04-11 6 56 07](https://user-images.githubusercontent.com/1126021/38612682-12376bb4-3dba-11e8-9269-46fda7881303.png)

第一、ERC 891 提案的重心，在於一個稱為 PPoW（Pseudo proof-of-work）的觀念。技術上，ERC 891 與 ERC 827 相同，都是 ERC 20 的延伸（Extension）；但 ERC 891 的目標，是希望「讓 ERC 20 成為 PoW 挖礦式代幣」。比較有趣的是，PPoW 打算採用異步式挖礦系統（Asynchronous mining system）。也就是說，礦工將能同時挖所有的 PPoW 代幣。

做為一個礦工，或者礦場的場主，更應該支持 ERC 891 的代幣標準。未來如果有 1,000 個 Token 採用 ERC 891 發行，表示一台挖礦機將能同時挖 1,000 種代幣。

第二、ERC 891 為 ERC 20 擴充了 ```function mine() public;``` 與 ```function checkReward() view public returns(uint256);``` 二個方法，原則上，這不影響原有的 ERC 20 智能合約實現。這二個方法充份表現了 ERC 891 的重點：挖礦與獎勵。挖掘 ERC 891 代幣，需要費用（Gas price），因此 ERC 891 希望 ```mine``` 方法是 *predictable*；也就是，礦工可能知道完成一個挖礦週期，需要花費多少 ETH。

## ICO 與 ERC 891

筆者認為，ERC 891 提案若能被廣為採行，將有助於打造更健康的 ICO 生態（ICO 2.0？）：

* 目前 ICO 採用 ERC 20 來發行代幣，代幣的初始供給總額（Total amount），是由智能合約的佈署者（Deployer）持有；採用 ERC 891 後，智能合約佈署者將不持有初始的所有代幣，而是由任何的礦工來 *mining*

![2018-04-11 7 50 11](https://user-images.githubusercontent.com/1126021/38614966-9b57363e-3dc1-11e8-9b16-6ecd75103e61.png)

* Token distribution 由智能銷售合約決定，有些 ICO 投資人認為這有潛在風險；將 token distribution 改採 PoW 的做法，有助於降低「人為掌握」所產生的投資風險

* 現有的 ICO model，其 token allocation 與 transfer 完全「可由人為」控制，但是我們都知道的，人性總是（永遠）無法戰勝誘惑，因此經常（一定）有非法行為產生；而 PoW 的方式來進行 token allocation 與 transfer，或許能部份防止此類的非法行為



</script>]]>
      
   </content>
</entry>
<entry>
   <title>P2P 物聯網論文發表：Advances in IoT Architecture and Systems，多倫多，加拿大 (2017)</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2017/10/devify-aiotas-isca-toronto-canada-june-2017.html" />
   <id>tag:www.jollen.org,2017:/blog//2.875</id>
   
   <published>2017-10-23T05:57:09Z</published>
   <updated>2017-10-23T11:00:05Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 ![2](https://user-images.githubusercontent.com/1126021/31872573-aaf66a08-b782-11e7-8c39-da838ba47d8a.jpg) 這是今年（2017）第二篇有關 Blockchain 的論文。在加拿大多倫多 ISCA 2017 的 Advances in IoT Architecture and Systems (AIoTAS 2017) 研討會上，發表了一篇有關 P2P IoT 的研究文：Devify: Decentralized Internet of Things Software Framework for a Peer-to-Peer and Interoperable IoT Device。這篇論文也會出版在 2018 年的 ACM SIGBED Review...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2017/10/devify-aiotas-isca-toronto-canada-june-2017.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="https://i.imgur.com/9h8vthIh.jpg">

![2](https://user-images.githubusercontent.com/1126021/31872573-aaf66a08-b782-11e7-8c39-da838ba47d8a.jpg)

這是今年（2017）第二篇有關 Blockchain 的論文。在加拿大多倫多 ISCA 2017 的 Advances in IoT Architecture and Systems (AIoTAS 2017) 研討會上，發表了一篇有關 P2P IoT 的研究文：Devify: Decentralized Internet of Things Software Framework for a Peer-to-Peer and Interoperable IoT Device。這篇論文也會出版在 2018 年的 ACM SIGBED Review 上。

![1](https://user-images.githubusercontent.com/1126021/31872572-aac05396-b782-11e7-83e8-352aa160a58e.jpg)

區塊鏈被視為是下一代的信息技術，它與目前的信息技術相較，有一個最大的差異就是去中心化應用（decentralized applications，Dapp）。單純從技術的角度來看，P2P（peer-to-peer）網路是 Dapp 的底層網路拓璞（topology）。

Devify 就是一個 P2P IoT 的軟體框架，它是 [Flowchain](https://flowchain.io) 研究的一個副產出（side project）；從區塊鏈與 Dapp 的角度來看，Devify 其實是最重要的基礎建議。因為沒有了 IoT P2P 軟體框架，IoT Blockchain 是無法實現的。

論文下載點：[https://flowchain.co/publication.html](https://flowchain.co/publication.html)

## Flowchain 計畫

Flowchain 目前處在 Proof-of-Concept 階段，後續計畫包含 TSDB（Time-Series Database）、去中心化的 IoT 通用框架（Decentralized and Generic IoT Programming Framework）以及混合區塊鏈的佈署案例（Hybrid Blockchain）。在商用化部份，目前已經開始搭配 Hyperledger Fabric 來提供一個 Edge Computing 與 IoT Blockchain 的實驗系統。所有的開源項目，以及最新進展，將會在 [https://flowchain.io](https://flowchain.io) 上發佈。

## 多倫多日常

![a](https://user-images.githubusercontent.com/1126021/31872580-b3abe95c-b782-11e7-926c-8963a668be37.jpg)
![b](https://user-images.githubusercontent.com/1126021/31872581-b3e7f050-b782-11e7-81d0-1c53ec0a0d27.jpg)
![c](https://user-images.githubusercontent.com/1126021/31872582-b446c454-b782-11e7-8169-238828ff278b.jpg)
![d](https://user-images.githubusercontent.com/1126021/31872583-b476ccda-b782-11e7-9119-de29b6df85fe.jpg)
![e](https://user-images.githubusercontent.com/1126021/31872584-b4af2e86-b782-11e7-9032-d9d82bc6c897.jpg)
![f](https://user-images.githubusercontent.com/1126021/31872585-b50ca098-b782-11e7-9564-f216317de2cf.jpg)
![g](https://user-images.githubusercontent.com/1126021/31872586-b542975c-b782-11e7-88a3-908d24a6a96b.jpg)
![h](https://user-images.githubusercontent.com/1126021/31872587-b5761a78-b782-11e7-8d0d-ba129e5c1d8f.jpg)
![i](https://user-images.githubusercontent.com/1126021/31872589-b5a4b176-b782-11e7-9047-5b01c89839c5.jpg)
![j](https://user-images.githubusercontent.com/1126021/31872590-b5d9ed5a-b782-11e7-89bf-1ce65a2ca213.jpg)



</script>]]>
      
   </content>
</entry>
<entry>
   <title>IoT Blockchain 論文發表：Linked Data and Distributed Ledgers 國際研討會，皮蘭，斯洛維尼亞 (2017)</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2017/10/flowchain-lddl-eswc-portoroz-slovenia-may-2017.html" />
   <id>tag:www.jollen.org,2017:/blog//2.874</id>
   
   <published>2017-10-23T05:51:37Z</published>
   <updated>2017-10-23T10:55:49Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 ![](http://i.imgur.com/kY9P4vUh.jpg) 關心 Blockchain、更別忘了 Web 3.0。IoT Blockchain 近期在台灣產業界受到不少關注。許多報導與活動，都在討論物聯網區塊鏈的機會與方向；我則是在 ESWC 發表 IoT Blockchain 的具體成果與程式碼。 ESWC (Extended Semantic Web Conference) 是歐洲主要的 Semantic Web 學術會議，今年在 Piran (斯洛維尼亞) 舉辦的 ESWC 2017 已經邁入第 14 屆。這次參加 ESWC 2017 全程 5 天的會議，學習來自各界的研究成果分享，非常有收獲。 ![](http://i.imgur.com/YMtxyXFh.jpg) 在與 ESWC...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2017/10/flowchain-lddl-eswc-portoroz-slovenia-may-2017.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="https://i.imgur.com/9h8vthIh.jpg">

![](http://i.imgur.com/kY9P4vUh.jpg)

關心 Blockchain、更別忘了 Web 3.0。IoT Blockchain 近期在台灣產業界受到不少關注。許多報導與活動，都在討論物聯網區塊鏈的機會與方向；我則是在 ESWC 發表 IoT Blockchain 的具體成果與程式碼。

ESWC (Extended Semantic Web Conference) 是歐洲主要的 Semantic Web 學術會議，今年在 Piran (斯洛維尼亞) 舉辦的 ESWC 2017 已經邁入第 14 屆。這次參加 ESWC 2017 全程 5 天的會議，學習來自各界的研究成果分享，非常有收獲。

![](http://i.imgur.com/YMtxyXFh.jpg)

在與 ESWC 2017 共同舉辦的 International Workshop on 2nd Distributed Ledger and Linked Data (LDDL) 上，我有一篇關於物聯網區塊鏈 (IoT Blockchain) 的論文被 Accept，因此有了 20 分鐘的機會，向大家簡報 Flowchain 計畫的目標。

另人興奮的是，一位來自 Standford 的教授，對於 Flowchain 的想法感到興趣；Chord 不是一個新的 DHT 技術，過去也有許多 Chord 的 fixed 與 extended 研究被提出，但對於利用 Chord 的 Distributed Data Store 這項「天然特性」來實作 Distributed Ledger，Flowchain 很可能是第一個提出這項應用的研究計畫。

![](http://i.imgur.com/8ISFu6dh.jpg)

在經過這段時間的 paper review 與現場討論後，準備開始進行 beta release 的 commits 了。目前 alpha 版本，將保留為 Proof-of-Concept 的版本，目前已經將程式碼發佈在 Github 上：

https://github.com/flowchain/flowchain-ledger

這個版本沒有太多的雕飾與抽像資料結構，所以可以很容易看出 Flowchain 的架構。接下來，在 7 月底前，將進入 beta commits，陸續將 evaluation code 重寫並提交；同時，也會開始進行商業化。

![](http://i.imgur.com/AF6RJJWh.jpg)

Semantic Web 另一個耳熟能詳的名字，叫做 Web 3.0；這次在 ESWC 2017 上，我發現幾個 Web 3.0 的共同研究方向。總結一下 Web 3.0 接下來可能的研究熱點：第一、對於 Data Streams 的支援。第二個多次被出的議題是 Security 與 Privacy；第三則是 Decentralized。

關於 Data Streams 的部份，透過延伸 RDF 以支援 Data Streams，是這次 ESWC 2017 不約而同的一個主題；因為過去大多著重在 Document-Oriented Data 應用，因此 Streaming Data 的研究相對較少。這個主題很明顯，開始受到特別關注了。

![](http://i.imgur.com/a4pnv2Uh.jpg)
![](http://i.imgur.com/QFu5t6Oh.jpg)
圖：會議酒店的海岸

Data Streams 又分為 Time-Series Data (aka Point-based) 與 Interval-based Data 二類；以這次大會選出的 Best Paper 為例，該論文就是針對 Time-Series Data 進行研究，並提出一套方法論 (Ontology)，讓 Web 3.0 能分析即時交通資訊，以提升道路安全。

![](http://i.imgur.com/WWezrNdh.jpg)

Flowchain 也提出一個以 Semantic Web 支援 Time-Series Database (TSDB) 的方法；這部份的程式碼，預計在 Flowchain v2.0 開始發佈。

最後，讓 Web 3.0 支援 Data Streams 很重要嗎？現在的 Machine Learning 已經很擅長分析 big “history” data 了；如果讓 Data 能更好的語意化 (Semantic)，並打造一套好的 “RDF” Streams Store，就可以讓 Machine Learning 能更好地分析即時數據。這也是今年 ESWC 2017 的另一個重點。

## Flowchain 計畫

Flowchain 目前處在 Proof-of-Concept 階段，後續計畫包含 TSDB（Time-Series Database）、去中心化的 IoT 通用框架（Decentralized and Generic IoT Programming Framework）以及混合區塊鏈的佈署案例（Hybrid Blockchain）。在商用化部份，目前已經開始搭配 Hyperledger Fabric 來提供一個 Edge Computing 與 IoT Blockchain 的實驗系統。所有的開源項目，以及最新進展，將會在 [https://flowchain.io](https://flowchain.io) 上發佈。

</script>]]>
      
   </content>
</entry>
<entry>
   <title>P2P IoT software framework paper accepted at AIoTAS 2017 @ISCA&apos;17</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2017/10/p2p-iot-software-framework-paper.html" />
   <id>tag:www.jollen.org,2017:/blog//2.873</id>
   
   <published>2017-10-19T06:03:02Z</published>
   <updated>2017-10-19T11:11:36Z</updated>
   
   <summary>My paper titled “Devify: Decentralized Internet of Things Software Framework for a Peer-to-Peer and Interoperable IoT Device” has been accepted by the Advances in IoT Architecture and Systems (AIoTAS 2017), as co-located at ISCA 2017, taking in place in Toronto,...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[My paper titled “Devify: Decentralized Internet of Things Software Framework for a Peer-to-Peer and Interoperable IoT Device” has been accepted by the <i>Advances in IoT Architecture and Systems</i> (<a href="https://sites.google.com/view/aiotas2017/">AIoTAS 2017</a>), as co-located at ISCA 2017, taking in place in Toronto, Canada in June 2017. The paper proposes Devify, an open source software framework for peer-to-peer IoT networks. 

Also, the nature of the distributed ledger technology (DLT) has a large opportunity to toward a more secure and trusted IoT network. Therefore, this paper has already developed <a href="https://flowchain.co">Flowchain</a>, the blockchain for the IoT, to practically prove the concept of this work.
]]>
      
   </content>
</entry>
<entry>
   <title>區塊鏈演講 &amp; 講稿下載：LinuxCon + ContainerCon + CloudOpen (LC3), Beijing, China, 2017</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2017/10/flowchain-linuxcon-china-2017.html" />
   <id>tag:www.jollen.org,2017:/blog//2.872</id>
   
   <published>2017-10-19T05:36:06Z</published>
   <updated>2017-10-19T10:40:37Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 ![](https://i.imgur.com/4Xei5MLl.jpg) 為什麼區塊鏈是 Web 3.0 的概念？因為 Web 3.0 有一個重要的概念，就是 P2P Internet。區塊鏈除了能為 Web 3.0 提供 P2P Internet 基礎建設外，也因為區塊鏈本身「天然特性」，還能提供 Web 3.0 所需的 Trusted Computing 與 Cryptography 技術。 Trusted computing 與 cryptography 在 IoT 領域，能提供絕佳的 Data security 與 Data privacy 環境。因此，一個建立在...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2017/10/flowchain-linuxcon-china-2017.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="https://i.imgur.com/9h8vthIh.jpg">


![](https://i.imgur.com/4Xei5MLl.jpg)

為什麼區塊鏈是 Web 3.0 的概念？因為 Web 3.0 有一個重要的概念，就是 P2P Internet。區塊鏈除了能為 Web 3.0 提供 P2P Internet 基礎建設外，也因為區塊鏈本身「天然特性」，還能提供 Web 3.0 所需的 Trusted Computing 與 Cryptography 技術。

Trusted computing 與 cryptography 在 IoT 領域，能提供絕佳的 Data security 與 Data privacy 環境。因此，一個建立在 Web 概念與 P2P 網路之上，並且能提供 Data security 與 Data privacy 環境的物聯網架構，就是物聯網區塊鏈（Blockchain IoT）的主要研究方向。

Flowchain 計畫就是為此生。由 Linux Foundation 主辦的 LinuxCon + ContainerCon + CloudOpen (LC3) 今年（2017）首次到北京舉辦，而且也設立了區塊鏈專場，利用這個難得的機會，投稿了今年 LC3 的 Blockchain Track；很幸運地得到 reviewers 的青睬，順利得到一個珍貴的演講機會。

## 議程與講稿下載

![](https://i.imgur.com/E7lRktbl.jpg)

* 官方議程（英文）：[LinuxCon + ContainerCon + CloudOpen China](https://goo.gl/c5zeaK)
* 講稿下載：[Flowchain: A Case Study on Building a Blockchain for the IoT](http://schd.ws/hosted_files/lc3china2017/43/Flowchain-LC3_2017_Beijing-20170614.pdf)
* [演讲内容中文介紹](https://www.bagevent.com/event/561769?sId=7411)
* [LC3大会技术亮点探秘之上篇](http://geek.csdn.net/news/detail/202037)

![](https://i.imgur.com/HDQ2MTJl.jpg)


</script>]]>
      
   </content>
</entry>
<entry>
   <title>Blockchain Developer - 初探 Distributed Ledger Technology (DLT)</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2017/09/blockchain-developer-distributed-ledger.html" />
   <id>tag:www.jollen.org,2017:/blog//2.871</id>
   
   <published>2017-09-30T06:24:58Z</published>
   <updated>2017-09-30T11:41:59Z</updated>
   
   <summary>DLT 有一個更耳熟能詳的名字，叫做區塊鏈... 本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 # Distributed Ledger Technology (DLT) DLT 有一個更耳熟能詳的名字，叫做區塊鏈。簡單來說，根據 Wikipedia 上的定義 [1]，區塊鏈（Blockchain）就是一種 Distributed Ledger 的資料結構（Data Structure）： ``` a Blockchain is only one type of data structure considered to be a distributed ledger. ``` 也就是說，DLT 可以延用 Blockchain 資料結構設計，也可以根據應用的不同，設計全新的資料結構；無論是採用...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>DLT 有一個更耳熟能詳的名字，叫做區塊鏈...</p>

<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2017/09/blockchain-developer-distributed-ledger.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="http://i.imgur.com/eoxcQmh.jpg">

# Distributed Ledger Technology (DLT)

DLT 有一個更耳熟能詳的名字，叫做區塊鏈。簡單來說，根據 Wikipedia 上的定義 [1]，區塊鏈（Blockchain）就是一種 Distributed Ledger 的資料結構（Data Structure）：

```
a Blockchain is only one type of data structure considered to be a distributed ledger.
```

也就是說，DLT 可以延用 Blockchain 資料結構設計，也可以根據應用的不同，設計全新的資料結構；無論是採用 Blockchain 資料結構，或是設計新的資料結構，目標都是提供一個分散式資料儲存系統（distributed data storage）。一個 DLT Platform 除了要具備一個安全可信任的 distributed data storage，還具備以下 2 個元素：

* A peer-to-peer network
* Consensus algorithms

在 distributed data storage 網路上的電腦裝置，稱之為節點。由於 distributed data storage 需要考慮備援與錯誤修正的問題，因此會將一筆資料同步備援在多個節點上，這樣的技術就稱為 replication。當某一個節點上的該筆資料毀損時，扮演該筆資料備援角色的節點，就能協助該節點，回覆毀損的資料，這樣的技術就稱為 redundancy。

技術上，DLT 就是一個為 distributed data storage 提供 replication/redundancy 功能的通訊協定（Protocol）。這樣的 replication/redundancy 機制，就稱為 fault tolerance（容錯機制）。

## Transactions

DLT 與傳統資料庫系統，除了上述的差別外，另一個重要的區別是：交易。DLT 儲存的是交易（Transaction）；而傳統資料庫儲存，則是儲存「資料」（Data）。

交易與資料的一個區別是，交易需要被「驗證」（validation）；而資料卻是可以直接地，儲存進資料庫裡即可。交易會包含所要儲存的資料，因此，可以說交易是資料的「封裝」。

在軟體設計的領域裡，封裝有「打包」的意思；也就是說，這像是在寄掛號信，我先將文件（資料）放進信封打包好，再將郵件「提交」到郵局，最後由收件人簽收無誤後取出文件，再將文件歸檔（儲存）。

在一個 DLT Platoform 裡，交易的驗證過程，需要決定該筆交易的接受者與簽收方式，這就開始涉及 Broadcast 與 Consensus 技術了。最終，這筆交易會被節點儲存，而儲存交易的地方就稱為 Block（區塊）；這些區塊將不只一個，而是一個 chain of blocks 的結構，這些串接在一起的 blocks 就稱為 blockchain。

## Byzantine Fault Tolerance（拜占庭容錯算法）

DLT 是一個比 Blockchain 更整體的研究主題，例如知名的 Hyperledger 就是一個 DLT 平台。Fault tolerance 與 transactions 則是 DLT 的核心骨幹。像是 PBFT（Practical Byzantine Fault Tolerance ）就是一個知名的 fault tolerance 演算法，並且被 Hyperledger Fabric v0.6 所採用。

SBFT（Simplified Byzantine Fault Tolerance）也是一種 fault toerance 演算法，由 Hyperledger Fabric v1.0 實作；SBFT 演算法延續自 PBFT，目標是擴充 PBFT 以支援更大規模（large scale）的 p2p 網路。


拜占庭容錯算法，目前經常被稱為共識算法（consensus algorithms）；雖然二者是不同的技術，不過現在似乎也不會這麼嚴謹地區分了。

## References

[1] https://en.wikipedia.org/wiki/Distributed_ledger


</script>]]>
      
   </content>
</entry>
<entry>
   <title>[Flowchain 專欄] 一分鐘看 IoT Blockchain (Part 6)：使用 Fullstack JavaScript</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2017/06/iot-blockchain-flowchain-fullstack.html" />
   <id>tag:www.jollen.org,2017:/blog//2.870</id>
   
   <published>2017-06-15T12:17:29Z</published>
   <updated>2017-06-15T17:31:07Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 Heterogenous Hardware 的觀念非常簡單：各式各樣的硬體裝置。 ## 各式各樣的硬體裝置 Heterogenous Hardware 的目標更為單純：「Write once, run everywhere」。對 IoT Blockchain 來說，是否能打造一套能在各式各樣硬體裝置上執行的軟體框架，會是一個關鍵議題。 使用 JavaScript 來實作 IoT 系統是一個流行，但更實質的原因，則是為了 Heterogenous Hardware。如圖一，Flowchain 以及它的底層通訊系統（Devify）都是 100% 的 JavaScript 實作，這可以解決基本的移植性問題。以現今的 IoT Device 硬體技術來說，Flowchain 能安裝在 Microcontroller、Microprocessor 與 Cloud Server 上。 ## Flowchain...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2017/06/iot-blockchain-flowchain-fullstack">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="http://i.imgur.com/mwX8cwYh.jpg">

Heterogenous Hardware 的觀念非常簡單：各式各樣的硬體裝置。

## 各式各樣的硬體裝置

Heterogenous Hardware 的目標更為單純：「Write once, run everywhere」。對 IoT Blockchain 來說，是否能打造一套能在各式各樣硬體裝置上執行的軟體框架，會是一個關鍵議題。

使用 JavaScript 來實作 IoT 系統是一個流行，但更實質的原因，則是為了 Heterogenous Hardware。如圖一，Flowchain 以及它的底層通訊系統（Devify）都是 100% 的 JavaScript 實作，這可以解決基本的移植性問題。以現今的 IoT Device 硬體技術來說，Flowchain 能安裝在 Microcontroller、Microprocessor 與 Cloud Server 上。

## Flowchain 基礎架構

Flowchain 是一個從底層到上層，都使用 JavaScript 實作的軟體框架（Fullstack JavaScript）。不過，區塊鏈要能支援 Heterogenous Hardware，共識算法的研究與設計，才是真正的關鍵。

![flowchain-linux-foundation_r3 001](https://user-images.githubusercontent.com/1126021/27135860-40c355de-514c-11e7-8876-e6694b9823bc.jpg)

## 小結

原生 P2P 演算法要應用在 IoT Blockchain，需要處理演算法上的一些細節。

</script>]]>
      
   </content>
</entry>
<entry>
   <title>[Flowchain 專欄] 一分鐘看 IoT Blockchain (Part 5)：認識 Churn 現象</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2017/06/iot-blockchain-flowchain-churn.html" />
   <id>tag:www.jollen.org,2017:/blog//2.869</id>
   
   <published>2017-06-15T12:15:59Z</published>
   <updated>2017-06-15T17:53:30Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 Chord 能運用在 Peer-to-Peer 的 IoT 網路，但是有些技術細節必須從軟體架構的層面解決。第一個會面的技術問題，就是「Churn」現象。 ## 進進出出 所謂的 Churn 現象就是：在 Peer-to-Peer 網路中，隨時都有節點（node）加入或離開（進進出出）。對於 Churn 的處理，要根據不同的 P2P 演算法來進行研究。Chord 如何處理 Churn 問題，以及 Handling Churn 的效能分析，過去已經有許多研究論文提出解決方法。 至於 [Flowchain 區塊鏈](https://flowchain.io) 當然也有針對 Churn 進行研究。在 Flowchain 裡面，處理 Churn 現象的方式，是以擴充 Chord Protocols 的方式來進行處理；這方面的研究，已經撰寫成學術論文，並且被 [AIoTAS...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2017/06/iot-blockchain-flowchain-churn">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="http://i.imgur.com/mwX8cwYh.jpg">

Chord 能運用在 Peer-to-Peer 的 IoT 網路，但是有些技術細節必須從軟體架構的層面解決。第一個會面的技術問題，就是「Churn」現象。

## 進進出出

所謂的 Churn 現象就是：在 Peer-to-Peer 網路中，隨時都有節點（node）加入或離開（進進出出）。對於 Churn 的處理，要根據不同的 P2P 演算法來進行研究。Chord 如何處理 Churn 問題，以及 Handling Churn  的效能分析，過去已經有許多研究論文提出解決方法。

至於 [Flowchain 區塊鏈](https://flowchain.io) 當然也有針對 Churn 進行研究。在 Flowchain 裡面，處理 Churn 現象的方式，是以擴充 Chord Protocols 的方式來進行處理；這方面的研究，已經撰寫成學術論文，並且被 [AIoTAS 2017](https://sites.google.com/view/aiotas2017/program) 接受並發表。

## Churn Rates

當 P2P 網路的節點，很頻繁地加入或離開時，這個網路稱為 High Churn Rates。如果 IoT Blockchain 無法有效處理 High Churn Rates 的問題，Data Transactions 的能力就會降低。例如，有資料需要交易處理時，就要經由 DHT 裡找到負責節點，但這個節點可能已經離開了。

IoT 裝置會離開 P2P 網路的原因，可能是 Wi-Fi 訊號不良，也可能是電量問題等其它問題；這和以 PC 為主的典型 P2P 網路非常不同。例如：PC 並非電池式裝置，因此電池式裝置的 Churn Rates，理論上會比 PC 為主的 P2P 網路高。又如，Wi-Fi 訊號問題，造成 P2P 網路中，經常有裝置會離線，這又是另一個造成 High Churn Rates 的因素。

## 小結

原生 P2P 演算法要應用在 IoT Blockchain，需要處理演算法上的一些細節。

</script>]]>
      
   </content>
</entry>
<entry>
   <title>[Flowchain 專欄] 一分鐘看 IoT Blockchain (Part 4)：認識 Chord 通訊協定</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2017/06/iot-blockchain-flowchain-chord.html" />
   <id>tag:www.jollen.org,2017:/blog//2.868</id>
   
   <published>2017-06-15T12:12:29Z</published>
   <updated>2017-06-15T17:50:01Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 Flowchain 使用一個稱為 Chord 的 P2P 通訊協定，[flowchain-chord](https://github.com/jollen/flowchain-chord) 是一份 Node.js 的實作。 近來受到相當程度討論的去中心化（Decentralized）概念，則是基於 Peer-to-Peer 通訊網路的分散式系統。Peer-to-Peer 的研究在 2000 年左右，就已經有相關的研究論文發表。Decentralized 與 Block Store 的觀念，在這裡論文裡已經被提出討論。可見這二個目前廣為討論的觀念（Decentralized 與 Block Store）都不是新鮮技術了。 ## 關於 DHT 與 Chord Protocol Chord[1] 是一個 DHT（distributed hash table）通訊協定，在 peer-to-peer 通訊網路中，DHT 指的是節點（nodes）的 store，用來儲存「資料的負責節點」。因此，Chord...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2017/06/iot-blockchain-flowchain-chord">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="http://i.imgur.com/mwX8cwYh.jpg">

Flowchain 使用一個稱為 Chord 的 P2P 通訊協定，[flowchain-chord](https://github.com/jollen/flowchain-chord) 是一份 Node.js 的實作。

近來受到相當程度討論的去中心化（Decentralized）概念，則是基於 Peer-to-Peer 通訊網路的分散式系統。Peer-to-Peer 的研究在 2000 年左右，就已經有相關的研究論文發表。Decentralized 與 Block Store 的觀念，在這裡論文裡已經被提出討論。可見這二個目前廣為討論的觀念（Decentralized 與 Block Store）都不是新鮮技術了。

## 關於 DHT 與 Chord Protocol

Chord[1] 是一個 DHT（distributed hash table）通訊協定，在 peer-to-peer 通訊網路中，DHT 指的是節點（nodes）的 store，用來儲存「資料的負責節點」。因此，Chord 協定能讓 P2P 網路尋找 Data 的負責節點，Chord 協定同時也維護所謂的指向表（Finger Table）來提升尋找節點的效能。Chord 於 2001 年誕生於 MIT[2][3]。

除了 Chord 外，連同其它 3 個 P2P 演算法：CAN、Tapestry 與 Pastry，被稱為 P2P 的 4 大原始演算法。P2P 演算法會維護一份稱為 DHT 的表格，這個表格便是用來紀錄「資料的負責節點」；以 Chord 為例，如果有一筆資料 *D1* 被送進 P2P 網路裡，負責處理這筆資料的節點稱為 *successor*，以 *sucessor(D1)* 來表示，*successor()* 函數將傳遞進來的資料做 Hash 運算，以 *successor(D1)=key1* 來表示。

簡而言之，P2P 透過 DHT 來找到負責處理資料的人。Flowchain 區塊鏈就是使用 Chord 來維護 DHT；關於 Chord Protocol 的研究，會參考 [MIT Chord/DHash](https://github.com/sit/dht) 的原始實作。這是一份 C++ 的實作，Flowchain 則是使用 JavaScript 重新實作了一份輕量化的 Chord 協定。

## Chord Protocols

Chord protocols 分為 5 個部份：

* Basic query
* Finger table
* Node join
* Stabilization
* Failures and replication

## Stabilization 算法

這是 Chord protocol 最重要的一個環節，根據 Chord protocol 的規範：

* Stabilization protocol 是週期性地（periodically）在背景執行
* 更新 finger table 與 successor pointers
  
以 JavaScript 來實現 stabilization protocol 的方式：

* 使用 ```setInterval``` 實現週期性執行（理論上這可以有更好的 scheduling 實現）

Stabilization protocol 的算法分二個部份：

* Stabilize()
* Nofity()

先定義 ```Stabilized()``` 與 ```Notify()``` 的訊息：

```
// 定義訊息類型
var FIND_PREDECESSOR = 0;
var NOTIFY_PREDECESSOR = 1;
```

其中，```Stabilized()``` 負責向 successor 請求它的 predecessor，並決定 predecessor 是否要成為新的 sucessor：

```
setInterval(function Stabilize() {
// 請求 predecessor，並將 predecessor 做為新的 successor
    send(successor, {type: FIND_SUCCESSOR, next: next_finger});
}, 1000);
```

此外，```Notify()``` 負責告知 sucessor 我是它的 node，讓 successor 能更新 finger table：

```
setInterval(function check_predecessor_and_stabilize() {
// 向 successor 請求 predecessor
    send(successor, {type: NOTIFY_PREDECESSOR});
}, 1000);
```

## Node join

新的 node 建立時，要執行以下任務：

* 初始化 node 的 predecessor 與 finger table
* 通知其它 nodes 更新 predecessors 與 finger table
* 從 sucessor 取得 responsible keys

## Finger Table

Finger table 是 Chord 的搜尋演算法。Node 可以經由 finger table 來找到任意節點。Finger table 的演算法設計，搜尋節點的關鍵，它可以避免線性（linear）搜尋的做法。每一個 node 都會有 finger table，finger table 的第 i 個 entry 紀錄的是 sucessor( (n + 2^(i-1)) mod 2^m )。

* _m_ 是 ring 長度，也就是finger table 的長度。這是 Chord network 的最大（最多）節點數量。
* successor 與 predecessor 是重要的觀念。

Finger table 是一個 hash ring 的結構。Chord 經由 predecessor 的觀念，來簡化 join 與 leave 的機制[2]。

## 小結

要以 P2P Topology 方式建構 IoT Blockchain，對於 P2P 演算法的深入研究，絕對是一項基本功。

## References

[1]: Chord, [https://en.wikipedia.org/wiki/Chord_(peer-to-peer)](https://en.wikipedia.org/wiki/Chord_%28peer-to-peer%29)

[2]: I. Stoica, et al, [Chord: A scalable peer-to-peer lookup service for internet applications](https://pdos.csail.mit.edu/papers/chord:sigcomm01/chord_sigcomm.pdf)

[3]: LibraRing: An Architecture for Distributed Digital Libraries Based on DHTs, http://scholar.harvard.edu/files/ecdl05.pdf

[4]: CS138, http://cs.brown.edu/courses/cs138/s15/content/projects/chord.pdf

[5]: Distributed Hash Tables, http://merlot.usc.edu/cs551-m05/lectures/tentative/20a_chord.pdf

[6]: http://zoo.cs.yale.edu/classes/cs722/2011/Jason_chord.pdf

[7]: http://www.dcs.ed.ac.uk/teaching/cs3/ipcs/chord-desc.html

[8]: http://slideplayer.com/slide/4418035/

[9]: http://www.slideshare.net/imprataap/chord-node-join

</script>]]>
      
   </content>
</entry>
<entry>
   <title>[Flowchain 專欄] 一分鐘看 IoT Blockchain (Part 3)：認識 Servient</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2017/06/iot-blockchain-flowchain-servient.html" />
   <id>tag:www.jollen.org,2017:/blog//2.867</id>
   
   <published>2017-06-05T17:54:59Z</published>
   <updated>2017-06-05T22:57:13Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 MCS Lite 導入了我開發的 Devify 框架，所以也有 Servient 玩法喔。 # 認識 Servient Servient 概念非常簡單：IoT Device 能同時扮演 Client 與 Server 的角色。這個 ```Client + Server = Servient``` 的觀念，是 Decentralized 與 P2P 非常重要的底層技術。 從 IoT Architecture 的觀念來說，並不是去辨別（identify）每一個物聯網裝置要扮演 Client 或 Server 哪一個角色，而是來開發一個能讓裝置扮演 ```Client...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2017/06/iot-blockchain-flowchain-servient.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="http://i.imgur.com/mwX8cwYh.jpg">

MCS Lite 導入了我開發的 Devify 框架，所以也有 Servient 玩法喔。

# 認識 Servient

Servient 概念非常簡單：IoT Device 能同時扮演 Client 與 Server 的角色。這個 ```Client + Server = Servient``` 的觀念，是 Decentralized 與 P2P 非常重要的底層技術。

從 IoT Architecture 的觀念來說，並不是去辨別（identify）每一個物聯網裝置要扮演 Client 或 Server 哪一個角色，而是來開發一個能讓裝置扮演 ```Client + Server``` 角色的軟體。

為什麼需要 *Servient* 這樣的架構呢？這個問題，可以很容易用圖 1 來解答。

![flowchain-linux-foundation_r3 001](https://cloud.githubusercontent.com/assets/1126021/26793654/5b845500-4a51-11e7-8ea8-c64c2eeb35f8.jpg)
圖 1：IoT Servient

當 *Device A* 想要以 WebSocket 來傳送資料到 *Device B* 時：

* *Device A* 要扮演 WebSocket Client 的角色；
* *Device B* 則是必須成為 WebSocket Server

當 *Device B* 想要以 CoAP 來傳送資料到 *Device C* 時：

* *Device B* 要轉變為 CoAP Client 的角色，同時；
* *Device C* 則要扮演  CoAP Server 的角色

以上述的 Use Case 來說：

* *Device A* 是 WebSocket Client
* *Device B* 是 *WebSocket Server + CoAP Client*
* *Device C* 是 *CoAP Server*

Servient 並不是一個很普遍的架構觀念，過去在一些技術文件上也能偶然看到 Servient 的觀念；但是，Servient 在 IoT 領域被正式提及，則是在 ISWC 2016 國際研討會上。在 ISWC 2016 上，Soumya Kanti Datta 在 *Semantic Web meets Internet of Things and Web of Things* 的 Tutorial 上，正式提到 WoT **Servient** 的觀念。

近期，在 *Web of Things (WoT) Architecture: Unofficial Draft* 文件中，已經將 WoT Servient 編入 *Terminology*。隨著 WoT 在今年（2017）已經正式由 IG（Interest Group）轉為 WG（Working Group），未來 WoT 也會正式列入這個架構。

## 小結

當 IoT Device 能以 Servient 的形式運作，IoT Device 間的「互聯網」：互相聯結的 IoT 網路，就可以是 Client-Server 架構、Peer-to-Peer 架構或是 Distributed 架構。

## 關於 *MCS Lite*

關於 IoT Servient 的技術，在 [Devify](https://github.com/DevifyPlatform) 專案裡有完整的實作。Devify 是我過去在研究[物聯網區塊鏈](https://flowchain.co)時做開發的底層 WoT 系統。

由聯發科所開發的 LinkIt 7697 物聯網平台，提供一個稱為 *MCS Lite* 的私有雲方案；*MCS Lite* 裡就使用到我所開發的 Devify 框架。也就是說，[LinkIt 7697 + MCS Lite](https://dariachen1.gitbooks.io/mcs-lite-introduction/content/mcs_lite_example.html) 還有更多 IoT 的完法喔。

</script>]]>
      
   </content>
</entry>
<entry>
   <title>IoT Blockchain paper accepted at LD-DL @ESWC&apos;17</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2017/05/iot-blockchain-paper.html" />
   <id>tag:www.jollen.org,2017:/blog//2.866</id>
   
   <published>2017-05-19T16:03:43Z</published>
   <updated>2017-10-23T11:04:59Z</updated>
   
   <summary>My paper titled “Flowchain: A Distributed Ledger Designed for Peer-to-Peer IoT Networks and Real-time Data Transactions” has been accepted by the 2nd International Workshop on Linked Data and Distributed Ledgers, as co-located at ESWC 2017, taking in place in Portoroz,...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[My paper titled “Flowchain: A Distributed Ledger Designed for Peer-to-Peer IoT Networks and Real-time Data Transactions” has been accepted by the <i>2nd International Workshop on Linked Data and Distributed Ledgers</i>, as co-located at ESWC 2017, taking in place in Portoroz, Slovenia in May 2017. The paper proposes <a href="https://flowchain.co">Flowchain</a>, an open source distributed ledger programming framework, for peer-to-peer IoT networks and real-time data transactions. 

Also, Flowchain proposes <b>Virtual Blocks</b> that provides a new blockchain data structure design to ensure the real-time data transactions. This paper also proposes a software architecture that provides peer-to-peer IoT networking and interoperable IoT application framework.

<ul>
<li> 2017.10.23 UPDATE: The paper can be download at the <a href="https://sites.google.com/site/lddleswc17/program">LD-DL</a> workshop website.</li>
</ul>]]>
      
   </content>
</entry>
<entry>
   <title>[Flowchain 專欄] 一分鐘看 IoT Blockchain (Part 2)：P2P 通訊架構</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2017/04/iot-blockchain-flowchain-p2p.html" />
   <id>tag:www.jollen.org,2017:/blog//2.865</id>
   
   <published>2017-04-30T05:06:04Z</published>
   <updated>2017-04-30T10:08:51Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 Decentralized 物聯網架構，需要 P2P 的通訊架構。 # 邁向 Decentralized 的關鍵 在 IoT 架構裡，實作 Peer-to-Peer (P2P) 網路有技術上的挑戰嗎？實作 Peer-to-Peer IoT Networking 的目標，是為了讓 IoT Devices 間能建立 P2P 架構的通訊方式，這就是技術上的挑戰了。讓 IoT Devices 能形成一個 P2P 網路，技術上似乎不太困難；不過，如果更深入技術細節來討論，就會發現許多學問。 第一、應用層的考量。IoT 裝置間必須以 Application Layer Protocols 來通訊，例如：HTTP。所以，我們需要能在 IoT 裝置上運行一個「Application Server」，也就是說，必須有一個「Programming...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2017/04/iot-blockchain-flowchain-p2p.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="http://i.imgur.com/mwX8cwYh.jpg">

Decentralized 物聯網架構，需要 P2P 的通訊架構。

# 邁向 Decentralized 的關鍵

在 IoT 架構裡，實作 Peer-to-Peer (P2P) 網路有技術上的挑戰嗎？實作 Peer-to-Peer IoT Networking 的目標，是為了讓 IoT Devices 間能建立 P2P 架構的通訊方式，這就是技術上的挑戰了。讓 IoT Devices 能形成一個 P2P 網路，技術上似乎不太困難；不過，如果更深入技術細節來討論，就會發現許多學問。

第一、應用層的考量。IoT 裝置間必須以 Application Layer Protocols 來通訊，例如：HTTP。所以，我們需要能在 IoT 裝置上運行一個「Application Server」，也就是說，必須有一個「Programming Framework」，然後才能在 IoT 裝置上開發這個 Application Server。這裡所提及的 Programming Framework，可以是 IoT 作業系統，或是 Middleware；但其實重點在於，為什麼 P2P 的 IoT Networking，要使用最上層的 Application Layer Protocols；這是一個值得探索的有趣議題。

第二、異質硬體的考量。[Flowchain](https://flowchain.io) 計畫的早期，是從打造一個 Web of Things Framework [1] 起步，這個軟體框架的目的，是以 JavaScript 實作一個 IoT Application Server 的開發框架，有了這個框架，就能達到二個目的：

* 能在不同的 IoT Device 上運行此 IoT Application Server 
* 將 IoT Device 抽象化為 **Virtual Thing**

如果異質硬體都能具備 JavaScript runtime，同樣的 IoT Application Server 就能佈署並運行在這些硬體上。因為 Node.js、JerryScript 等技術被帶入到這些硬體上，這個想法現在有了很高的可行性。

## 小結

IoT Blockchain 並非一個主題，而是一套 IoT Architecture，當中的 P2P Networking，有賴於一個 IoT Application Server 的框架來實現。

## References

[1]: Web of Things Implementations, https://www.w3.org/WoT/IG/wiki/Implementations

</script>]]>
      
   </content>
</entry>
<entry>
   <title>[Flowchain 專欄] 一分鐘看 IoT Blockchain (Part 1)：Decentralized 創造附加新價值</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2017/04/iot-blockchain-flowchain-decentralizedhtml.html" />
   <id>tag:www.jollen.org,2017:/blog//2.864</id>
   
   <published>2017-04-28T07:57:10Z</published>
   <updated>2017-04-30T10:05:43Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 當你的 IoT 資料，將資料送至中央化的 IoT Platform 時，原本該屬於你的資料所有權、使用權與儲存地，將會默默超出自已的可控制範圍。 # 從 IoT Architecture 看物聯網區塊鏈 IEEE 在 2017 年 1 月發佈一篇 Newsletter 分析 IoT Blockchain 的技術挑戰 [1]，文中提到，從 IoT Architecture 的角度，可以看到 IoT Blockchain 的幾個主要技術挑戰。簡單來說，一個「Decentralized」的 IoT Architecture 將會有機會克服當中的一些技術挑戰。 將 Blockchain 技術應用在 IoT 架構中時，需要「Decentralized」的...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2017/04/iot-blockchain-flowchain-decentralizedhtml.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="http://i.imgur.com/mwX8cwYh.jpg">

當你的 IoT 資料，將資料送至中央化的 IoT Platform 時，原本該屬於你的資料所有權、使用權與儲存地，將會默默超出自已的可控制範圍。

# 從 IoT Architecture 看物聯網區塊鏈

IEEE 在 2017 年 1 月發佈一篇 Newsletter 分析 IoT Blockchain 的技術挑戰 [1]，文中提到，從 IoT Architecture 的角度，可以看到 IoT Blockchain 的幾個主要技術挑戰。簡單來說，一個「Decentralized」的 IoT Architecture 將會有機會克服當中的一些技術挑戰。

將 Blockchain 技術應用在 IoT 架構中時，需要「Decentralized」的 IoT 架構，成為一個標準的討論議題。不過，這個去中心化的架構，能為 IoT 應用帶來什麼好處呢？其中最重要的議題，就是 Data Privacy。當你把 IoT 資料傳送到特定的 IoT Platform 時，對於珍貴的資料所有權、使用權與儲存地，就會開始失控。

資料是物聯網系統最重要的資產。因此，回歸區塊鏈的本質來看，IoT Blockchain 能為現有的物聯網網路架構提供 Data Privacy 的解決方案，同時，透過 Trust 機制的導入，讓 Data Security 更加提昇。Data Privacy 與 Data Security 二個議題，與 Semantic Web 的訴求有共同的交集。也就是說，從場景應用的角度來看，IoT 區塊鏈技術不在解決高深的技術問題，**而是為現有的 IoT 產業生態，提供 Data Privacy 與 Trust 的附加商業價值**。

解決技術問題不一定能創造出新的商業模式，但有了附加價值，新的商業價值，以及新的商業模式，就有機會自然而生。所以，Flowchain 之所以要有去中心化架構的原因，不在於新技術，而是希望創造這樣的附加商業價值。

## 後續

單純從技術來看，如何才能打造一個 Decentralized 的 IoT Architecture 呢？目前，最普遍的看法是，使用 Peer-to-Peer 的技術來實作 IoT Network。[Flowchain](https://flowchain.io) 計畫就是希望以 Peer-to-Peer Networking 的方式，來建立 IoT Blockchain 的系統。

> 本專欄透過「每天一分鐘」的短篇幅文章，整理「IoT Blockchain」的精華。內容主要來源為 Flowchain 計畫的研究分享，以及個人觀點匯整。

## References

[1]: IoT and Blockchain Convergence: Benefits and Challenges, http://iot.ieee.org/newsletter/january-2017/iot-and-blockchain-convergence-benefits-and-challenges.html

</script>]]>
      
   </content>
</entry>
<entry>
   <title>Blockchain Developer - 快速認識 Proof-of-Stake</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2017/02/blockchain-developer-proof-of-stake.html" />
   <id>tag:www.jollen.org,2017:/blog//2.863</id>
   
   <published>2017-02-16T15:29:37Z</published>
   <updated>2017-02-16T21:33:07Z</updated>
   
   <summary>除了 Proof-of-Work（PoW）外，還有其它「形成共識」的做法嗎？除了 Proof-of-Work 外，還有一種稱之為 Proof-of-Stake（PoS）的共識系統... 本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 # Blockchain Developer - 快速認識 Proof-of-Stake 前一篇文章提到的 Proof-of-Work 是利用「運算」的方式來取得「共識」。除了 Proof-of-Work（PoW）外，還有其它「形成共識」的做法嗎？除了 Proof-of-Work 外，還有一種稱之為 Proof-of-Stake（PoS）的共識系統。不像 PoW 是以運算做為基礎，PoS 以「權益」做為基礎，來決定挖礦的難度。 除了 PoW 與 PoS 外，還有其它不同的共識系統： * PBFT[1] (Practical Byzantine Fault Tolerance - 拜占庭容錯算法) * Paxos /...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>除了 Proof-of-Work（PoW）外，還有其它「形成共識」的做法嗎？除了 Proof-of-Work 外，還有一種稱之為 Proof-of-Stake（PoS）的共識系統...</p>

<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2017/02/blockchain-developer-proof-of-stake.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="http://i.imgur.com/eoxcQmh.jpg">

# Blockchain Developer - 快速認識 Proof-of-Stake

前一篇文章提到的 Proof-of-Work 是利用「運算」的方式來取得「共識」。除了 Proof-of-Work（PoW）外，還有其它「形成共識」的做法嗎？除了 Proof-of-Work 外，還有一種稱之為 Proof-of-Stake（PoS）的共識系統。不像 PoW 是以運算做為基礎，PoS 以「權益」做為基礎，來決定挖礦的難度。

除了 PoW 與 PoS 外，還有其它不同的共識系統：

* PBFT[1] (Practical Byzantine Fault Tolerance - 拜占庭容錯算法)
* Paxos / The Part-Time Parliament [2] (希臘城邦算法)
* DPoS (Delegate Proof of Stake)

PoW 與 PoS 的共通點，就是他們都是以 hash function 為基礎，來「形成共識」；也就是 mining。

## PPCoin

Bitcoin 底層的區塊鏈，透過 mining 的方式來建立新的 block；mining 的 difficulty 透過 proof-of-work 系統來決定，接著，全世界各地的挖礦機，就要開始進行比賽，看誰能找出這個 difficulty 的 hash 值。

然而，Proof-of-Work 是一種消耗資源的工作；因此，開始有開發者，試圖使用其它的共識機制來建立新的加密貨幣（Cryptocurrency）系統。Peercoin（或稱為 PPCoin）就是第一個以 proof-of-stake 系統，所打造的加密貨幣 [3]。

## 快速認識 Proof-of-Stake

Proof-of-stake 的誕生，是為了取代 proof-of-work 系統，以減少大量運算所造成的資源消耗。此外，PoS 系統的加密貨幣，不一定要透過 mining 的過程來產生 cryptocurrency，可以採用「mint」的方式；即「鑄造」。這有點像「鑄幣廠」。在鑄造硬幣前，就要決定好「發行量」。

PoS 系統的 cryptocurrency 大多採用 mint 機制，而不是 mining 機制；所以說，貨幣是一開始就決定好數量並發行。

在 PoS 的區塊鏈系統裡，新的區塊如何產生呢？首先，要決定由哪個節點（node）來負責創造新區塊，再由該節點來建立下一個區塊。這就像是，大家一起討論，誰是下一個「鑄幣廠」，被選上的人就負責鑄造新硬幣。所有的節點都是鑄幣廠，也都有機會獲選鑄造新硬幣；所以，這不是「中央鑄幣廠」的機制，而是去中心化的機制。

至於如何決定負責創造新區塊的節點，就是以每個節點的權益（stake）來決定。這就有別於 Bitcoin 的 mining 機制了。Bitcoin mining 機制，是所有人在比賽創造新區塊，並且靠的是運算能力；誰創造了新的區塊？是無法預期的，所以是誰創造了下一個區塊，是非常隨機的（random）。

然而，PoS 機制下，創造了下一個區塊的人，是可預期的（deterministic）。PoW 系統的區塊產生是 random 方式；PoS 系統的區塊產生則是 deterministic 方式（或稱為 pseudo-random ）。

## 小結

做為 blockchain 的底層系統開發者，有許多議題是重要的研究功課，例如：物聯網區塊鏈，適合使用 PoW 或 PoS 系統來設計？

## References

[1] Practical Byzantine Fault Tolerance, http://pmg.csail.mit.edu/papers/osdi99.pdf

[2] The Part-Time Parliament, https://www.microsoft.com/en-us/research/wp-content/uploads/2016/12/The-Part-Time-Parliament.pdf

[3] PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, https://peercoin.net/assets/paper/peercoin-paper.pdf

</script>]]>
      
   </content>
</entry>
<entry>
   <title>Blockchain Developer - 簡單易懂的 Memory-Hard Function</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2016/12/blockchain-developer-memory-hard.html" />
   <id>tag:www.jollen.org,2016:/blog//2.862</id>
   
   <published>2016-12-09T14:50:27Z</published>
   <updated>2016-12-09T21:15:28Z</updated>
   
   <summary>Bitcoin mining 演算法，就是使用傳統的 SHA-256 函數，而 SHA-256 的優點，也好就是它的一個缺點... 本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 # Blockchain Developer - 簡單易懂的 Memory-Hard Function SHA-256 函數是傳統的 hash 演算法，但是應用在區塊鏈系統時，有一個缺點。Bitcoin mining 演算法，就是使用傳統的 SHA-256 函數，而 SHA-256 的優點，也好就是它的一個缺點。 ## SHA-256 的問題 為了提升 SHA-256 的計算速度，工程師會利用行平行處理（parallelism）的技術。利用平行運算，大幅提升 SHA-256 的運算速度，這樣做不是很好嗎？ 然而，這就是一個問題了。簡單來說，一個能平行化的演算法，就能使用硬體來做加速，例如：使用 GPU、FPGA 或是 ASIC。這裡就是「弊端」所在了。從 Proof-of-Work...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>Bitcoin mining 演算法，就是使用傳統的 SHA-256 函數，而 SHA-256 的優點，也好就是它的一個缺點...</p>

<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2016/12/blockchain-developer-memory-hard.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="http://i.imgur.com/eoxcQmh.jpg">

# Blockchain Developer - 簡單易懂的 Memory-Hard Function

SHA-256 函數是傳統的 hash 演算法，但是應用在區塊鏈系統時，有一個缺點。Bitcoin mining 演算法，就是使用傳統的 SHA-256 函數，而 SHA-256 的優點，也好就是它的一個缺點。

## SHA-256 的問題

為了提升 SHA-256 的計算速度，工程師會利用行平行處理（parallelism）的技術。利用平行運算，大幅提升 SHA-256 的運算速度，這樣做不是很好嗎？

然而，這就是一個問題了。簡單來說，一個能平行化的演算法，就能使用硬體來做加速，例如：使用 GPU、FPGA 或是 ASIC。這裡就是「弊端」所在了。從 Proof-of-Work 的觀點來看，「大家必須公平地做計算」，意思是說，因為 hash 值的運算是「decentralization」的架構，所以「大家的硬體最好一樣」。

## Decentralization of Trust

Proof-of-work 的主要工作是 mining。此外，驗證交易的「可信度」，也是 proof-of-work 的一環。Proof-of-work 的工作不此於此，例如：miner 間的資料庫同步，也是包含在內。總之，proof-of-work 很忙。

這些 proof-of-work 的工作，是 miners 一起進行的，而不是由一個中央伺服器（centralized）來統一運算，這就是 decentralization of trust 的觀念。

更簡單來看，這就是所謂的 decentralization（去中心化）架構。以 mining 來說，每個人都可以參與 hash 值的運算（大家都可以挖礦），所以，想「快一點」的人，就會使用 ASIC 挖礦機。可是，有些人是用自已的電腦來挖礦。

到這裡，問題就很清楚了：大家的硬體如果等級不同，挖礦就會「不公平」。當大家的運算速度都差不多，沒有人可以「大幅加速」時，理論上就公平了。

## Memory-Hard Function

為了解決這個問題，科學家就想出了一個方法。這個方法非常簡單，首先，你不可能強制每個人都要買一樣的電腦才能挖礦，所以解決方式就要回歸演算法的本質：parallelism。

於是，科學家提出一種稱為 memory-hard function 的 hash 演算法觀念：一種不能或難以平行化的 hash 演算法。

這讓我想過幾年前的一個有趣故事。過去，多核心處理器開始後，開始有 Android 手機的製造廠，以「多核心手機」做為市場宣傳口號。這當然很好啊，「多核就是快」。但是，學軟體的人都知道一個道理，就是「軟體必須支援多核心」。如果你的軟體設計，本身就不是多核心架構，那就會像這支手機一樣：明明是 4 核心，但是開機後，其實只用了 1 個核心，另外 3 個核心被關閉（省電考量）了。

有了 memory-hard function 後，「挖礦」就理論上公平了，並且也能消除弊端。因為，就算有頂極的挖礦機，也會像這支多核心手機一樣：再強的硬體也很難加速軟體運算。

## Memory Intensive

Memory-hard function 是怎麼做到這點的呢？上述的「一種不能或難以平行化的 hash 演算法」，其實是利用這個原理：降低平行處理的優勢。讓平行處理難有發揮的空間，這樣就能降低 GFP、FPGA 或 ASIC 挖礦機的優勢了。

要消除平行處理的優勢，只要讓軟體是 memory intensive 即可。Memory intensive 是每天都會看到的現象：記憶體不足時、電腦變慢。

Memory-hard function 的原理就是這樣，在 hash 運算時，可以透過「亂塞一堆資料到記憶體」的方式，降低硬體的運算優勢。這樣的 hash 演算法，就稱為 memory-hard function。這堆要塞到記憶體的資料，稱為 data array（array of data）。

## Argon2

[Argon2](https://github.com/p-h-c/phc-winner-argon2) 是屬於 memory-hard function 的一種演算法，Blockchain 開發者會知道它，是因為 Argon2 在 2015 年，從 24 個參賽者中，拿下 [PHC](https://password-hashing.net/) 競賽的優勝。

## 小結

Argon2 可以取代傳統的 SHA-256 函數。如果想要知道原因的話，一般的說法就是：Argon2 沒辦法用 ASIC 挖礦機進行挖礦。

接下來，可以試著 fork 一份 [block0](https://block0.org) 專案，導入 Argon2 演算法，並試著比較 Argon2 與 SHA-256 的挖礦困難度。


## 其它

* [Node.js Fullstack《從零到一的進擊》：初學者寫給初學者的全端軟體教材](https://github.com/jollen/nodejs-fullstack-book)

</script>]]>
      
   </content>
</entry>
<entry>
   <title>Blockchain Developer - 簡單易懂的 Mining 演算法設計</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2016/12/blockchain-developer-how-mining.html" />
   <id>tag:www.jollen.org,2016:/blog//2.861</id>
   
   <published>2016-12-06T09:05:25Z</published>
   <updated>2016-12-06T15:11:28Z</updated>
   
   <summary>假設表 1 是「最後一個 Block」內容，根據先前教學的介紹，要如何挖出新區塊呢... 本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 # 簡單易懂的 Mining 演算法設計 ## Mining 演算法初體驗 表 1 是截至目前為止，範例所設計的 Block 資料結構。假設表 1 是「最後一個 Block」內容，根據先前教學的介紹，要如何挖出新區塊呢？ |欄位 |範例 |用途說明 | |--------|--------|--------| |hash |dd0e2b79d79be0dfca96b4ad9ac85600097506f06f52bb74f769e02fcc66dec6 |Block Hash | |previousHash |0000000000000000000000000000000000000000000000000000000000000000 |前一個 Block 的 Hash 值 |...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>假設表 1 是「最後一個 Block」內容，根據先前教學的介紹，要如何挖出新區塊呢...</p>

<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2016/12/blockchain-developer-how-mining.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="http://i.imgur.com/eoxcQmh.jpg">

# 簡單易懂的 Mining 演算法設計

## Mining 演算法初體驗

表 1 是截至目前為止，範例所設計的 Block 資料結構。假設表 1 是「最後一個 Block」內容，根據先前教學的介紹，要如何挖出新區塊呢？

|欄位       |範例      |用途說明 |
|--------|--------|--------|
|hash     |dd0e2b79d79be0dfca96b4ad9ac85600097506f06f52bb74f769e02fcc66dec6      |Block Hash |
|previousHash       |0000000000000000000000000000000000000000000000000000000000000000 	   |前一個 Block 的 Hash 值 |
|timestamp     |Tue Dec 06 2016 15:14:58 GMT+0800 (CST)       |區塊建立的時間 |
|merkleRoot     |851AE7D7390A76384ACA2D7CC29BE820918CA900071FC22F41F5C399BE065558    |區塊的 Merkle Root |
|difficulty     |00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF    |挖礦的困難度 |

表 1 最後一個 Block 內容

表 1 的內容，將做為「挖礦」的依據：透過最後一個 Block 的資訊，計算出新區塊的 Hash 值。

一個簡單的挖礦演算法實作步驟如下。

### Step 1：建立新的 Merkle Tree

假設現在有一筆交易資訊，正等著被紀錄在區塊裡，這筆交易的狀態目前就是「待確認」。挖礦機就要先取得這筆「待確認」的交易資訊，再建立這筆交易的 Merkle tree。

多筆待確認交易的做法也相同：挖礦機先取得這些待確認的交易資訊，並建立它們的 Merkle tree。

以 Bitcoin 的網路來說，Bitcoin network 裡一個稱為「unverified pool」的地方，就是存放這些「待確認」的交易。因此，unverified pool 的設計與實作，是區塊鏈開發者的另一個課程，本教學暫不涉及 unverified pool 的介紹。

延續先前的教學，為一筆交易建立 Merkle tree 的程式碼實作如下：

```
// 一筆待確認的交易
var tx = [‘Created by Jollen’];

// Merkle root hash
var hashMerkleRoot;

merkleRoot.async(tx, function(err, tree){
    // 取得 Merkle Root 的 Hash
    hashMerkleRoot = tree.level(0)[0];
});
```

### Step 2：定義本文

這裡所講的「本文」，就是用來進行 SHA-256 計算的資料內容。一個簡單的本文定義，需要 3 個項資訊：

* *merkleRoot*：由前一個步驟產生
* *previousHash*：最後一個區塊的 block hash，未來產生的新區塊，要往前「鏈接」到這個區塊
* *nonce*：number once 的簡寫，在加密學裡，nonce 指的是只能使用一次的任意數

為簡化演算法的設計，可以將 *nonce* 定義為一個「流水號」。因為 *nonce* 只能使用一次，所以流水號只能「持續遞增」，不能歸零重算。

本文所需的資訊都收集齊全了，接著以 JavaScript 的物件語法，來定義本文如下：

```
var nonce = 0;

var header = {
	nonce: nonce,
	previousHash: ‘dd0e2b79d79be0dfca96b4ad9ac85600097506f06f52bb74f769e02fcc66dec6’,
	merkleRoot: hashMerkleRoot
};
```

本文的定義由區塊鏈開發者自行決定，例如：把 timestamp 也加入到本文裡。

### Step 3：Double SHA-256 運算

將 ```header``` 物件 stringify（轉換為文件）後，使用這個「文件」做為本文，來進行 SHA-256 雜湊運算：

```
// Secret
var secret = ‘Dummy Blockchain’;

var hash1 = crypto.createHmac(‘sha256’, secret)
					.update( JSON.stringify(header) )
					.digest(‘hex’);
```

再將得到的 hash 值，做為新的 secret，進行第 2 次運算：

```
var hash2 = crypto.createHmac(‘sha256’, hash1)
					.update(‘powered by flowchain’)
					.digest(‘hex’);
```

現在，```hash2``` 存放的就是 Block Hash 的「候選人」。如果 ```hash2``` 的值，確認為「success」的話，表示「挖礦成功」了：一個新的區塊被計算出來了。

### Step 4：Difficulty 運算

候選人的意思是：它還不一定是成功的 hash 值。必須比對 difficulty 的條件設定，才能決定這個 hash 值是否能使用。

延續先前教學的介紹，假設困難度是「有足夠的零」時，就要進行困難度的確認：

```
if (hash2 < ‘00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF’) {
	console.log(‘success: ‘ + id);
}
```

當 ```hash2``` 不滿足目前的 difficulty 條件時，就要重新計算，直到成功為止。

以上述的範例來說，當 hash 值不滿足 difficulty 條件時，就變更 nonce 值後，再重新運算。本文範例，使用流水號的方式來產生 nonce 值。

### Step 5：完整範例

根據前個的步驟，實作一段簡單的 mining 演算法如下：

```
var crypto = require(‘crypto’);
var merkle = require(‘merkle’);
var merkleRoot = merkle(‘sha256’);

// Secret
var secret = ‘Dummy Blockchain’;

// Unverified pool
var tx = [‘Created by Jollen’];

merkleRoot.async(tx, function(err, tree){
    // Merkle Root 的 Hash
    var hashMerkleRoot = tree.level(0)[0];
    var nonce = 0;

    var hash = function(nonce) {
	    var header = {
			nonce: nonce,
			previousHash: ‘dd0e2b79d79be0dfca96b4ad9ac85600097506f06f52bb74f769e02fcc66dec6’,
			merkleRoot: hashMerkleRoot
	    };

		var hash1 = crypto.createHmac(‘sha256’, secret)
							.update( JSON.stringify(header) )
							.digest(‘hex’);

		var hash2 = crypto.createHmac(‘sha256’, hash1)
                   			.update(‘powered by flowchain’)
							.digest(‘hex’);

		return hash2;
    };

    while (1) {
    	var id = hash(nonce++);
    	console.log(nonce + ‘: ‘ + id);
		if (id < ‘0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF’) {
			console.log(‘success: ‘ + id);
			break;
		}
    }
});
```

輸出結果：

```
…
7590: 9208c185a5d218dcd1a9ce63b4609a21c9ac90e0cad65d3355ce436522ded234
7591: 766ccefa06fd97cf8b1472809e03499321fde6ba1e7341e74bd7bbcdc0a7ce01
7592: f3cb6f4f6ae187556a3ec8218453d3073958eed430155cd73d9a8d2976d30e1f
7593: 74ff8bf0695100c6cce400fde5fcbfbb0574efb79664c229a8044df0525c39ca
7594: 0002db2b239b29f52711a2629e98face0151c2020f48c94a12459a43b24a3f85
success: 0002db2b239b29f52711a2629e98face0151c2020f48c94a12459a43b24a3f85
```

由這個結果發現，總計 mining 了 7594 次才得到成功的 hash 值。當 difficulty 提升時，mining 所花的時間也會更多。

例如，當困難度為「前面至少 4 個零」時，mining 的次數就增加到 118432  次。挖礦的困難度在於，產生的 hash 值有一定程度的「隨機」性，通常是不太可預期的。

### Step 6：難度調整

難度調整是 mining 的重要技術。本文暫不涉及這個部份，現階段，可以採用「前面有足夠的零」做為難度設定條件，並使用上述的範例進行練習。

調整後的 difficulty，以及 *nonce* 值，都必須儲存在新產生的區塊裡，以做為後續「挖礦」的依據。

## 更多 Mining 觀念

本節所實作的 mining 演算法，僅只是用來測試的粗淺程式（dirty code）。但透過這 30 行的程式碼，還能很快了解「如何開始設計 mining 的演算法」。

還有更多 mining 的觀念，正等待區塊鏈開發者學習：

1. 前面有足夠的零：這意味著 difficutly 會到一個極限，也就是當前面的零夠多時，表示這個數字可能是最小了，再也無法算出更小的數值了，這表示區塊的數量是有限的，總有一天會挖完所有的礦
2. 挖礦機：執行這段挖礦演算法的電腦（正式說法為節點：node），稱為挖礦機
3. Proof-of-Work：這是來自 Bitcoin 的觀念，大略的意思就是，「大家都同意你真的挖到礦了」，此外還有很多工作要做，像是挖礦機如何彼此間更新並同步資料庫等

Proof-of-work 是一個複雜的系統，除了上述提及的功能外，它還涉及 Peer-to-Peer 的網路技術，這個部份，是區塊鏈開發者的真正挑戰「之一」。

## 小結

下一個階段是加入資料庫功能，並且將目前為止的區塊鏈系統實作成伺服器。

## 其它

* [Node.js Fullstack《從零到一的進擊》：初學者寫給初學者的全端軟體教材](https://github.com/jollen/nodejs-fullstack-book)

</script>]]>
      
   </content>
</entry>
<entry>
   <title>Blockchain Developer - 為什麼要挖礦？</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2016/12/blockchain-developer-why-mining.html" />
   <id>tag:www.jollen.org,2016:/blog//2.860</id>
   
   <published>2016-12-05T03:32:56Z</published>
   <updated>2016-12-05T09:34:16Z</updated>
   
   <summary>交易（transaction）確認後的資訊以 Merkle tree 來做紀錄，所以就要有 Block 來儲存這個 Merkle tree... 本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 # 為什麼要 Mining？ 交易（transaction）確認後的資訊以 Merkle tree 來做紀錄，所以就要有 Block 來儲存這個 Merkle tree。這個時候就需要有新的區塊。 在 Bitcoin 的生態中，mining（挖礦）的主要目的就是「產生新的區塊」，當區塊產生時，就會產生另一個「副作用」：新 Bitcoin 被產生出來。 簡單說，產生新的 Bitcoin 並不是挖礦的主要目的，這只是挖礦的副作用。挖礦的主要目的，是生產區塊來確認並紀錄新的交易資訊。本章的目標，在學習挖礦的基本知識，內容以簡單易懂為原則，並不是介紹如何重新實作 Bitcoin 的挖礦技術。但教學內容會以 Bitcoin 做為實例，輔助說明 mining 技術。 ## Difficulty 眾所皆知，Bitcoin 的挖礦難度是非常高的。這個意思是：產生新的...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>交易（transaction）確認後的資訊以 Merkle tree 來做紀錄，所以就要有 Block 來儲存這個 Merkle tree...</p>

<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2016/12/blockchain-developer-why-mining.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="http://i.imgur.com/eoxcQmh.jpg">

# 為什麼要 Mining？

交易（transaction）確認後的資訊以 Merkle tree 來做紀錄，所以就要有 Block 來儲存這個 Merkle tree。這個時候就需要有新的區塊。

在 Bitcoin 的生態中，mining（挖礦）的主要目的就是「產生新的區塊」，當區塊產生時，就會產生另一個「副作用」：新 Bitcoin 被產生出來。

簡單說，產生新的 Bitcoin 並不是挖礦的主要目的，這只是挖礦的副作用。挖礦的主要目的，是生產區塊來確認並紀錄新的交易資訊。本章的目標，在學習挖礦的基本知識，內容以簡單易懂為原則，並不是介紹如何重新實作 Bitcoin 的挖礦技術。但教學內容會以 Bitcoin 做為實例，輔助說明 mining 技術。

## Difficulty

眾所皆知，Bitcoin 的挖礦難度是非常高的。這個意思是：產生新的 Block 是一件非常困難的事情。Bitcoin 將挖礦設計的非常困難，其實是有一個很重要的原因：避免有人任意產生區塊。

要產生新的區塊，就會有所謂的 difficulty（難度），這個 difficulty 的作用是什麼呢？主要目的是：決定新的 hash 值產生條件。

要產生新的區塊前，必須先計算出這個區塊的 Block Hash，區塊的 hash 值如何決定呢？這點後續再談。因為，這裡有一個更重要的問題：如何決定這個 hash 值是否可用？

例如，根據新的交易與其它資訊，運算出一個 double SHA-256 的 hash 值如下：

```
18AC3E7343F016890C510E93F935261169D9E3F565436429830FAF0934F4F8E4
```

新的區塊是否就能直接使用這個 hash 值呢？如果可以，表示新的 hash 值已成功（success）建立，如果不行，表示新的 hash 值產生失敗。系統必須不斷進行運算，「直到成功得到新的 hash 值」。

不如用一個簡單的方法，來「定義什麼是 success」：當產生的 hash 值前面「有足夠的零」時，就是 success。例如，「前面至少要有 2 個零」，上述的 hash 值就是失敗的運算。以下的這個 hash 值，則是 success：

```
0018AC3E7343F016890C510E93F935261169D9E3F565436429830FAF0934F4F8
```

這個條件就是 difficulty 會儲存在最後一個區塊上，所以修改 22.1 節的範例，加入 difficulty 欄位，並且在 Genesis Block 裡，設定最原始的 difficulty 為「前面至少有 2 個零」。

```
function Block(block) {
	this.hash = block.hash || '';
	this.previousHash = block.previousHash || '';
	this.timestamp = block.timestamp || new Date();
	this.merkleRoot = block.merkleRoot || {};
	this.difficulty = block.difficulty || '00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
}
```

以 JavaScript 來實作時，只要以字串比對方式，就可以知道 hash 值是否為 success 了。例如：

```
if ('CD18AC3E7343F016890C510E93F935261169D9E3F565436429830FAF0934F4' <'00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF') {
	// success
} else {
	// failed
}
```

## 越來越難

新的區塊產生後，會「重新調整」這個 difficulty。例如，將 difficulty 調整為「前面至少有 3 個零」，這時，可以將新區塊的 difficulty 欄位設定為：

```
000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
```

Difficulty 的條件設定，由每一個區塊鏈系統的設計者所制定。但是有一個基本原則就是：難度必須越來越高，以上述例子來說，要產生「前面 3 個零」的 hash 值，其難度大於「前面 2 個零」的 hash 值。

## 小結

認識為什麼要 mining 以及什麼是 difficulty 後，就可以開始設計 mining 的演算法了。


## 其它

* [Node.js Fullstack《從零到一的進擊》：初學者寫給初學者的全端軟體教材](https://github.com/jollen/nodejs-fullstack-book)

</script>]]>
      
   </content>
</entry>
<entry>
   <title>Blockchain Developer - 建立 Merkle Tree</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2016/12/blockchain-developer-merkle-tree.html" />
   <id>tag:www.jollen.org,2016:/blog//2.859</id>
   
   <published>2016-12-04T07:42:31Z</published>
   <updated>2016-12-04T13:48:46Z</updated>
   
   <summary>Merkle tree 用來存放交易資訊（transactions），為了要討論更詳細的 Merkle tree 生成過程，假設現在有 2 筆交易正在等候「處理」... 本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 # Blockchain Developer - 建立 Merkle Tree ## Merkle Tree 的生成過程 Merkle tree 用來存放交易資訊（transactions），為了要討論更詳細的 Merkle tree 生成過程，假設現在有 2 筆交易正在等候「處理」。這 2 筆交易資訊，分別以 ```Tx0``` 與 ```Tx1``` 來表示。 ![圖 1 生成 Merkle...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>Merkle tree 用來存放交易資訊（transactions），為了要討論更詳細的 Merkle tree 生成過程，假設現在有 2 筆交易正在等候「處理」...</p>

<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2016/12/blockchain-developer-merkle-tree.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="http://i.imgur.com/eoxcQmh.jpg">

# Blockchain Developer - 建立 Merkle Tree

## Merkle Tree 的生成過程

Merkle tree 用來存放交易資訊（transactions），為了要討論更詳細的 Merkle tree 生成過程，假設現在有 2 筆交易正在等候「處理」。這 2 筆交易資訊，分別以 ```Tx0``` 與 ```Tx1``` 來表示。

![圖 1 生成 Merkle tree](https://raw.githubusercontent.com/jollen/nodejs-fullstack-book/master/images/figure-22_5.jpg)

圖 1 生成 Merkle tree

Merkle tree 節點存放的是 double SHA-256 運算結果。如何將這 2 筆交易資訊，以 Merkle tree 來表示呢？以下是這一顆 Merkle tree 的生成過程。

將 ```Tx0``` 的本文（content）以 double SHA-256 進行雜湊運算，並將結果儲存在 ```HA```，表示方法如下：

```
HA = SHA256( SHA256(Tx0) )
```

同理，再將 ```Tx1``` 進行 double SHA-256 運算，結果儲存於 ```HB```：

```
HB = SAH256( SHA256(Tx1) )
```

SHA-256 的運算結果，是一個 64 bytes 的 HEX（十六進位）字串。在得到 ```HA``` 與 ```HB``` 後，就將這二個字串連接（concat）在一起，成為一個 64*2=128 bytes 的字串，這裡以 ```HA + HB``` 來表示。

再將 ```HA + HB``` 進行 double SHA-256 運算，結果儲存於 ```HAB```：


```
HAB = SAH256( SHA256( HA + HB ) )
```

得到結果 ```HAB``` 就是 ```HA``` 與 ```HB``` 的父節點。這是一個 3 個節點的 binary Merkle tree。

## 更多交易

如果現在有 ```Tx0```、```Tx1```、```Tx2``` 與 ```Tx3``` 共 4 筆交易呢？完整的 double SHA-256 運算過程就是：

```
HA = SHA256( SHA256(Tx0) )
HB = SAH256( SHA256(Tx1) )
HC = SAH256( SHA256(Tx2) )
HD = SAH256( SHA256(Tx3) )

HAB = SAH256( SHA256( HA + HB ) )
HCD = SAH256( SHA256( HC + HD ) )

HABCD = SAH256( SHA256( HAB + HCD ) )
```

最後得到的 binary Merkle tree 就是圖 2。

## 使用 Node.js 打造 Merkle Tree

Node.js 開發者不一定要自行實作 Merkle tree 演算法，網路上能找到開放源碼的實作。在 GitHub 上可以找到 [Merkle](https://github.com/c-geek/merkle) 模組，這是 JavaScript 的 Merkle tree 實作，並且支援 SHA-256 在內的多種 hash algorithm。

### Step 1：安裝 Merkle 模組

先安裝 Merkle 模組：

```
$ npm install merkle --save
```

接著引入 ```merkle``` 模組：

```
var merkle = require('merkle');
```

建立 root node，並指定使用 SHA-256 演算法：

```
var merkleRoot = merkle('sha256');
```

### Step 2：準備交易資訊

宣告幾筆交易資訊，例如：

```
// 建立一筆新的交易紀錄
var tx = ['Created by Jollen'];
```

交易的內容，現階段可任意填寫。例如，如果有 4 筆交易資訊：

```
// 建立 4 筆新的交易紀錄
var tx = ['a', 'b', 'c', 'd'];
```

現在只是練習 Merkle tree 的生成，暫時還沒有定義交易的資料結構，所以填寫任意內容即可。

### Step 3：建立完整 Merkle Tree

呼叫 ```async``` 函數，傳入所有交易資訊來建立 Merkle tree：

```
merkleRoot.async(tx, function(err, tree){
});
```

透過 Callback 函數來取得 Merkle tree。根據 Merkle 官方文件的說明，可以呼叫 ```tree``` 物件的 ```root``` 函數，來取得 Merkle root 的 Hash 值。以下是完整的範例列表：

```
var merkle = require('merkle');
var merkleRoot = merkle('sha256');

// 建立一筆新的交易紀錄
var tx = ['a', 'b', 'c', 'd'];

merkleRoot.async(tx, function(err, tree){
    console.log( tree.root() );
});
```

結出結果：

```
AB4587D9F4AD6990E0BF4A1C5A836C78CCE881C2B7C4287C0A7DA15B47B8CF1F
```

## 更多 Merkle Tree 資訊

如圖 2 所示，Merkle tree 是 binary tree（二元樹），以 4 筆交易量來看，總計會有 6 個節點（nodes），並且「高度」為 3。這個高度稱為 level。

![圖 2 Merkle Tree 的 depth 為 2](https://raw.githubusercontent.com/jollen/nodejs-fullstack-book/master/images/figure-22_6.jpg)

圖 2 Merkle Tree 的 depth 為 2

這是一個 levels 為 3 的 Merkle tree，排除 leaf nodes 後的高度稱為 depth。所以：

* ```HA``` 與 ```HB``` 稱為 leaf nodes
* 這個 Merkle tree 的 depth  為 2
* 這個 Merkle tree 的 level 為 3

延續上述範例，取得該 Merkle tree 的 depth 與 levels：

```
merkleRoot.async(tx, function(err, tree){
    console.log( tree.root() );
    console.log( tree.depth() );
    console.log( tree.levels() );    
});

```

結出結果：

```
AB4587D9F4AD6990E0BF4A1C5A836C78CCE881C2B7C4287C0A7DA15B47B8CF1F
2
3
```

此外，呼叫 ```level``` 函數，可以取得指定 level 的所有節點，例如：


```
merkleRoot.async(tx, function(err, tree){
    console.log( tree.level(1) );
});
```

輸出結果：

```
[ '6A20F2EE7789E6BB7F404CC2DD729FF308B724D904F6A455B74D4851ADE5AECB',
  'A99E82F486656840A790C0EF6024D2C02359DE7674A587562FEB81C8970F24DD' ]
```

如圖 2 所示：

* level 0 是根節點（root）
* level 1 有 2 個節點

如果要顯示所有的節點，要怎麼修改程式碼呢？答案如下：

```
merkleRoot.async(tx, function(err, tree){
    // 印出所有節點
    for (i = 0; i < tree.levels(); i++) {
        console.log( tree.level(i) );
    }
});
```

## 視覺化 Merkle Tree

實際撰寫程式，來觀察 4 筆交易資訊的 Merkle tree：

```
var merkle = require('merkle');
var merkleRoot = merkle('sha256');

// 4 筆交易資訊
var tx = ['a', 'b', 'c', 'd'];

merkleRoot.async(tx, function(err, tree){
    // 印出所有節點
    for (i = 0; i < tree.levels(); i++) {
        console.log( tree.level(i) );
    }
});
```

輸出結果：

```
[ 'AB4587D9F4AD6990E0BF4A1C5A836C78CCE881C2B7C4287C0A7DA15B47B8CF1F' ]
[ '6A20F2EE7789E6BB7F404CC2DD729FF308B724D904F6A455B74D4851ADE5AECB',
  'A99E82F486656840A790C0EF6024D2C02359DE7674A587562FEB81C8970F24DD' ]
[ 'CA978112CA1BBDCAFAC231B39A23DC4DA786EFF8147C4E72B9807785AFEE48BB',
  '3E23E8160039594A33894F6564E1B1348BBD7A0088D42C4ACB73EEAED59C009D',
  '2E7D2C03A9507AE265ECF5B5356885A53393A2029D241394997265A1A25AEFC6',
  '18AC3E7343F016890C510E93F935261169D9E3F565436429830FAF0934F4F8E4' ]
```

為了幫助學習，圖 3 以視覺化的方式，來呈現這個範例的結果。

![圖 3 視覺化 Merkle Tree](https://raw.githubusercontent.com/jollen/nodejs-fullstack-book/master/images/figure-22_7.png)

圖 3 視覺化 Merkle Tree

## 小結

現在，你學會了如何使用 Node.js 來生成 Merkle tree，並且也更進一步了解 Merkle tree 的結構。


## 其它

* [Node.js Fullstack《從零到一的進擊》：初學者寫給初學者的全端軟體教材](https://github.com/jollen/nodejs-fullstack-book)

</script>]]>
      
   </content>
</entry>
<entry>
   <title>Blockchain Developer - 開始建立 Genesis Block</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2016/12/blockchain-developer-genesis-block-2.html" />
   <id>tag:www.jollen.org,2016:/blog//2.858</id>
   
   <published>2016-12-03T08:02:27Z</published>
   <updated>2016-12-03T14:32:49Z</updated>
   
   <summary>使用 Node.js 發展區塊鏈的下一個動作，就是建立 Genesis Block... 本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 # Blockchain Developer - 開始建立 Genesis Block 使用 Node.js 發展區塊鏈的下一個動作，就是建立 Genesis Block。 ## Step 1：定義區塊資料結構 根據 [[Blockchain Developer - 認識 Genesis Block](http://www.jollen.org/blog/2016/12/blockchain-developer-genesis-block.html)] 的說明，區塊的資料結構包含 4 個欄位如下： * *hash*：區塊的 hash ID * *previousHash*：紀錄前一個區塊的 hash...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>使用 Node.js 發展區塊鏈的下一個動作，就是建立 Genesis Block...</p>

<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2016/12/blockchain-developer-genesis-block-2.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="http://i.imgur.com/eoxcQmh.jpg">

# Blockchain Developer - 開始建立 Genesis Block

使用 Node.js 發展區塊鏈的下一個動作，就是建立 Genesis Block。

## Step 1：定義區塊資料結構

根據 [[Blockchain Developer - 認識 Genesis Block](http://www.jollen.org/blog/2016/12/blockchain-developer-genesis-block.html)] 的說明，區塊的資料結構包含 4 個欄位如下：

* *hash*：區塊的 hash ID
* *previousHash*：紀錄前一個區塊的 hash ID
* *timestamp*：區塊建立的時間
* *merkleRoot*：區塊的 merkle tree

以 Node.js 來實作此資料結構，方式是以 *function* 關鍵字來定義 *Block* 類別（Class）：

```
function Block(block) {
	this.hash = block.hash || '';
	this.previousHash = block.previousHash || '';
	this.timestamp = block.timestamp || new Date();
	this.merkleRoot = block.merkleRoot || {};
}
```

## Step 2：生成 Hash ID

每個 Block 都有一個獨一無二（uniquely）的編號，這個編號是使用 SHA256 演算法產生，稱之為 Block Hash（即 Block Hash ID）。

Genesis block 的 hash ID 要如何生成呢？原則上是使用 SHA256 演算法來產生，當然開發者也能自行定義 Block Hash 的生成方式。在這篇教學裡，筆者打算根據 Merkle tree 的演算法來生成 Hash ID。

Merkle tree 同樣是使用 SHA256 演算法來產生 Hash ID，標準的 Merkle tree 會使用二次的 SHA256 來計算出 hash ID，這樣的做法也稱為 double SHA256。本文的 Block Hash 就以 double SHA256 來產生。

Node.js 內建的 ```crypto``` 模組，就提供了 SHA256 演算法函數。先引入 ```crypto``` 模組：

```
var crypto = require('crypto');
```

使用 ```createHmac``` 函數，計算出第 1 個 hash 值，用法如下：

* 第 1 個參數，填寫 ```sha256``` 
* 第 2 個參數，填寫 secret：任意一段句子即可

執行後，```createHmac``` 會建立 ```Hmac``` 的實例化（instance），再呼叫 ```Hmac``` 物件的 ```update``` 函數，並傳入一段本文來進行 sha256 編碼運算。完成後，呼叫 ```digest``` 將結果轉為 *hex* 格式。

完整範例：

```
var secret = 'blockchain developer';

var hash1 = crypto.createHmac('sha256', secret)
                   .update('created by jollen')
                   .digest('hex');
```

得到第 1 個的 hash 值。接著，使用這個 hash 值做為新的 secret，進行第 2 次的 hash 運算：

```
var hash2 = crypto.createHmac('sha256', hash1)
                   .update('powered by flowchain')
                   .digest('hex');

console.log(hash2);
```

輸出結果：

```
dd0e2b79d79be0dfca96b4ad9ac85600097506f06f52bb74f769e02fcc66dec6
```

這就是 genesis block 的 hash ID 了。

## Step 3：定義 Genesis Block 

建立 genesis block 最簡單的方式，就是直接「定義」它。建立一個名為 *config.js* 的檔案，並且直接定義好 genesis block 的欄位資訊：

```
// Filename: config.js
'use strict';                                                                                              

exports.genesis = {
    hash: 'dd0e2b79d79be0dfca96b4ad9ac85600097506f06f52bb74f769e02fcc66dec6',

    prevHash: '0000000000000000000000000000000000000000000000000000000000000000',

    timestamp: new Date(),
    
    merkleRoot: {}
};
```

## Step 4：建立 Genesis Block

終於來到歷史性的一刻了。先引入事先準備好的 genesis block 定義：

```
var config = require('../config.js');
```

接著，再實例化 ```Block```，得到的物件，就是 Genesis Block 了。

```
// Filename: index.js
var genesis = new Block(config.genesis);
```

後續可以將 ```genesis``` 物件，儲存在 NoSQL 資料庫裡。

## 小結

創建出 Genesis Block 後，下一個步驟就是幫它加入一個空的 merkle tree。

## 其它

* [Node.js Fullstack《從零到一的進擊》：初學者寫給初學者的全端軟體教材](https://github.com/jollen/nodejs-fullstack-book)

</script>]]>
      
   </content>
</entry>
<entry>
   <title>Blockchain Developer - 認識 Genesis Block</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2016/12/blockchain-developer-genesis-block.html" />
   <id>tag:www.jollen.org,2016:/blog//2.857</id>
   
   <published>2016-12-02T04:45:31Z</published>
   <updated>2016-12-03T14:04:22Z</updated>
   
   <summary>Merkle tree 是一種 hash tree，用來表示 hash 值的資料結構。Merkle tree 的發明人是 Ralph Merkle，當然這就是這個資料結構的名稱由來... 本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊這裡。 # Genesis Block Merkle tree 是一種 hash tree，用來表示 hash 值的資料結構。Merkle tree 的發明人是 [Ralph Merkle](https://en.wikipedia.org/wiki/Ralph_Merkle)，當然這就是這個資料結構的名稱由來。 Merkle tree 的基本結構是 binary tree（二元樹），每一個 non-leaf 的節點（node），都被標示一個 hash 值。 圖 1：就是一個 binary...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Blockchain" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>Merkle tree 是一種 hash tree，用來表示 hash 值的資料結構。Merkle tree 的發明人是 Ralph Merkle，當然這就是這個資料結構的名稱由來...</p>

<p>本文章採用 Markdown 語法撰寫，若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2016/12/blockchain-developer-genesis-block.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="http://i.imgur.com/eoxcQmh.jpg">


# Genesis Block

Merkle tree 是一種 hash tree，用來表示 hash 值的資料結構。Merkle tree 的發明人是 [Ralph Merkle](https://en.wikipedia.org/wiki/Ralph_Merkle)，當然這就是這個資料結構的名稱由來。

Merkle tree 的基本結構是 binary tree（二元樹），每一個 non-leaf 的節點（node），都被標示一個 hash 值。

圖 1：就是一個 binary Merkle Tree 的結構。其中，*Top hash* 的部份，就是 *Merkle Root*。

![圖 1 Merkle Tree（圖片來源：https://commons.wikimedia.org/wiki/File%3AHash_tree.png，By Davidgothberg at English Wikipedia，遵循 Public Domain 授權）](https://upload.wikimedia.org/wikipedia/commons/6/6d/Hash_tree.png)

圖 1：Merkle Tree（圖片來源：https://commons.wikimedia.org/wiki/File%3AHash_tree.png，By Davidgothberg at English Wikipedia，遵循 Public Domain 授權

學習 Merkle tree 資料結構，可以說是「Blockchain 系統開發者」的第 1 堂課。為什麼這麼說呢？

以圖 2 來看，分散（Distributed）在世界各地的所有 Block 之間，以一個鏈（Chain）的關係串連在一起，這就是 Blockchain（區塊鏈）的概念與名稱由來。

![圖 2 Block 與 Chain](https://raw.githubusercontent.com/jollen/nodejs-fullstack-book/master/images/figure-22_2.jpg)

圖 2：Block 與 Chain

## Block #0

這些分散在世界各地的 Block，都會有一個編號，如圖 3。這個編號就是區塊產生的「順序」。

![圖 3 Block #0](https://raw.githubusercontent.com/jollen/nodejs-fullstack-book/master/images/figure-22_3.jpg)

圖 3：Block #0

這其中，就一定會有編號為 0 的第一個區塊，這個區塊就稱之為 Genesis Block（創世區塊），學習如何建立 Genesis Block 就是 Blockchain 系統開發者的第 2 堂課。

而區塊的產生「方式」，則可以由 Blockchain 的系統開發者來設計。以 Nakamoto Blockchain 來說（Bitcoin 的 Blockchain 系統），區塊的產生過程，就稱為「挖礦」。

## Blockchain 與 Merkle Tree

那 Merkle Tree 與 Blockchain 的關係倒底是什麼呢？將 Blockchain、Genesis block 與 Merkle tree 放在一起討論時，它們的關係就是圖 4。

![圖 4 Blockchain、Genesis block 與 Merkle tree](https://raw.githubusercontent.com/jollen/nodejs-fullstack-book/master/images/figure-22_4.jpg)

圖 4：Blockchain、Genesis block 與 Merkle tree

如果我發展一個叫做 Jollen's Blockchain 系統時，一個粗略的起步應該就是：

* 建立 Genesis block，genesis block 會有自已的一個 hash 值，這個值是經由 hash 演算法產生，因此也叫做 hash ID

* 利用演算法，經過一段困難的演算法運算，產生 Block #1

* Block #1 也會有自已的 hash ID，同時， Block #1 要使用 *PreviousHash* 欄位，串接到前一個 Block，它的前一個 Block 就是 Genesis block（Block #0）

* 同理，產生 Block #2 與更多 Blocks，這些 block 之間都用 *PreviousHash* 欄位串接，這條鏈就是 Block *chain*

到這邊，還是很好奇 Merkle tree 的用途啊？回顧圖 4 發現，每個 Block 裡面都會有 *Merkle Root* 欄位，這個欄位就是一顆 Merkle tree。

區塊倒底能做什麼呢？每一個區塊，都能用來「記帳」，整個 Blockchain 串接起來就是一本完整的帳冊，所以說，Blockchain 也叫做 distributed ledger（分散式帳冊）。

更深入技術來看，區塊裡的 Merkle tree 就是負責記帳的欄位。

## 其它

* [Node.js Fullstack《從零到一的進擊》：初學者寫給初學者的全端軟體教材](https://github.com/jollen/nodejs-fullstack-book)

</script>]]>
      
   </content>
</entry>
<entry>
   <title>使用 Stripe Atlas 設立美國公司的心得與歷程分享</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2016/06/stripe-atlas.html" />
   <id>tag:www.jollen.org,2016:/blog//2.856</id>
   
   <published>2016-06-08T05:34:14Z</published>
   <updated>2016-06-08T10:47:45Z</updated>
   
   <summary>使用 Stripe Atlas 設立美國公司的心得與歷程分享 本文章採用 Markdown 語法撰寫（why?），若無法完整閱讀全文，請點擊這裡。 # 前言 自從 Stripe 發佈 Stripe Atlas 計畫後，我就對這個服務非常有興趣，也因為在美國有發展業務的機會，就利用 Stripe Atlas 試著申請美國公司。以下是整個歷程的分享，希望對想透過 Stripe Atlas 在美國設立公司的朋友有幫助。 ## 第一階段：2016 年 4 月 7 日 Stripe Atlas 今天開始 Private Beta。在收到 Private Beta 邀請函後，開始進行填表申請美國公司。申請還算簡單，一開始要詳讀 Stripe Atlas 提供的二份文件： *...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>使用 Stripe Atlas 設立美國公司的心得與歷程分享</p>

<p>本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2016/02/build-javascript-unikernel-from-scratch-part-1.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="https://images.unsplash.com/photo-1453227588063-bb302b62f50b?ixlib=rb-0.3.5&q=20&fm=jpg&crop=entropy&s=cb544f8f6b9c25ac9f109fdecf760500">



# 前言

自從 Stripe 發佈 Stripe Atlas 計畫後，我就對這個服務非常有興趣，也因為在美國有發展業務的機會，就利用 Stripe Atlas 試著申請美國公司。以下是整個歷程的分享，希望對想透過 Stripe Atlas 在美國設立公司的朋友有幫助。



## 第一階段：2016 年 4 月 7 日

Stripe Atlas 今天開始 Private Beta。在收到 Private Beta 邀請函後，開始進行填表申請美國公司。申請還算簡單，一開始要詳讀 Stripe Atlas 提供的二份文件：

* https://stripe.com/atlas/resources/pwc-tax-guide.pdf
* https://stripe.com/atlas/resources/orrick-legal-guide.pdf

這二份文件相當值得一看，第一份是租稅法規的說明，第二份是公司架構的建議。二份的內容都非常詳細到位，例如：公司的 shares 數量不同，產生的稅率也會不同。

Stripe Atlas 還提到，申請公司本身並不是重點，而是創業者自已要思考清楚，為什麼需要美國公司？打算拿它來做什麼？以及打算建立什麼架構的美國公司：要建立全新的美國公司、或是國際公司的分支。

要透過 Strip Atlas 申請美國公司，只要準備 500 字以上的公司產品說明，以及 500 字以上的公司介紹，還有個人護照描掃檔即可。申請過程有什麼疑問，還可以預約專人的電話（Skype）咨詢。


## 第二階段：2016 年 4 月 11 日更新

上週送出申請後，今天進入開戶階段（好驚人的效率）。線上填寫申請表時，只需要 500 字的產品跟 500 字的公司介紹；今天收到 Stripe 的通知，他們說，銀行要求，希望開戶公司，能有 live product 以及 fully functional website。所以透過電子郵件，「補件」附上這二份資訊。

因此，未來想使用 Stripe Atlas 在美國開公司的話，可能要先把產品原型跟網站做好，才能加速審核進度。不過 Stripe 在郵件裡也提到，如果沒有產品或網站，他們也是可以試著協助的。


## 第三階段：2016 年 4 月 19 日更新

Stripe Atlas 透過 DocuSign 送來一份合約書，這份是公司設立與銀行開戶的合約，內容非常「詳細」。一般個人要看懂會有難度，最好找個熟悉美國稅法的律師協助。Stripe Atlas 在郵件再次提到：

> If you have your own legal counsel or tax advisors, we recommend asking them to review these documents before signing. We also suggest reading through the guides prepared by Orrick and PwC on common legal and tax considerations for Atlas users:

建議在簽名前，務必找法律與稅法專家，檢視這份合約內容。並且再次閱讀 Stripe 建議的二份文件。


## 第四階段：2016 年 5 月 24 日更新


花了一個月的時間「再次」閱讀相關文件，並且咨詢熟悉美國稅法的律師，終於完成合約內容的檢視。今天正式簽名回傳，幾個小時後就收到回覆：

> We are writing to let you know that your entity and bank account documents have now been signed by all company representatives, and we have submitted them on your behalf. 

Stripe Altas 的整體服務流程非常完善，而且效率也相當高。


## 第五階段：2016 年 5 月 26 日更新


Stripe Altas 再次通知，已經送出我的申請文件，一星期內會有結果。然後，非常意外地，收到一份禮物：AWS Activate Portfolio Package。

AWS Activate Portfolio Package 內含 $15,000 額度的 AWS credits、一堂價值 $600 的教育訓練課程、價值 $5,000 的 AWS Business Support，以及 1 對 1 的 virtual office hours。意外獲贈一送大禮，真是太高興了！


## 第六階段：2016 年 6 月 1 日更新


終於收到郵件：「Devify, Inc. - Your SVB Bank Account is OPENED」。順利完成公司設立與銀行開戶，新公司正式開張。同時，又獲得一份小禮物：前 2 年免收帳戶保管費，這真是好消息。



## 結案：2016 年 6 月 7 日


今天終於完成最後步驟了，將銀行帳戶與 Stripe 綁定。從填表，到美國公司設立與銀行開戶，總計花費 2 個月的期間，不過，大部份的時間，都花在檢視合約，以及研究美國稅法。整體 Stripe Atlas 的服務非常流暢，強力推薦給想在美國設立公司的創業者。

最後是二個重要心得：

1. 在美國設立公司的重點，並不是「申請流程」，所以你不需要幫你跑流程的代理人，而是能告訴你「如何建立國際營運架構」的專家。因為這樣，你才能知道「自已為何要成立美國或境外公司」，以及「打算建立什麼架構的美國公司」

2. 如果一覺醒來突然有創業的衝動，這天早上最重要的事情，就是去找到一位值得信任，又非常熟悉美國稅法的律師專家；這非常重要，好的律師能幫助你與 Stripe Atlas 團隊，加速整個流程。因為，你將會花費很長的時間，在閱讀相關文件，以及檢視合約；這些工作必須由你的律師協助


結論是，如果你是一位想在美國開公司的創業者，Stripe Atlas 是強力推薦的服務。






</script>]]>
      
   </content>
</entry>
<entry>
   <title>強化串連智付寶（Pay2go）交易的安全性</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2016/03/security-pay2go.html" />
   <id>tag:www.jollen.org,2016:/blog//2.855</id>
   
   <published>2016-03-31T06:14:40Z</published>
   <updated>2016-03-31T11:36:02Z</updated>
   
   <summary>這幾天因為專案需要，開始將線上支付的金流平臺，從 Paypal 轉移到 Pay2go... 本文章採用 Markdown 語法撰寫（why?），若無法完整閱讀全文，請點擊這裡。 ## 前言 這幾天因為專案需要，開始將線上支付的金流平臺，從 Paypal 轉移到 Pay2go。要串接 Pay2go 金流平台是一個很簡單的工作，API 文件也很完整。在實作前端與後端的過程中，發現有一些應該要注意的事項，紀錄如下。 ## 關於 MPG 參數 由於 Pay2go 是以 Form Post（HTML5 的 ``````）的方式提交付款請求，所以必須使用 `````` 來紀錄交易參數，如圖一。 ![2016-03-31 11 57 06](https://cloud.githubusercontent.com/assets/1126021/14165431/810d558e-f73b-11e5-8f03-3bb49591baba.png) 圖一：MPG API 一個稱為 ```CheckValue``` 的參數，編碼規則如下： ```js var...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Node.js &amp; RESTful" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>這幾天因為專案需要，開始將線上支付的金流平臺，從 Paypal 轉移到 Pay2go...</p>

<p>本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2016/02/build-javascript-unikernel-from-scratch-part-1.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="https://images.unsplash.com/photo-1453227588063-bb302b62f50b?ixlib=rb-0.3.5&q=20&fm=jpg&crop=entropy&s=cb544f8f6b9c25ac9f109fdecf760500">

## 前言

這幾天因為專案需要，開始將線上支付的金流平臺，從 Paypal 轉移到 Pay2go。要串接 Pay2go 金流平台是一個很簡單的工作，API 文件也很完整。在實作前端與後端的過程中，發現有一些應該要注意的事項，紀錄如下。

## 關於 MPG 參數

由於 Pay2go 是以 Form Post（HTML5 的 ```<form></form>```）的方式提交付款請求，所以必須使用 ```<input>``` 來紀錄交易參數，如圖一。

![2016-03-31 11 57 06](https://cloud.githubusercontent.com/assets/1126021/14165431/810d558e-f73b-11e5-8f03-3bb49591baba.png)

圖一：MPG API

一個稱為 ```CheckValue``` 的參數，編碼規則如下：

```js
var data = 'HashKey=' + hashKey +
          '&Amt=' + amt +
          '&MerchantID=' + merchantID +
          '&MerchantOrderNo=' + merchantOrderNo +
          '&TimeStamp=' + timeStamp +
          '&Version=1.2' +
          '&HashIV=' + hashIV;
// 使用 SHA256 壓碼後轉大寫
var checkValue = sha256(data).toLocaleUpperCase();
```

將幾個主要的交易參數、 ```hashKey``` 與 ```hashIV``` 連接成 Query String 形式後，再用 SHA256 編碼。```CheckCode``` 看起來是為了檢查交易參數的正確性。不過：

* 將 ```CheckCode``` 放在 Form 的欄位裡，有安全上的疑慮
* 最好能改用 REST API 的做法，由 Backend 直接向 Pay2go 的 API 送出一個自定的 HTTP headers，來傳送 ```CheckCode```，但 Pay2go 目前不支援這樣的做法

另外，有些前端網頁，直接將 ```hashKey``` 與 ```hashIV``` 也紀錄在 Form 裡面，也是非常危險的做法。如圖二（為避免不必要的問題，僅做截圖，恕不註明出處）。

![2016-03-31 12 04 17](https://cloud.githubusercontent.com/assets/1126021/14165535/95ff93a2-f73c-11e5-9a16-1c86046a814d.png)

圖二：曝露在外的 ```hashKey``` 與 ```hashIV```

類似的安全議題，可以在研發或工程階段，就進行嚴格檢視。不過，把交易機制、平台架構與 SDK 做到非常嚴謹，應該是金流平臺的基本責任。

一個安全且嚴謹的交易平臺，也要針對各種「使用不當」的案例，而造成的安全疑慮，進行完整測試。

## 關於 NotifyURL

NotifyURL 是 Pay2go 用來通知店家後台交易結果的 URL。Pay2go 在訂單完成交易後，會以 HTTP POST 方法，呼叫 NotifyURL。店家的後台則是要實作這個 API，並進行自已的訂單處理流程。

以下是一個 Pay2go 模擬交易，所回送的 POST 資料：

```
{ JSONData: '{"Status":"SUCCESS","Message":"\\u4ed8\\u6b3e\\u6210\\u529f","Result":"{\\"MerchantID\\":\\"31745140\\",\\"Amt\\":992,\\"TradeNo\\":\\"16033018180593725\\",\\"MerchantOrderNo\\":\\"14593335802368129\\",\\"RespondType\\":\\"JSON\\",\\"CheckCode\\":\\"4E2B2FB0A54CCFECE9616742FE9025EFBBE8FABBC6562268C11D39DFD6E03E9C\\",\\"IP\\":\\"36.231.213.27\\",\\"EscrowBank\\":\\"KGI\\",\\"PaymentType\\":\\"WEBATM\\",\\"PayTime\\":\\"2016-03-30 18:18:05\\",\\"PayerAccount5Code\\":\\"-\\",\\"PayBankCode\\":\\"-\\"}"}' }
```

這份資料會以 JSON 格式，經由 POST 方法，由 Pay2go 後台傳送到店家的 NotifyURL。將這筆資料的 ```JSONData``` 轉換為 JSON 物件：

```js
var jsonData = JSON.parse(postData.JSONData);  // postData 為上述回傳資料
```

詳細的交易狀態，則是紀錄在 ```jsonData``` 的 ```Result``` 裡，再將這個欄位轉換為 JSON 物件：

```js
var result = JSON.parse(jsonData.Result);
```

終於得到以下內容（疑問：為什麼不直接回傳一個 Stringify 過的 JSON 物件就好？）：

```
{ MerchantID: '31745140',
  Amt: 992,
  TradeNo: '16033018180593725',
  MerchantOrderNo: '14593335802368129',
  RespondType: 'JSON',
  CheckCode: '4E2B2FB0A54CCFECE9616742FE9025EFBBE8FABBC6562268C11D39DFD6E03E9C',
  IP: '36.231.213.27',
  EscrowBank: 'KGI',
  PaymentType: 'WEBATM',
  PayTime: '2016-03-30 18:18:05',
  PayerAccount5Code: '-',
  PayBankCode: '-' }
```

這個回傳結果也是頗耐人尋味：

* ```CheckCode``` 放在這裡面，不但有安全上的疑慮，必要性也值得探討
* ```CheckCode``` 的目的，如果是為了 Pay2go 與店家，自行驗證交易資料使用（檢查交易參數是否被竄改），或許可以在各自的後台運算即可，是否以明文傳送，有討論空間

回傳的結果，在交易使用的 Form 裡面幾乎都可以取得。因此向店家發出一個「模擬交易成功」的請求並不是太困難。

## 強化方案

消極作為：

1. 不要在 Form 裡面傳送 ```NotifyURL``` 參數，避免用心人士，向店家發出「模擬交易成功」的通知。可以在 Pay2go 的管理介面設定 ```NotifyURL```，減少 ```NotifyURL``` 曝露的機會。

2. 不要在 Form 裡面放入 ```hashKey``` 與 ```hashIV```。

3. 店家的 ```NotifyURL``` 實作，可以考慮移除「自動出貨」、「自動付款銷核」等流程，取消部份自動化，改採手工銷核。

4. 店家的 ```NotifyURL``` 實作，可以考慮加入更嚴謹的檢查，例如查看 HTTP 的 ```Origin:```，或是 ```Referer:``` 等檔頭，或是使用 DNS 反查詢等機制。不過因為 HTTP headers 也是很容易變造，所以根本之道還是 Pay2go 的後台能強化相關機制。

最後，展示如何用 ```curl``` 進行「模擬交易成功」。首先，在店家的 Form 裡面取得 ```MerchantID```、```CheckValue```、```MerchantOrderNo``` 與 ```Amt``` 四個參數。

接著，將以上參數帶入以下的內容模板：

```
{
"JSONData": "{\"Status\":\"SUCCESS\",\"Message\":\"\\u4ed8\\u6b3e\\u6210\\u529f\",\"Result\":\"{\\\"MerchantID\\\":\\\"31745140\\\",\\\"Amt\\\":992,\\\"TradeNo\\\":\\\"16033018180593725\\\",\\\"MerchantOrderNo\\\":\\\"14593258232469307\\\",\\\"RespondType\\\":\\\"JSON\\\",\\\"CheckCode\\\":\\\"4E2B2FB0A54CCFECE9616742FE9025EFBBE8FABBC6562268C11D39DFD6E03E9C\\\",\\\"IP\\\":\\\"36.231.213.27\\\",\\\"EscrowBank\\\":\\\"KGI\\\",\\\"PaymentType\\\":\\\"WEBATM\\\",\\\"PayTime\\\":\\\"2016-03-30 18:18:05\\\",\\\"PayerAccount5Code\\\":\\\"-\\\",\\\"PayBankCode\\\":\\\"-\\\"}\"}"
}
```

將上述內容儲存為 test.json。最後利用 ```curl``` 向店家的 ```NotifyURL``` 發出 POST 請求：

```
curl -X POST -d @test.json --header "Content-Type: application/json" http://localhost:80/pay2go/notify
```

從這個「模擬交易」的測試可以知道，把自已的 ```NotifyURL``` 藏好是一個很重要的工作。提供 REST API 來替代 Form Post 方式，可以消除主要的安全疑慮。

## Reports and Discussion

* Bug reports of this article: [https://github.com/jollen/blog/issues/18](https://github.com/jollen/blog/issues/18)

</script>]]>
      
   </content>
</entry>
<entry>
   <title>學習 Unikernel 與 Runtime.js (Part 2)－Build Runtime.js VM Image</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2016/02/build-javascript-unikernel-from-scratch-part-2.html" />
   <id>tag:www.jollen.org,2016:/blog//2.854</id>
   
   <published>2016-02-16T04:32:09Z</published>
   <updated>2016-02-16T13:09:10Z</updated>
   
   <summary>Runtime.js 可以讓我們用 Node.js 與 JavaScript 來開發 Unikernel，熟悉 Node.js 是第一個基本功課，Runtime.js 的 OS kernel 採用 V8 JavaScript Engine，目前支援 KVM，研究 Runtime.js 的 kernel 實作，是第二個基本功課... 本文章採用 Markdown 語法撰寫（why?），若無法完整閱讀全文，請點擊這裡。 ## 前言 以下步驟參考自 [Runtime.js 官網](http://runtimejs.org/) 的說明，目標是初始化一個新的 Runtime.js 專案。請參考 [Getting Started](http://runtimejs.org/getting-started/) 上的環境安裝說明。 要使用 Runtime.js 必須安裝 [Node.js](https://nodejs.org) 執行環境，以下步驟以...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="IoT &amp; WoT" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="unikernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>Runtime.js 可以讓我們用 Node.js 與 JavaScript 來開發 Unikernel，熟悉 Node.js 是第一個基本功課，Runtime.js 的 OS kernel 採用 V8 JavaScript Engine，目前支援 KVM，研究 Runtime.js 的 kernel 實作，是第二個基本功課...</p>

<p>本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2016/02/build-javascript-unikernel-from-scratch-part-1.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="https://images.unsplash.com/photo-1447069387593-a5de0862481e?ixlib=rb-0.3.5&q=10&fm=jpg&crop=entropy&s=0dab06e522cf4cd96ee75e9801e73c8a">

## 前言

以下步驟參考自 [Runtime.js 官網](http://runtimejs.org/) 的說明，目標是初始化一個新的 Runtime.js 專案。請參考 [Getting Started](http://runtimejs.org/getting-started/) 上的環境安裝說明。

要使用 Runtime.js 必須安裝 [Node.js](https://nodejs.org) 執行環境，以下步驟以 Mac 環境為主，Node.js 的版本為 v4.2.6。

## 建立 Runtime.js 專案

Runtime.js 仍是一個發展中的開源計畫，目前的發展狀態如下：

* Hypervisor 部份，目前僅支援 [KVM](http://www.linux-kvm.org/page/Main_Page)
* API 部份，目前 Runtime.js 提供的 JavaScript library 非常有限，不過根據應用程式需求，可以自行安裝 Node.js 模組來使用
* 目前提供 *runtimeify* 工具來製作 Unikernel image，這是 *browserify* 的前端（wrapper）命令列工具

即便 Runtime.js 還是處於這麼早期的階段，但實作簡單的 IoT cloud VM image 問題並不大。以下是使用 runtime.js 製作 unikernel image 的準備工作說明。

### 1. 安裝 QEMU VM

安裝 QEMU VM 做為 Runtime.js 的執行環境。以 Mac 為例，使用 [homebrew](http://brew.sh/) 安裝 qemu：

```
$ brew install qemu   
```

Runtime.js 目前僅支援 KVM。

### 2. 建立新的 Node.js 專案

使用 *npm* 建立新的 Node.js 專案：

```
$ mkdir simple-iot-runtime
$ cd simple-iot-runtime
$ npm init
```

這次的學習計畫，將不使用 [Express](http://expressjs.com/)。如果要實作 REST API 的話，後續就要實作一個小型的 URL router。

### 3. 安裝 Runtime.js 模組

安裝 Runtime.js 的 core library:

```
$ npm install runtimejs --save

```

### 4. 安裝 Runtime.js CLI 與 Runtimeify

Runtime.js 提供二個命令列工具（CLI）：

* *runtime-cli* 是 *qemu* 的 wrapper，用來啟動 qemu，方便測試 runtime.js VM image
* *runtimeify* 是 *browserify* 的 wrapper，用來將 Node.js 的相依模組打包（bundle）成一個檔案 

```
$ sudo npm install runtime-cli -g
$ sudo npm install runtimeify -g
```

*Browserify* 原本是用給 frontend 開發使用的工具，讓 frontend 的 JavaScript 程式碼，也能以 *require()* 的風格引入相依模組。現在被應用於 Runtime.js 專案中。

### 5. 製作 Unikernel Images

撰寫應用程式 *index.js*，目前內容僅只是簡單的 *console.log()*，可參考 [jollen/simple-iot-runtime/index.js](https://github.com/jollen/simple-iot-runtime/blob/db8eafa74d9340840a62ba22ca4194f294d0a9a1/index.js)。

使用 *runtimeify* 將主程式 *index.js* 打包（bundle）成 *initrd* 檔案：

```
$ runtimeify index.js -o initrd
```

### 6. 啟動 Unikernel

使用 *runtime-cli* 啟動製作出來的 *initrd*：

```
$ runtime start 
```

![2016-02-15 6 58 35](https://cloud.githubusercontent.com/assets/1126021/13046853/2cf1d5da-d416-11e5-9cc9-18b0a0f53f1e.png)


## 小結

上述步驟得到的 *initrd* 就是一個 unikernel image。*runtime-cli* 是 *qemu* 的 wrapper，測試方式是使用 *runtime-cli* 啟動 qemu，並載入 *initrd* 檔案。*initrd* 是 runtime.js 預設的 unikernel 檔案。

雖然 unikernel 的檔名是 *initrd*，但這與 GNU/Linux 上的 initrd（init process）是完全不同的實作。Runtime.js 所製作的 *initrd*，其實就是 *browserify* 所編譯出來的 JavaScript 應用程式。

這個部份並沒有難度，只是操作層面的練習，熟悉指令就可以很容易上手。從這個練習也可以知道：

* Runtime.js 可以讓我們用 Node.js 與 JavaScript 來開發 Unikernel，熟悉 Node.js 是第一個基本功課
* Runtime.js 的 OS kernel 採用 V8 JavaScript Engine，目前支援 KVM，研究 Runtime.js 的 kernel 實作，是第二個基本功課
* Runtime.js 的 OS kernel 架構與 Exokernel 相似，所以研究 Exokernel 與 Runtime.js kernel 的架構，是第三個功課

## 延伸閱讀

* 2016-02-15: [學習 Unikernel 與 Runtime.js (Part 1)](http://www.jollen.org/blog/2016/02/build-javascript-unikernel-from-scratch-part-1.html)
* 2016-02-16: [學習 Unikernel 與 Runtime.js (Part 2)－Build Runtime.js VM Image](http://www.jollen.org/blog/2016/02/build-javascript-unikernel-from-scratch-part-2.html)

## Reports and Discussion

* Bug reports of this article: [https://github.com/jollen/blog/issues/13](https://github.com/jollen/blog/issues/13)
* 練習 Runtime.js 的專案, [https://github.com/jollen/simple-iot-runtime](https://github.com/jollen/simple-iot-runtime)
* 討論社團, [https://www.facebook.com/groups/wotcity/](https://www.facebook.com/groups/wotcity/)

</script>]]>
      
   </content>
</entry>
<entry>
   <title>學習 Unikernel 與 Runtime.js (Part 1) </title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2016/02/build-javascript-unikernel-from-scratch-part-1.html" />
   <id>tag:www.jollen.org,2016:/blog//2.853</id>
   
   <published>2016-02-15T05:01:37Z</published>
   <updated>2016-02-16T13:08:27Z</updated>
   
   <summary>Unikernel 是一個很有趣的概念。不久前 Docker 收購 Unikernel Systems[1] 是很多人對它的第一印象，台灣的新聞媒體將 Unikernel 翻譯為「無核化」或「去核化」... 本文章採用 Markdown 語法撰寫（why?），若無法完整閱讀全文，請點擊這裡。 ## 前言 Unikernel 是一個很有趣的概念。不久前 Docker 收購 Unikernel Systems[1] 是很多人對它的第一印象，台灣的新聞媒體將 Unikernel 翻譯為「無核化」或「去核化」；不過，Unikernel 並「不是」要消滅作業系統核心，當然也不是要去除作業系統核心；相反地，作業系統核心技術，將更顯重要。 ## Library OS 相較傳統的作業系統核心（conventional OS），Unikernel 的作業系統核心是以「Library」的形式實作 。技術上來說，Unikernel 可以說是一個「Library OS」的概念。 Unikernel 的做法（implementation）是將應用程式（applications）、相關模組（modules）與 library OS 打包（construct）成一個 image 檔。這樣做的目的，是希望將目標系統（target...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="IoT &amp; WoT" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="unikernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="2" label="simple-iot-runtime" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>Unikernel 是一個很有趣的概念。不久前 Docker 收購 Unikernel Systems[1] 是很多人對它的第一印象，台灣的新聞媒體將 Unikernel 翻譯為「無核化」或「去核化」...</p>

<p>本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2016/02/build-javascript-unikernel-from-scratch-part-1.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="https://images.unsplash.com/photo-1447069387593-a5de0862481e?ixlib=rb-0.3.5&q=10&fm=jpg&crop=entropy&s=0dab06e522cf4cd96ee75e9801e73c8a">

## 前言

Unikernel 是一個很有趣的概念。不久前 Docker 收購 Unikernel Systems[1] 是很多人對它的第一印象，台灣的新聞媒體將 Unikernel 翻譯為「無核化」或「去核化」；不過，Unikernel 並「不是」要消滅作業系統核心，當然也不是要去除作業系統核心；相反地，作業系統核心技術，將更顯重要。

## Library OS

相較傳統的作業系統核心（conventional OS），Unikernel 的作業系統核心是以「Library」的形式實作 。技術上來說，Unikernel 可以說是一個「Library OS」的概念。

Unikernel 的做法（implementation）是將應用程式（applications）、相關模組（modules）與 library OS 打包（construct）成一個 image 檔。這樣做的目的，是希望將目標系統（target image）儘量簡化；簡化的目的，是縮小 images 的大小（image size）。

根據維基百科上的解釋[2]：

```
These libraries are then compiled with the application and configuration code to build sealed, fixed-purpose images (unikernels) which run directly on a hypervisor or hardware without an intervening OS such as Linux or Windows.
```

簡單來說，打包出來的 images 檔就稱為「Unikernel」。這個打包的過程，會將 library OS 編譯到應用程式裡，因此，製作 unikernel image 也需要配套工具。

Unikernel 並不是要去除作業系統。所謂的「無核化」的「核」，更精準的解釋應該是去掉 conventional OS 的「核（kernel）」，改採 library OS 的「核」。

專研作業系統與編譯器的工程師，不但沒有身價眨值的問題，還可能會倍數增值呢。為什麼學習作業系統又更重要了呢？因為 Unikernel image 是一種特定用途的 image file，這種 image file 也稱為 immutable VM image。

Immutable image 裡面的 library OS 讓 unikernel image 能直接（directly）在虛擬機上（hypervisor）運行，而不需要透過像是 Linux 或 Windows 的 conventional OS[2]。實作這個 library OS 需要對作業系統、微處理器、虛擬機、編譯器與 software stacks 有綜合的知識。

Unikernel 是一個 image file，也是一種 immutable image。它的用途單一不變（immutable），Unikernel 的「Uni」正能表達它的理念。Unikernel 自然有許多不同的實作；針對不同的應用程式（applications）甚致是不同的雲端佈署架構，也需要更多單一的 library OS。

受到 [jserv](https://github.com/jserv) 一直在自幹編譯器[3]的激勵，新的一年（2016 猴年）就幫自已定了一道作業：期許在新的一年，也可以自已做一個 Unikernel。不過，因為 Unikernel from scratch 的目標有點遠大，所以：

* 第一階段使用 runtime.js，學習 [Build JavaScript unikernel from scratch](https://github.com/jollen/simple-iot-runtime)
* 第二階段研究 runtime.js，可以的話也能幫忙改善 runtime.js 的 OS kernel 實作

因為，近幾年一直是 JavaScript 的愛好者，所以找了 runtime.js 做為研究目標。

## Runtime.js

Runtime.js 是 Unikernel 的一個實作。Runtime.js 提供一個稱為 *runtimeify* 的編譯器，可以將 JavaScript 應用程式，打包為 ramdisk image，並透過 *initrd* 啟動。這是第一階段的學習重點，關於這個部份的學習紀錄，都會發佈在 [jollen/simple-iot-runtime](https://github.com/jollen/simple-iot-runtime)

沒想到 Embedded Linux 也能有這樣的面貌，這是一種有點熟悉又有些陌生的奇妙感覺。*initrd* 與 JavaScript 放在一起使用，又是一個奇妙的感覺。

隨著 Node.js 的發展，以及 frontend 模組化（JavaScript modules）技術的進步，出現了 Browserify 技術，Browserify 今天更是運用在 Unikernel 概念裡，果真是 JavaScript 無極限。

Runtime.js 是一個開源的 library OS 實作，裡面包含二個 component [4]：

* Runtime.js 的 OS kernel
* Runtime.js 程式庫本身

Runtime.js 的 OS kernel 引入了  V8 JavaScript engine；整體來看，Runtime.js 提供了一個優雅的 JavaScript Unikernel 技術方案。

## 相關資源

* [1] Unikernel Systems Joins Docker, https://blog.docker.com/2016/01/unikernel/
* [2] Unikernel, https://en.wikipedia.org/wiki/Unikernel
* [3] 從無到有開發 C 編譯器, https://goo.gl/aqBw9R
* [4] Runtime.js, https://github.com/runtimejs/runtime
* [5] https://github.com/jollen/simple-iot-runtime

## 延伸閱讀

* 2016-02-15: [學習 Unikernel 與 Runtime.js (Part 1)](http://www.jollen.org/blog/2016/02/build-javascript-unikernel-from-scratch-part-1.html)
* 2016-02-16: [學習 Unikernel 與 Runtime.js (Part 2)－Build Runtime.js VM Image](http://www.jollen.org/blog/2016/02/build-javascript-unikernel-from-scratch-part-2.html)

## Reports and Discussion

* Bug reports of this article: [https://github.com/jollen/blog/issues/12](https://github.com/jollen/blog/issues/12)
* 練習 Runtime.js 的專案, [https://github.com/jollen/simple-iot-runtime](https://github.com/jollen/simple-iot-runtime)
* 討論社團, [https://www.facebook.com/groups/wotcity/](https://www.facebook.com/groups/wotcity/)

</script>]]>
      
   </content>
</entry>
<entry>
   <title>如何自行架設 Parse API Server</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2016/02/how-to-setup-parse-api-server.html" />
   <id>tag:www.jollen.org,2016:/blog//2.852</id>
   
   <published>2016-02-04T14:14:05Z</published>
   <updated>2016-02-04T20:25:57Z</updated>
   
   <summary>Facebook 在 2016 年 1 月 28 日（台北時間 1 月 28 日）宣佈，將關閉 Parse.com 平台服務，但也同時釋出 Prase Platform 的 API Server 原始碼。本文介紹如何自行架設 Parse Server。 本文章採用 Markdown 語法撰寫（why?），若無法完整閱讀全文，請點擊這裡。 ## 前言 WoT.City 將在 2 月 4 日晩間 08:00PM ，舉辦 Parse.com API 伺服器的架設教學與討論交流。在家裡上網，跟著大家在 IRC 上一起架設...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>Facebook 在 2016 年 1 月 28 日（台北時間 1 月 28 日）宣佈，將關閉 Parse.com 平台服務，但也同時釋出 Prase Platform 的 API Server 原始碼。本文介紹如何自行架設 Parse Server。</p>

<p>本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2016/02/how-to-setup-parse-api-server.html">這裡</a>。</p>
<script id="markdown" type="text/plain" data-header-image="https://images.unsplash.com/photo-1447069387593-a5de0862481e?ixlib=rb-0.3.5&q=10&fm=jpg&crop=entropy&s=0dab06e522cf4cd96ee75e9801e73c8a">

## 前言

WoT.City 將在 2 月 4 日晩間 08:00PM ，舉辦 Parse.com API 伺服器的架設教學與討論交流。在家裡上網，跟著大家在 IRC 上一起架設 Parse 伺服器，共同迎接 IoT 個人架構時代的開始。

[parse-server](parse-server) 是一個相容於 Express 的 URL Router 套件，這表示：

* 以 npm 模組方式引入使用，不需要直接 fork 此專案
* 可以建立新的 Express application 專案來使用
* 或是，將 parse-server 掛載（mount）到現有的 Express application 專案上使用

以下從建立新的 Express application 專案開始，介紹 parse-server URL router 套件的使用方法。

如果不想自行使用 Express Generator 產生專案的話，請參考 [nodejs-express](https://github.com/jollen/nodejs-express) 並直接由 **Step 4** 開始。

本文目標：

* 前置作業
* 建立 Node.js 與 Express 專案
* Create the first **ParseServer** instance and **Cloud Code**
* Use **restAPIKey**
* 測試 REST API

## 前置作業

環境安裝：

* 安裝 Node.js 4.1 以上版本（建議 v4.2.x TLS）
* 安裝 MongoDB Server，或直接到 [MongoLab](https://mongolab.com/) 申請免費的 MongoDB 資料庫服務即可

MongoDB 的新手建議可先申請 MongoLab 服務。MongoLab 目錄提供 500MB 的免費資料庫服務（如圖一）。

![2016-02-04 12 27 02](https://cloud.githubusercontent.com/assets/1126021/12805879/318eb416-cb3b-11e5-9947-252815dcbb50.png)
圖一：申請 MongoLab 服務

## Step 1: 安裝 Express Generator

```
$ sudo npm install express-generator -g
```

## Step 2: 建立新的 Express 專案

```
$ express my-parse-app

   create : my-parse-app
   create : my-parse-app/package.json
   create : my-parse-app/app.js
   create : my-parse-app/public
   create : my-parse-app/public/javascripts
   create : my-parse-app/public/images
   create : my-parse-app/public/stylesheets
   create : my-parse-app/public/stylesheets/style.css
   create : my-parse-app/routes
   create : my-parse-app/routes/index.js
   create : my-parse-app/routes/users.js
   create : my-parse-app/views
   create : my-parse-app/views/index.jade
   create : my-parse-app/views/layout.jade
   create : my-parse-app/views/error.jade
   create : my-parse-app/bin
   create : my-parse-app/bin/www

   install dependencies:
     $ cd my-parse-app && npm install

   run the app:
     $ DEBUG=my-parse-app:* npm start
```

進入專案目錄，並安裝 npm 模組：

```
$ cd my-parse-app/
$ npm install
```

目前的專案內容：

```
$ ls -l
total 16
-rw-r--r--  1 apple  staff  1442  2  3 14:22 app.js
drwxr-xr-x  3 apple  staff   102  2  3 14:22 bin
drwxr-xr-x  3 apple  staff   102  2  3 14:23 node_modules
-rw-r--r--  1 apple  staff   362  2  3 14:23 package.json
drwxr-xr-x  5 apple  staff   170  2  3 14:22 public
drwxr-xr-x  4 apple  staff   136  2  3 14:22 routes
drwxr-xr-x  5 apple  staff   170  2  3 14:22 views
```

## Step 3: 安裝 parse-server  模組

```
$ npm i parse-server --save
```

## Step 4: 修改 app.js 主程式

開啟 **app.js** 主程式，分別加入以下幾段程式碼。

### 4.1. 引入 *parse-server* 模組：

```
var ParseServer = require('parse-server').ParseServer;
``` 

### 4.2. 建立 *ParseServer* 的 instance

修改 ```app.js```，加入：

```
// Specify the connection string for your mongodb database
// and the location to your Parse cloud code
var api = new ParseServer({
  databaseURI: 'mongodb://localhost:27017/dev',
  cloud: '/home/myApp/cloud/main.js', // Provide an absolute path
  appId: 'myAppId',
  masterKey: 'mySecretMasterKey',
  fileKey: 'optionalFileKey'
});
```

以上有幾個選項要修改：

* ```databaseURI```：MongoDB 的 URI
* ```cloud```：Cloud Code 主程式
* ```appId```：Application ID

### 4.3 修改 ```databaseURI```

如果是申請 MongoLab 的服務，請填入 MongoLab 提供的 URI 填入（如圖二）。```<dbuser>``` 與 ```<dbpassword>``` 填入自行建立的 database user。

![2016-02-04 12 35 16](https://cloud.githubusercontent.com/assets/1126021/12805923/c583ccd8-cb3b-11e5-9972-3873b96ea1c8.png)
圖二：申請的 MongoDB URI

### 4.4 加入 Cloud Code

這個是 Parse Cloud Code 的程式碼路徑，請建立想存放 Parse Cloud Code 的路徑，接著建立 **main.js** 主程式，內容如下：

```
Parse.Cloud.define("hello", function(request, response) {
  response.success('hello');
});
```

### 4.5 設定 ```appId```

Application ID 用來管理 Parse API 的使用權限，原則上可以自行指定一個任意字串，例如：```5de49f1cd4bd09be95bf35ecbf1117b0```。Mac 或 Linux 的使用者，可以用 ```md5``` 做一個 md5sum 當 appId 用：

```
$ md5 /etc/hosts
MD5 (/etc/hosts) = 91df01d82a846dbddc163a65c0f7b047
```

### 4.6 掛載 parse-server 的 URL router

修改 ```app.js``` 加入：

```
// Serve the Parse API on the /parse URL prefix
app.use('/parse', api);
```

### 4.6 練習加入 ```restAPIKey ```

同樣的觀念，為 Parse Server 加入 ```restAPIKey```。修改示範：

* [jollen/nodejs-express/commit/59880ac](https://github.com/jollen/nodejs-express/commit/59880ac63b29d97130ebb69eb2f43c716cc2ab68)

### 完整示範

提供 **app.js** 程式碼修改示範：

* [jollen/nodejs-express/commit/08f58a4](https://github.com/jollen/nodejs-express/commit/08f58a450ca1cee772a6a12e16c73acdf2a0fdd2)

## Step 5: 啟動 MongoDB

申請 MongoLab 服務請略過本步驟。

## Step 6: 啟動 Node.js

```
$ npm start
```

## API 測試

使用 ```curl``` 來呼叫 Parse 的 REST API 進行初步測試。閱讀 [REST API Guide](https://parse.com/docs/rest/guide#objects-creating-objects) 了解 Parse Server API 細節。

### Creating Objects

測試指令：

```
curl -X POST \
-H "X-Parse-Application-Id: 123456789" \
-H "X-Parse-REST-API-Key: 9d676c364a11d96b8c67e69bf7bbfb82" \
-H "Content-Type: application/json" \
-d '{"score":1337,"playerName":"Sean Plott","cheatMode":false}' \
http://localhost:3000/parse/classes/GameScore
```

返回結果：

```
{"objectId":"B2BjW12yXo","createdAt":"2016-02-04T05:29:35.187Z"}
```
Parse API 使用 ```X-Parse-Application-Id``` 檔頭送出 ```appId```，請填入自行設定的 ```appId```。

## 參考資源

* Parse Server Guide, https://parse.com/docs/server/guide

## Reports and Discussion

* Bug reports of this article: [https://github.com/jollen/blog/issues/10](https://github.com/jollen/blog/issues/10)
* [Parse API Server 開發者聊天室](https://gitter.im/wotcity/parse-server)

</script>]]>
      
   </content>
</entry>
<entry>
   <title>How to build a CoAP message and send it to Internet using FreeRTOS on ESP8266.</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2016/01/build-coap-message-freertos-esp8266.html" />
   <id>tag:www.jollen.org,2016:/blog//2.851</id>
   
   <published>2016-01-27T15:58:03Z</published>
   <updated>2016-01-27T22:15:15Z</updated>
   
   <summary> How to build a CoAP message and send it to Internet using FreeRTOS on ESP8266. Please follow this link if you are unable to read this article. ## Abstraction This article describes how to build a CoAP message by...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="IoT &amp; WoT" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>

How to build a CoAP message and send it to Internet using FreeRTOS on ESP8266.

</p>

<p>Please follow <a href="http://www.jollen.org/blog/2016/01/build-coap-message-freertos-esp8266.html">this link</a> if you are unable to read this article.

<script id="markdown" type="text/plain" data-header-image="https://images.unsplash.com/photo-1431887773042-803ed52bed26?ixlib=rb-0.3.5&q=10&fm=jpg&crop=entropy&s=65b80c72d88022965f20b535b5411918">

## Abstraction

This article describes how to build a CoAP message by er-coap-13 APIs. *er-coap-13* is a high-level CoAP library of Contiki operating system. This article will introduce rtos-wot project which is based on  esp-open-rtos from SuperHouse.

With rtos-wot, you are able to build CoAP messages with FreeRTOS and send them over ESP8266 WiFi module.

## Introducing rtos-wot

[rtos-wot](https://github.com/wot-sdk/rtos-wot) is an open source FreeRTOS distribution for ESP8266 WiFi module. It aims to conform the W3C web of things framework and is heavily based on [esp-open-rtos](https://github.com/SuperHouse/esp-open-rtos).  

The development is still in progress. 

## CoAP Library

*libcoap* of Contiki has already been ported to rtos-wot project. The following steps explains how to build a CoAP message and send it to Internet over ESP8266 wifi module.

### 1. Include necessary header files.

```
#include "er-coap-13.h"
#include "er-coap-13-transactions.h"
```

### 2. Prepare and initialize a CoAP packet.

```
coap_packet_t request[1];
coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0);
```

In the example, the packet is initialized to *COAP_TYPE_CON* type and *POST* method.

### 3. Fill CoAP headers.

```
coap_set_header_uri_path(request, '/object/123456/send');
coap_set_header_uri_host(request, 'wot.city');
```

In the example, the packet headers was filled with both server URI path and server host.

### 4. Set the payload.

```
const char *payload = "{}";
coap_set_payload(request, (uint8_t *)payload, strlen(payload));
```

The payload is the message context. In the example, the payload is an empty JSON object.

### 5. Get message ID

```
request->mid = coap_get_mid();
```

### 6. Serialize CoAP message

```
coap_transaction_t *transaction = coap_new_transaction(request->mid, &ipaddr, uri->port);
transaction->packet_len = coap_serialize_message(request, transaction->packet);
```

### 7. Final step

After serializing the CoAP message, the final CoAP packet is stored at *transaction->packet* field. The final step is to call lwip APIs to create a UDP socket and send out the serialized message. For example, assume that the server was connected via local socket _s_.

```
write(s, transaction->packet, transaction->packet_len);
```

CoAP is basis of web of things framework. For push pattern of WoT, the TD (thing description) can be serialized in CoAP binary format.

### Put together

Please refer to [coap_send](https://github.com/wot-sdk/rtos-wot/tree/master/examples/coap_send) for how to put all things together.

## Reports and Discussion

* Bug reports of this article: [https://github.com/jollen/blog/issues/2](https://github.com/jollen/blog/issues/2)
* Discussion group: [https://www.facebook.com/groups/wotcity/](https://www.facebook.com/groups/wotcity/)

</script>]]>
      
   </content>
</entry>
<entry>
   <title>使用 ESP8266 做為 FreeRTOS 的學習與開發環境</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2016/01/study-freertos-using-esp8266.html" />
   <id>tag:www.jollen.org,2016:/blog//2.850</id>
   
   <published>2016-01-27T11:02:30Z</published>
   <updated>2016-03-10T11:32:35Z</updated>
   
   <summary> 根據 2016 CES 的 IoT 產業新聞分析：WiFi Module 正以出乎意料外的速度，佔領 IoT 市場，並且 RTOS 與 HTML5 扮演重要的主流 IoT 技術。本文介紹如何使用 ESP8266 做為 FreeRTOS 的學習環境。 本文章採用 Markdown 語法撰寫（why?），若無法完整閱讀全文，請點擊這裡。 ## 前言 ESP8266 是 Espressif（樂鑫信息科技有限公司） 所開發的一款 WiFi 模組，ESP8266 WiFi Module 受到開發者與自造社群的喜愛。目前可見的 ESP8266 開發模式有： 1. Microcontrollers 搭配...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="IoT &amp; WoT" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>

根據 2016 CES 的 IoT 產業新聞分析：WiFi Module 正以出乎意料外的速度，佔領 IoT 市場，並且 RTOS 與 HTML5 扮演重要的主流 IoT 技術。本文介紹如何使用 ESP8266 做為 FreeRTOS 的學習環境。

</p>

<p>本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2016/01/study-freertos-using-esp8266.html">這裡</a>。</p>

<script id="markdown" type="text/plain" data-header-image="https://images.unsplash.com/photo-1443453489887-98f56bc5bb38?ixlib=rb-0.3.5&q=20&fm=jpg&crop=entropy&s=ebbdd1c51d315bf2bdcba3f56e6c2ba6">

## 前言

ESP8266 是 Espressif（樂鑫信息科技有限公司） 所開發的一款 WiFi 模組，ESP8266 WiFi Module 受到開發者與自造社群的喜愛。目前可見的 ESP8266 開發模式有：

1. Microcontrollers 搭配 ESP8266 WiFi Module，使用 microcontrollers 來控制 ESP8266，例如：Arduino + ESP8266

2. 使用官方的 ESP8266-RTOS-SDK，使用 FreeRTOS 來開發 ESP8266 的應用程式，ESP8266 WiFi Module 可以做為主動方（即不需要 microcontroller 即可單獨執行）

3. 使用 NodeMCU 的 ESP8266 firmware，使用 Lua script 的方式來開發 ESP8266 應用程式；ESP8266 WiFi Module 可以做為主動方（即不需要 microcontroller 即可單獨執行）

如果要把 ESP8266 做為 FreeRTOS 的學習平台，倒底要選擇那一個 SDK 呢？

## 開始學習 FreeRTOS

要將 ESP8266 做為 FreeRTOS 的學習平台，如果要練習修改或閱讀 FreeRTOS kernel 程式碼，就要使用開源的 FreeRTOS 版本。以下是使用 ESP8266 做為 FreeRTOS 學習或實驗平台的要點：

* 要使用 Open Source 的 [FreeRTOS](http://www.freertos.org) 原始碼
* 要有 ESP8266 的 Portable Layer 實作，例如 *pvPortMalloc()*

由 SuperHouse 社群所維護的 ESP8266 SDK 正好能滿足上述要點。此外，使用 FreeRTOS 在 ESP8266 平台上，打造 IoT 應用程式時，則是要滿足以下基本條件：

* 使用 lwip 做為 TCP/IP Stacks
* 具備 CoAP 的支援
* 硬體控制部份，最好有一個 Component-based 的程式設計模式

為了方便起見，WoT.City 發起 [rtos-wot](https://github.com/wot-sdk/rtos-wot) 計畫，將上述開源計畫整合成一個 FreeRTOS distribution，目標是維護一個用於學習 FreeRTOS + IoT 的 FreeRTOS 特別版本（distribution）。

## 安裝 FreeRTOS 開發環境

以下是開發環境的架設教學，教學內容以 Mac 環境為主。

### 安裝 ESP Open SDK

在 MacOS 系統建置 ESP8266 的編譯環境。首先，確認是否已安裝 Xcode command line tools：

```bash
$ xcode-select --install
```
再使用 [homebrew](http://brew.sh) 安裝所需的套件：

```bash
$ brew tap homebrew/dupes
$ brew install binutils coreutils autoconf automake wget gawk libtool gperf gnu-sed --with-default-names grep bison libvorbis
$ export PATH=/usr/local/opt/gnu-sed/libexec/gnubin:/usr/local/opt/gperf/bin:$PATH
```
製作一個 "case-sensitive"（可區分大小寫檔名）的虛擬磁碟，大小是 8GB：

```bash
$ hdiutil create ./eos.dmg -volname "esp-open-sdk" -size 8g -fs "Case-sensitive HFS+"
```
將 ESP8266 Open SDK 下載至此虛擬磁碟：

```bash
$ hdiutil mount ./eos.dmg
$ cd /Volumes/esp-open-sdk
$ git clone --recursive https://github.com/pfalcon/esp-open-sdk.git
$ cd eos-open-sdk
```

編譯 "separated SDK"：
```bash
$ make STANDALONE=n
```
編譯完成後的畫面：

```
Xtensa toolchain is built, to use it:

export PATH=/Volumes/esp-open-sdk/esp-open-sdk/xtensa-lx106-elf/bin:$PATH

Espressif ESP8266 SDK is installed. Toolchain contains only Open Source components
To link external proprietary libraries add:

xtensa-lx106-elf-gcc -I/Volumes/esp-open-sdk/esp-open-sdk/sdk/include -L/Volumes/esp-open-sdk/esp-open-sdk/sdk/lib
```

根據畫面提示，修改 *PATH* 環境變數：

```
$ export PATH=/Volumes/esp-open-sdk/esp-open-sdk/xtensa-lx106-elf/bin:$PATH
```
完成 ESP8266 Toolchain 的安裝，接下來就可以開始編譯 rtos-wot 了。

### 編譯 FreeRTOS Application Firmware

安裝 [pyserial](https://github.com/pyserial/pyserial) 套件：

```bash
$ git clone https://github.com/pyserial/pyserial.git
$ cd pyserial/
$ sudo python setup.py install
```

下載 [rtos-wot](https://github.com/jollen/rtos-wot) 原始碼：

```bash
$ git clone https://github.com/wot-sdk/rtos-wot
```
編輯 ```include/ssid_config.h``` 檔案，設定 WiFi 的 SSID 與密碼：

```c
#define WIFI_SSID "<the-SSID>"
#define WIFI_PASS "<your-passworld>"
```
完成後，挑選一個 RTOS 應用程式，並進行 firmware 編譯：

```bash
$ cd examples/blink
$ make
```
編譯完成後，在目前的應用程式路徑下，得到以下二個檔案：

* firmware/0x00000.bin
* firmware/0x20000.bin

將以上二個檔案燒錄至 ESP8266 更新即可，指令如下：

```bash
$ make flash ESPPORT=/dev/cu.SLAB_USBtoUART 
```

使用 Linux 環境的讀者，請另行參考[這篇文章](http://www.allaboutcircuits.com/projects/guts-of-the-iot-part-1-building-nodemcu-from-source-for-the-esp8266/)的說明。

### 使用 esptool 更新 ESP8266 Firmware

如果要使用 *esptool.py* 工具，手動更新 firmware 檔案的話，指令如下：

```
$ esptool.py -p /dev/cu.SLAB_USBtoUART --baud 115200 write_flash -fs 32m -fm dio -ff 40m 0x20000 ./firmware/0x20000.bin 0x00000 ./firmware/0x00000.bin
```

在 Mac 下使用 *esptool.py* 更新 NodeMCU firmware 時，需額外加上 *-fm* 與 *-fs* 二個參數。

## 關於 RTOS WoT 計畫

本文使用的 RTOS WoT 版本，是專為 ESP8266 製作的 FreeRTOS 學習、教學與實驗平台。RTOS WoT 的目標是打造一個 Web of Things 的 RTOS SDK。

RTOS WoT 也在 RTOS Application Layer 做了一些加強，請參考以下文章：

* [RTOS WoT (v0.1.0) 使用 FreeRTOS、 lwIP 與 C++ 元件重用](http://www.jollen.org/blog/2016/01/freertos-lwip-esp8266-mbed-styles.html)

## Reference

* http://www.allaboutcircuits.com/projects/guts-of-the-iot-part-1-building-nodemcu-from-source-for-the-esp8266/

## 留言與討論

* 回報本文的錯誤：[https://github.com/jollen/blog/issues/8](https://github.com/jollen/blog/issues/8)
* 技術討論社團：[https://www.facebook.com/groups/wotcity/](https://www.facebook.com/groups/wotcity/)

</script>]]>
      
   </content>
</entry>
<entry>
   <title>RTOS WoT (v0.1.0) 使用 FreeRTOS、 lwIP 與 C++ 元件重用</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2016/01/freertos-lwip-esp8266-mbed-styles.html" />
   <id>tag:www.jollen.org,2016:/blog//2.849</id>
   
   <published>2016-01-07T02:57:42Z</published>
   <updated>2016-01-07T09:17:17Z</updated>
   
   <summary> 沿續前一個 Web of Things 的實驗計畫在 NodeMCU 上使用 er-coap-13，RTOS WoT 使用由 SuperHouse 開發的 esp-open-rtos 版本，進行一些實驗性質的修改。esp-open-rtos 同樣是基於 Espressif 官方的 Espressif IOT RTOS SDK，但改採 open source 版本的 FreeRTOS 與 lwIP 程式碼。 本文章採用 Markdown 語法撰寫（why?），若無法完整閱讀全文，請點擊這裡。 ## 關於 libc 標準 C 程式庫（libc）部份，esp-open-rtos 改用 newlib...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="IoT &amp; WoT" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>

沿續前一個 Web of Things 的實驗計畫<a href="https://github.com/jollen/blog/issues/1">在 NodeMCU 上使用 er-coap-13</a>，RTOS WoT 使用由 SuperHouse 開發的 esp-open-rtos 版本，進行一些實驗性質的修改。esp-open-rtos 同樣是基於 Espressif 官方的 <a href="https://github.com/espressif/esp_iot_rtos_sdk">Espressif IOT RTOS SDK</a>，但改採 open source 版本的 FreeRTOS 與 lwIP 程式碼。

</p>

<p>本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2016/01/freertos-lwip-esp8266-mbed-styles.html">這裡</a>。</p>

<script id="markdown" type="text/plain" data-header-image="https://images.unsplash.com/photo-1446776858070-70c3d5ed6758?ixlib=rb-0.3.5&q=10&fm=jpg&crop=entropy&s=9bbb8a4b7e9b0107fdb0fe52d0dbcaff">

## 關於 libc

標準 C 程式庫（libc）部份，esp-open-rtos 改用 newlib 來取代 Espressif 官方的標準 C 程式庫（libmain.a），並加入了 thread-safe 的支援。相關說明可參考 SuperHouse 官方的 [esp-open-rtos](https://github.com/SuperHouse/esp-open-rtos) 計畫。

## RTOS WoT 目標

[RTOS WoT](https://github.com/wot-sdk/rtos-wot) 是 *esp-open-rtos* 的一份 fork，目標是基於 FreeRTOS 設計並實作符合 W3C Web of Things 標準的 WoT server。RTOS WoT 目標是支援 constrained devices（Micro-controllers），這與目前 W3C 正在發展的 Web of Things Framework（採用 Node.js）目標不同，但未來都會經由 Web of Things 標準，讓不同的平台互通（interoperability）。

## RTOS WoT v0.1.0

RTOS WoT 共有 10 個版本計畫，第一個版本（v0.1.0）的目標非常簡單：

* 使用 C++ programming model
* 加入 WebSocket（版本 13 以上）的支援

WebSocket 的部份還在測試中，C++ programming model 的概念說明如下。

## Reusable Components

加入 C++ programming model 的想法，「不是」為了使用 C++ 來撰寫 FreeRTOS 應用程式，而是能將 device drivers 的程式碼，封裝為 component，以達到重用（reuse）的目的。

設計考量部份，只需要將 ESP8266 的 GPIO、Analog、I2C、UART 腳位，封裝為 class library 即可，但不封裝 FreeRTOS APIs。這項工作的目標，是讓 FreeRTOS 可以具備一層能重用的 device driver 架構。

實作部份，則是直接引用 ARM mbed 的程式碼，範例可參考 [AnalogIn.h](https://github.com/wot-sdk/rtos-wot/blob/master/examples/mbed_air_quality/AnalogIn.h)。有了  mbed components 的移植，未來還可以使用 mbed programming style 來撰寫 FreeRTOS 的驅動程式。

例如，要讀取 ESP8266 的 A0 數據，使用 mbed programming style 的寫法如下：

```
AnalogIn    AIR(17);
int a = AIR;
```

以下是一個 Air Quality 的完整程式碼範例：

```
#include "espressif/esp_common.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "esp8266.h"
#include "math.h"

// C++ programming model
#include "AnalogIn.h"

struct userdata {
    xQueueHandle xQueue;
    xTaskHandle xHandle;
};

/* user context */
static struct userdata user;

/* ADC0 (A0)
 *
 * MP503 Air Quality Sensor -
 * http://www.seeedstudio.com/wiki/File:Air_quality_sensor_MP503.pdf
 */
AnalogIn    AIR(17);

/* This task uses the high level GPIO API (esp_gpio.h) to blink an LED.
 *
 */
void readTask(void *pvParameters)
{
    struct userdata *user = (struct userdata *)pvParameters;
    int a;

    while(1) {
        // read from sensor output voltage
        a = AIR;

        if (a > 798 || a <= 10) {
            printf("Sensor is initializing. Waiting for 5 seconds...\n");
            wait(5);
            continue;
        }

        // send to queue
        xQueueSendToBack( user->xQueue, (void *) &a, portMAX_DELAY );

        // Resume the suspended task ourselves.
        if( user->xHandle != NULL ) {
            vTaskResume( user->xHandle );
        }

        wait(5);
    }
}

void transmitTask(void *pvParameters)
{
    struct userdata *user = (struct userdata *)pvParameters;

    int a;

    while(1) {
        // Suspend ourselves.
        vTaskSuspend( NULL );

        xQueueReceive(user->xQueue, &a, portMAX_DELAY);

        printf("{ \"quality\": %d }\n", a);
    }
}

extern "C" void user_init(void)
{
    uart_set_baud(0, 115200);

    user.xQueue = xQueueCreate(2, sizeof(uint32_t));
    xTaskCreate(readTask, (signed char *)"readTask", 256, &user, tskIDLE_PRIORITY+1, NULL);
    xTaskCreate(transmitTask, (signed char*)"transmitTask", 256, &user, tskIDLE_PRIORITY, &user.xHandle);
}
```

同樣的方式，移植 [DigitalOut.h](https://github.com/wot-sdk/rtos-wot/blob/master/examples/mbed/DigitalOut.h)。以下是一個 GPIO 控制的完整範例：

```
#include "espressif/esp_common.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "esp8266.h"

// mbed API layer
#include "DigitalOut.h"
#include "AnalogIn.h"

// GPIO2 (D4) 
DigitalOut D4(2);

/* This task uses the mbed programming style to blink a LED.
 *
 */
void blinkenTask(void *pvParameters)
{
    while(1) {
        D4 = 1;
        wait(1)
        D4 = 0;
        wait(3);
    }
}

extern "C" void user_init(void)
{
    uart_set_baud(0, 115200);
    xTaskCreate(blinkenTask, (signed char *)"blinkenTask", 256, NULL, 2, NULL);
}
```


## 留言與討論

* [https://github.com/jollen/blog/issues/7](https://github.com/jollen/blog/issues/7)

</script>]]>
      
   </content>
</entry>
<entry>
   <title>[IoT] 如何用 Wio Link 快速自製 GoPro Remote</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2015/12/wio-link-gopro-remote.html" />
   <id>tag:www.jollen.org,2015:/blog//2.848</id>
   
   <published>2015-12-28T07:34:50Z</published>
   <updated>2015-12-28T17:57:57Z</updated>
   
   <summary>上週（12/23 與 12/24）分別在「WoT.City x 台灣大學電機系：Wio Link 工作坊」課程，以及「LinkIt Smart 7688 與 Wio Link（ESP8266）技術沙龍」活動上，閃電展示了如何使用 Wio Link 自製 GoPro 的 Remote 控制器，整個過程只需要大約 30 分鐘，以下分享製作方法。 本文章採用 Markdown 語法撰寫（why?），若無法完整閱讀全文，請點擊這裡。 ## 實作原理 本專案的技術原理非常簡單： * GoPro 內建 Cherokee Web Server * 使用 HTTP GET 方法呼叫 GoPro 的拍照...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="IoT &amp; WoT" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>上週（12/23 與 12/24）分別在「<a href="https://www.facebook.com/mokoversity/posts/500405160140707">WoT.City x 台灣大學電機系：Wio Link 工作坊</a>」課程，以及「<a href="https://www.mokoversity.com/conference/party">LinkIt Smart 7688 與 Wio Link（ESP8266）技術沙龍</a>」活動上，閃電展示了如何使用 Wio Link 自製 GoPro 的 Remote 控制器，整個過程只需要大約 30 分鐘，以下分享製作方法。</p>

<p>本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法完整閱讀全文，請點擊<a href="http://www.jollen.org/blog/2015/12/wio-link-gopro-remote.html">這裡</a>。</p>

<script id="markdown" type="text/plain" data-header-image="https://images.unsplash.com/photo-1441644599508-24ae08965c5c?ixlib=rb-0.3.5&q=10&fm=jpg&crop=entropy&s=86ac0e8a9fa4f935beafaf83148abd62">

## 實作原理

本專案的技術原理非常簡單：

* GoPro 內建 Cherokee Web Server
* 使用 HTTP GET 方法呼叫 GoPro 的拍照 API

本文使用 Wio Link 或 NodeMCU 開發板，並以 Lua 來撰寫 HTTP request 程式碼。改用 Node.js 來實作 HTTP request 的話，可以改用近期火紅的 MediaTek LinkIt Smart 7688 (Duo) 開發板來製作 GoPro 控制器。

## Step 1: 材料準備

* GoPro 一台，筆者使用的是 GoPro Hero 4 Silver
* Wio Link 或 NodeMCU 開發板（皆使用 ESP8266 模組）

## Step 2: 更新 GoPro Firmware

下載 [GoPro Studio](http://zh.shop.gopro.com/softwareandapp/gopro-studio/GoPro-Studio.html) 安裝後，將 GoPro 連接到電腦。GoPro Studio 會自動更新 GoPro firmware。

## Step 3: 更新 Wio Link Firmware

使用 NodeMCU 的開發者可忽略這個步驟。

Wio Link 預載 Seeed Stduio 專門打造的 firmware，可搭配 Wio Link App[1] 快速打造 IoT application。在這個小專題裡，我們會使用 Lua 來撰寫簡單的 GoPro 控制器，因此要更換為 NodeMCU firmware。

更新 NodeMCU firmware 的詳細步驟，請參考[ESP8266 & NodeMCU 開發入門 (Part 5) - 編譯並更新 NodeMCU Firmware](https://wotcity.com/blog/2015/11/13/esp8266-nodemcu-iot-starter-part-5/)。

## Step 4: 連接 GPIO Button

如圖 1，將 Grove Kit 的 Button 接到 Wio Link 的 Digital 插糟。以圖 1 為例，Button 將經由 GPIO14 來控制，後續撰寫程式時，須將 GPIO14 設定為中斷觸發。

![wio-link-gopro-1](https://cloud.githubusercontent.com/assets/1126021/12014473/64353fe8-ad68-11e5-9eb7-c1391fc05205.jpg)
圖 1：連接 GPIO Button

## Step 5: 認識 Wio Link GPIOs

Wio Link 設計了 3 個 Digital 插糟，每個插糟上都有 2 根 GPIO 腳位。以上圖為例，觀察黃色接線，可以看出，Grove Kit 的 Button 是經由 GPIO14 來控制。Wio Link 的 GPIO 腳位，相容於 NodeMCU，因此應用上可視為 NodeMCU 的替代品。

| Wio Link 腳位名稱 | NodeMCU 腳位名稱 | Note | 
|-------|---------|------------|-------|
| GPIO-13 | GPIO-13 |  D7  | 
| GPIO-12 | GPIO-12  |  D6 | 
| GPIO-14 | GPIO-14  |  D5 | 

以圖 1 為例，撰寫 Lua 程式將 GPIO-14（D5）設定為中斷觸發模式：

```
pin = 5
gpio.mode(pin, gpio.INT)
```

再定義中斷觸發的 callback function：

```
--set the interrupt callback function
gpio.trig(pin, "both", button)
```

對 Wio Link 與 NodeMCU 的 Lua 開發環境不熟悉的話，可以參考以下文章：

* [ESP8266 & NodeMCU 開發入門 (Part 1) - Hello World](https://wotcity.com/blog/2015/08/31/esp8266-nodemcu-iot-starter-part-1/)

WoT.City 提供的[ESP8266 & NodeMCU 開發入門](https://wotcity.com/blog/tag/esp8266/)系列文章，可做為初學者的自學教材。

## Step 6: 撰寫 Lua 程式

將以下程式碼上傳至 Wio Link：

```
--
-- GoPro Remote Simple
-- See: https://github.com/jollen/blog/issues/6
--

-- Configs
host = "10.5.5.9"
port = 80
ssid = "<SSID>"
pass = "<PASSWORD>"
pin = 5
api = "/gp/gpControl/command/shutter?p=1"

-- Configure the ESP as a station (client)
wifi.setmode(wifi.STATION)
wifi.sta.config(ssid, pass)
wifi.sta.autoconnect(1)

-- Create a TCP socket
sk = net.createConnection(net.TCP, 0)
sk:on("receive", function(sck, c) 
  print(c)
end)

-- Set GPIO
gpio.mode(pin, gpio.INT)

-- Poll GPIO
now = 0
duration = 0
    
function button(level)
  duration = tmr.now()-now
  print(duration)
  now = tmr.now()

  if level == 1 then 
    print("down")
    sk:send(headers)
  else 
    print("up")
  end
end

--set the interrupt callback function
gpio.trig(pin, "both", button)
    
-- Print IP address
local ip = wifi.sta.getip()

-- Make HTTP request headers
if (ip == nil) then
  ip = "localhost"
end
headers = "GET " .. api .. " HTTP/1.1\r\nHost: " .. ip .. "\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n"
print(headers)

-- Connect to GoPro host
sk:connect(port, host)
```

可將程式碼儲存為 *init.lua* 後上傳至 Wio Link。Wio Link 開機時，會自動執行 *init.lua*。

## Step 7: 開啟 GoPro Wifi 並進行測試

1. 開啟 GoPro Wifi 
2. 將 GoPro 設定為拍照模式
2. 上傳上述程式碼至 Wio Link
3. 按下 Button 拍照

實境測試影片如下。

<iframe width="560" height="315" src="https://www.youtube.com/embed/vsLIuOPg83c" frameborder="0" allowfullscreen></iframe>

## 網路資源

[1]: Wio Link App, https://itunes.apple.com/tw/app/wio-link/id1054893491?mt=8


## 留言與討論

* [https://github.com/jollen/blog/issues/6](https://github.com/jollen/blog/issues/6)

</script>]]>
      
   </content>
</entry>
<entry>
   <title>[IoT] 在 NodeMCU 上使用 er-coap-13</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2015/12/nodemcu-firmware-er-coap-13.html" />
   <id>tag:www.jollen.org,2015:/blog//2.847</id>
   
   <published>2015-12-28T04:00:39Z</published>
   <updated>2015-12-28T15:25:45Z</updated>
   
   <summary>源由 為了在 NodeMCU 上進行 WoT 實驗，日前開啟了一個小型的專案 node-wot，node-wot 將會持續小幅修改 nodemcu-firmware，以做為 WoT 的實驗用 firmware。 本文章採用 Markdown 語法撰寫（why?），若無法閱讀內文，請點擊這裡。 ## node-wot 專案：ESP8266 CoAP SDK 目前的主要修改內容，是將 NodeMCU firmware 裡的 libcoap 更換為 Contiki OS 的 er-coap-13 實作，並且只保留了 CoAP client。主要的原因如下： * er-coap-13 有比較嚴謹的 API 設計，可做為 NodeMCU 的...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="IoT &amp; WoT" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<h1>源由</h1>

<p>為了在 NodeMCU 上進行 WoT 實驗，日前開啟了一個小型的專案 <a href="https://github.com/node-wot/node-wot">node-wot</a>，node-wot 將會持續小幅修改 nodemcu-firmware，以做為 WoT 的實驗用 firmware。</p>

<p>本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法閱讀內文，請點擊<a href="http://www.jollen.org/blog/2015/12/nodemcu-firmware-er-coap-13.html">這裡</a>。</p>

<script id="markdown" type="text/plain" data-header-image="https://images.unsplash.com/photo-1436985487860-712a3b558087?ixlib=rb-0.3.5&q=10&fm=jpg&crop=entropy&s=7a36e714238ddd2b2e54633e9eeaf18d">


## node-wot 專案：ESP8266 CoAP SDK

目前的主要修改內容，是將 NodeMCU firmware 裡的 libcoap 更換為 Contiki OS 的 er-coap-13 實作，並且只保留了 CoAP client。主要的原因如下：

* er-coap-13 有比較嚴謹的 API 設計，可做為 NodeMCU 的 CoAP SDK，未來可以更方便開發 CoAP 應用程式
* 「有朝一日」，或許可加入基於 er-coap-13 的 LWM2M 實作 (wakaama)
* 未來計畫引入 protothreads 機制，取代 FreeRTOS multitasking
* Heap management

現階段，僅將 ESP8266 做為 data push object，並不做為 CoAP server，因此只保留 CoAP client 的實作。主要考量是節省 RAM + ROM 的空間（ESP8266 的 iram1_0_seg + irom0_0_seg）。

### 使用 CoAP API

er-coap-13 的完整 API 設計，是 node-wot 專案的重要考量。例如，要建立一個新的 CoAP 封包，只要呼叫 *coap_init_message()* 函數即可：

```
// 引入 er-coap-13 APIs
#include "er-coap-13.h"
#include "er-coap-13-transactions.h"

// 宣告 CoAP packet
coap_packet_t request[1];

// 將 CoAP packet 初始化為 COAP_TYPE_CON 類型，並使用 HTTP POST
coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0);
```
要初始化 CoAP headers，例如：填寫 CoAP header 的 Uri Path 與 Uri Host，只需要這樣寫：

```
coap_set_header_uri_path(request, 'object/123456/send');
coap_set_header_uri_host(request, 'wot.city');
```
要加入 payload（本文），也只要這樣寫：

```
const char *payload = "{}";
coap_set_payload(request, (uint8_t *)payload, strlen(payload));
```

最後也只要呼叫不到 5 個 APIs，就可以將 CoAP 封包送出。

er-coap-13 有更好的 abstraction level，可以隱藏所有 CoAP 標準的技術細節。

### Heap Management

node-wot 上的 er-coap-13 做過微幅修改，以及完整的測試，可保證 CoAP requests 不會消耗 Heap 空間。Heap 空間若持續減少，會發生記憶體不足的現象，Lua 程式會 crash。

## Lua 範例程式

node-wot 的修改並不影響 Lua programming model，因此 Lua 程式可同時在 nodemcu-firmware 與 node-wot 上執行。

以下是 2015 年 12 月 8 日在 [ESP8266 IoT Workshop](https://www.mokoversity.com/events/esp8266) 上使用的 Lua 範例（搭配 node-wot firmware 使用）。

### Hello, Lua

以 HTTPD 做為學習 Lua 的 "Hello, World"。

```
-- Select IO - GPIO4
outpin=4
gpio.mode(outpin,gpio.OUTPUT)
gpio.write(outpin,gpio.HIGH)    

function power(stat)
  if stat=="ON"  then gpio.write(outpin,gpio.HIGH) 
    return 
   end
  if stat=="OFF" then gpio.write(outpin,gpio.LOW) 
    return 
   end
end

-- Print IP address
ip = wifi.sta.getip()  
print(ip)

-- Configure the ESP as a station (client)
wifi.setmode(wifi.STATION)  
wifi.sta.config("JY", "1234567654321")  
wifi.sta.autoconnect(1)

-- Create a server
-- and set 30s time out for a inactive client
sv = net.createServer(net.TCP, 30)

-- Server listen on 80
-- Print HTTP headers to console
sv:listen(80,function(c)  
    c:on("receive", function(conn, payload)
        print(payload)

        if (string.find(payload, "GET /power/on") ~= nil) then
            power("ON")
        elseif (string.find(payload, "GET /power/off") ~= nil) then
            power("OFF")
        end
        
        conn:send("HTTP/1.1 200 OK\n\n")
        conn:close()
    end)
end)
```

### Hello, CoAP

以 CoAP request 做為學習 IoT 的 "Hello, World"。

```
-- Print IP address
ip = wifi.sta.getip()  
print(ip)

-- Configure the ESP as a station (client)
wifi.setmode(wifi.STATION)  
wifi.sta.config("JY", "1234567654321")  
wifi.sta.autoconnect(1)

-- Print IP address
ip = wifi.sta.getip()  
print(ip)

-- Create a CoAP client
cc = coap.Client()

-- Make a POST request
uri="coap://127.0.0.1:8000/object/12345678/send"

tmr.alarm(0, 1000, 1, function() 
    cc:post(uri, "{\"temp\":20}\r\n")
end)
```

### Hello, LWM2M

最後是一個 CoAP-LWM2M Broker 的範例。需搭配 WoT.City 專案使用。

```
- Print IP address
ip = wifi.sta.getip()  
print(ip)

-- Configure the ESP as a station (client)
wifi.setmode(wifi.STATION)  
wifi.sta.config("JY", "1234567654321")  
wifi.sta.autoconnect(1)

-- Print IP address
ip = wifi.sta.getip()  
print(ip)

-- Create a CoAP client
cc = coap.Client()

-- Make a POST request
uri="coap://172.20.10.4:8000/object/12345/send"
cc:post(uri, "{\"temp\":30}\r\n")

-- Register LWM2M object
registry="coap://172.20.10.4:8000/75000/1/create"
cc:post(registry, "{}\r\n")
```

這個範例需要搭配一個 *LWM2M broker server * 來使用：

* NodeMCU 以 CoAP 發送一個 LWM2M 的註冊請求
* LWM2M broker 協助 NodeMCU 準備完整的 LWM2M object，並向 LWM2M server 註冊
* LWM2M broker 作為一個代理（proxy）的角色

這個範例，假設 NodeMCU 僅做為 CoAP client 使用，因此 node-wot 目前並沒有移植 er-coap-13 的 CoAP server 實作。

此外，考量硬體限制（ROM 與 RAM 大小），也沒有移植 LWM2M 程式庫至 node-wot。

## 關於 LWM2M

OMA LWM2M 建構在 CoAP 協定層之上，在這次的工作坊裡，展示了如圖 1 的佈署（deploy）策略。

以下是這個佈署策略的簡要說明：

* LWM2M 只佈署在 connected device 上（具對外網路能力的裝置），現階段可使用 Notebook、LinktIt Smart 7688 或 Intel Edison 做為 connected device

* ESP8266 做為 physical data object（IoT data device），並且將 CoAP blocking request 修改為 protothread 機制

* Physical data object 不具備 control 能力

## 留言與討論

* [https://github.com/jollen/blog/issues/1](https://github.com/jollen/blog/issues/1)

</script>]]>
      
   </content>
</entry>
<entry>
   <title>物聯網架構師： 談 IoT Diagram</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2015/09/iot-diagram.html" />
   <id>tag:www.jollen.org,2015:/blog//2.846</id>
   
   <published>2015-09-11T15:34:57Z</published>
   <updated>2015-09-11T20:37:20Z</updated>
   
   <summary>物聯網架構師： 談 IoT Diagram 文/Jollen Chen（原文刊載於 CTIMES 雜誌 2015 年 8 月號） 上一期專欄提到的通訊協定革命，是微觀的 IoT 經濟體；這一期來討論宏觀的 IoT 經濟體：IoT Diagrams。IoT Diagram 簡單說，就是物聯網的構成，這包含很多面向，例如：Product、Service、Experiences、Business Models 等。以下從中摘錄幾個重點主題（Agenda）與大家分享。 第一、Sensor。這是 IoT 最基本的構成，Sensor 的成本與技術，直接影響 IoT 的佈署與互連方式。此外，整合無線通訊技術（WiFi、BLE、GPS、Satellite 與 GPRS ）的 Sensor 會帶出各式的物聯網應用。目前有一些新創公司（例如：WEFT），使用無線通訊技術的 Sensor 來提供物流追蹤（Logistics）服務。 第二、Actor。最主要的 Actor 是使用者（人類），但 M2M 的情境運用越來越廣泛，因此...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      物聯網架構師： 談 IoT Diagram
文/Jollen Chen（原文刊載於 CTIMES 雜誌 2015 年 8 月號）

上一期專欄提到的通訊協定革命，是微觀的 IoT 經濟體；這一期來討論宏觀的 IoT 經濟體：IoT Diagrams。IoT Diagram 簡單說，就是物聯網的構成，這包含很多面向，例如：Product、Service、Experiences、Business Models 等。以下從中摘錄幾個重點主題（Agenda）與大家分享。

第一、Sensor。這是 IoT 最基本的構成，Sensor 的成本與技術，直接影響 IoT 的佈署與互連方式。此外，整合無線通訊技術（WiFi、BLE、GPS、Satellite 與 GPRS ）的 Sensor 會帶出各式的物聯網應用。目前有一些新創公司（例如：WEFT），使用無線通訊技術的 Sensor 來提供物流追蹤（Logistics）服務。

第二、Actor。最主要的 Actor 是使用者（人類），但 M2M 的情境運用越來越廣泛，因此 Device 本身也是 Actor 的角色。在 IoT Diagram 上，Actor-Sensor 是很常見的關聯。例如，Actor 走路時，帶動腳上的計步器。

第三、Device。泛指連網裝置（Connected Device），例如：手機。Sensor-Device 是大家最熟悉的關係，例如：計步器 Sensor 將數據傳送到手機上。報導指出，在 2020 年時，會有超過 50 billion 的連網裝置，當中又以 Sensor-type 的成長最多（可能佔比也最多）。Device-Device 的關聯（M2M）是最重要的使用情境。

第四：Cloud。Cloud-Actor、Cloud-Device 甚致是 Cloud-Sensor 都是重要的關鍵。目前許多通訊協定標準與技術，都在解決 Cloud-Sensor 的技術問題。所以數據收集與傳輸並不會關鍵議題，真正的關鍵是 IoT Cloud 的供應商。IoT Cloud 可以是企業級的服務供應商，也可以是個人自行架設的服務；前者是中央化的生態，後者則是去中央化（decentralized）的生態。

第五：Data。IoT 的重點並不是「Things」，而是「Data」。Data 又涉及隱私（Privacy）與安全性（Security）等問題，這未來將是 IoT 產品化的過程中，需要優先克服的二個問題。其中，隱私問題層面又更廣，例如：涉及法律問題。另外，中央化的 IoT Cloud 生態，因為儲存了大量的個人資料，除了隱私問題外，也可能衍生資料的所有權問題。

第六：Interface。Interface-Device 是最典型的關聯，例如：觸控。Interface 的設計直接影響到 User Experience，因此這個議題有很大的發揮空間。Interface-Sensor 的關鍵中，最常見的設計就是 LED Lights，但隨著 IoT 逐漸被佈署在 Web 上，Interface-Actor 的設計會成為關鍵，目前常見的機制是 Notification 與 Alert 。

第七：Energy。能源，是最近突然被重視的 IoT 議題，Smart Energy 會成為 IoT 領域的創新熱點。更多的裝置，代表更多的能源消耗，所以 Energy Delivery、Smart Energy System 與 Power Sustainability 或許是很有潛力的創業與投資項目。Energy-Device 的關聯，目前仍以電池為主，但 Energy-Sensor 則開始在研究無線供電的做法。

最後，補充說明二點。Smart Grid 是一種 Energy Delivery 的方式，被視為是未來明星產業，目前認為需要產生一套新的電力標準。美國現行的電力網（Power Grid）系，從 1900 年代開始施行至今，已經超過 100 年沒有進行更新。藉著 IoT 的發展，順勢重構現有的 Power Grid，已被提出來討論。

Smart Grid 的技術很可能先應用在 Smart Home 領域。目前的 Smart Home 系統缺乏 Energy 的考量，例如：在屋頂裝設溫度感測器時的永續供電問題。Smart Home 不考慮 Smart Grid 時，就像是買好了一套電視與音響，但裝潢時佈線沒有到位。TI 目前已經開始研究 Smart Grid 技術議題。

      
   </content>
</entry>
<entry>
   <title>Change of IoT Apps：mBaaS 遇上 IoT</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2015/05/change-of-iot-apps.html" />
   <id>tag:www.jollen.org,2015:/blog//2.845</id>
   
   <published>2015-05-05T05:18:42Z</published>
   <updated>2015-05-05T10:19:24Z</updated>
   
   <summary>文／Jollen Chen（原文刊載於 CTImes 雜誌：2015 年 5 月號） mBaas 雖然不是新的概念，但它改變了應用程式開發的思惟。比如說：Real-time WebHooks。WebHooks 是一個 Backend-to-backend 的設計模式，mBaas 對 Mobile app 開發模式，產生有一些重要的改變。 「Change of Mobile Apps」是對 mBaaS 最佳的註解。這個 mBaaS 模式，也正開始「Change of IoT Apps」。根據筆者的觀察，mBaaS 商業模式，最有機會在 IoT 領域，取得大規模的成功。現在的 mBaaS 供應商，往 IoT 服務平台發展，已經成為一個標準策略。一個 mBaaS + IoT 的平台，應該具備哪些基本功能呢？以下是筆者的一些匯整，供大家參考。 第一、Smart...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      文／Jollen Chen（原文刊載於 CTImes 雜誌：2015 年 5 月號）

mBaas 雖然不是新的概念，但它改變了應用程式開發的思惟。比如說：Real-time WebHooks。WebHooks 是一個 Backend-to-backend 的設計模式，mBaas 對 Mobile app 開發模式，產生有一些重要的改變。

「Change of Mobile Apps」是對 mBaaS 最佳的註解。這個 mBaaS 模式，也正開始「Change of IoT Apps」。根據筆者的觀察，mBaaS 商業模式，最有機會在 IoT 領域，取得大規模的成功。現在的 mBaaS 供應商，往 IoT 服務平台發展，已經成為一個標準策略。一個 mBaaS + IoT 的平台，應該具備哪些基本功能呢？以下是筆者的一些匯整，供大家參考。

第一、Smart Push Notification。智能手機將 Push Notification 機制運用到極緻，手機用戶也已經很習慣這樣的推送通知機制。從技術的角度來看，Push Notification 在 IoT 架構中，是一種 Physical to Mobile 的使用案例。將 Physical（裝置實體）的數據，推送到手機上，中間需要一個「IoT 通道」。除了現有的 mBaaS 供應商外，未來應該會有大量的新創公司，提供這類型的的服務。

第二、Social Integration。讓 IoT 裝置與社交網路整合也是一個趨勢，例如：Facebook、WeChat、Twitter 等。從技術的角度來看，與社交網路整合是為了加入 OAuth 認證機制，以及將訊息推送至個人社交平台上。另外，筆者認為，IoT 與 Social Networks 的結合，可能會是另外一個 IoT Apps 的呈現形式。

第三、Small Data Analytics。小量資料分析技術，大多實作於裝置端（In-place analysis）。進行小量資料分析的目的，大致可分為：Filtering、Real-Time Notfitication 與 Time-Series Data Push。將一些無效或無用的資料捨棄，技術上並不太困難，可以安裝一個固定的演算模式或模型（Pattern and Models）在裝置上。小量分析與即時推送的結合，比較偏向於警示性質的訊息（Alert），但未來也可能應用在 LWM2M（Lightweight M2M）的情境中。至於 Time-Series Data 則是應用在連續資料的推送，在推送的過程式，可以為資料加註訊息（例如：Timestamp）或記號等。

第四、REST API Broker。IoT 裝置本身會提供一些簡單的 REST API，或是經由「通道」來「代理提供」，因此筆者也認為，REST API Broker（Proxy）服務，未來也將扮演重要的角色。REST API Broker 的另一個重責大任，就是進行 Backend-to-Backend 的整合。例如，知名的 Firebase 服務，就是一個 Backend-to-Backend 整合的平台。未來這樣的平台，也將延伸到物聯網裝置。

第五、Code Generation。對一個以 MCU 為主的 IoT 裝置，自動代碼產生相對應的代碼，可能是一個重要的機制。例如，Temboo 就提供這樣的服務。從「物聯網裝置」的角度來看，Code Generation 的重要性，應該略大於「視覺化編程」；因為物聯網裝置，不只有 GPIO 控制的功能，也會有網路與演算法的能力。因此，Code Generation 其實是一種 Code Template 的服務，等於是開發者的「懶人包」。另一個需要 Code Generation 的原因是，IoT 裝置會與 mBaaS 或 REST API 做整合，這些程式碼直接由系統產生即可。

第六、IoT Apps Hosting。將 Physical 包裝為 App 將是一個潮流，目前提供相關服務的供應商還不多，但許多新創公司正在往這個方向前進。像是，built.io 就提供 IoT Apps 的代管服務。

以上都是由技術的角度出發，以及過去的收集與觀察，所進行的整理。其中，物聯網應用程式代管服務，是筆者認為最重要，也是最具商業潛力的領域。從上述的分析，可以歸納出一個結論：未來的物聯網新創團隊，勢必要具備 Full Stack 的技術能力，以及 End-to-End 商業模式的策略思考能力。
      
   </content>
</entry>
<entry>
   <title>ARM mbed 學習紀錄, #2：IoT Objects 與 Websocket</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2015/01/arm-mbed-iot-objects-websocket.html" />
   <id>tag:www.jollen.org,2015:/blog//2.844</id>
   
   <published>2015-01-26T12:49:19Z</published>
   <updated>2015-01-26T18:57:48Z</updated>
   
   <summary>Websocket 是 HTML5 標準的一項技術，Websocket 讓 client 與 server 能建立永續性的 TCP 連線。簡單來說，有了 Websocket，就能實作出 real-time data streaming 機制。 以下將說明 IoT 第 4 階段，也就是 WoT 最重要的一個觀念：使用 Websocket channel server 來封裝 IoT objects，讓 IoT devices 成為抽象化的 Websocket server。 關於 IoT 與 Websocket 一般來說，Websocket 的使用案例（use...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>Websocket 是 HTML5 標準的一項技術，Websocket 讓 client 與 server 能建立永續性的 TCP 連線。簡單來說，有了 Websocket，就能實作出 real-time data streaming 機制。</p>

<p>以下將說明 IoT 第 4 階段，也就是 WoT 最重要的一個觀念：使用 Websocket channel server 來封裝 IoT objects，讓 IoT devices 成為抽象化的 Websocket server。</p>

<h2>關於 IoT 與 Websocket</h2>

<p>一般來說，Websocket 的使用案例（use case）是 server push（data push）機制，也就是說，ARM mbed 物件本身，應該是扮演 Websocket server 的角色。但現實層面，讓 IoT 分演 Websocket server 的話，會有幾個技術問題：</p>

<p>1. ARM mbed 要管理 client 端的 connections<br />
2. 需要更多的內存來維護 client connections<br />
3. 需要實作 Data push 的演算法，例如：round-roubin<br />
4. 要考量 error handling 與 exception handling</p>

<p>因此，最簡單的 scenario 設計如下：</p>

<p>1. 佈署專用的 Websocket channel server<br />
2. ARM mbed 將 data 即時推送（push）到 Websocket channel server<br />
3. 用戶（user）與 Websocket channel server 建立 Websocket connection<br />
4. 用戶接收 Websocket channel server 的即時資料（經由 server push）</p>

<p>抽像上來看，ARM mbed 仍然是 server 端，而不是 client 端；真正的 client 端是用戶。</p>

<h2>Websocket Channel Server</h2>

<p>Websocket channel server 扮演封裝 IoT 物件的角色，對 Websocket server 來說，只要能定義好「channel」的結構，就能封裝數以萬計、千萬計的 IoT 物件。「抽像上來看，ARM mbed 仍然是 server 端」，就是這樣的觀念。</p>

<p>ARM mbed 官方就提供了 Websocket channel server 的服務：</p>

http://sockets.mbed.org

<h2>ARM mbed 與 Websocket Client</h2>

<p>了解上述觀念後，技術的實作就能區隔為二個部份：</p>

<p>1. Websocket channel server 服務，可使用 sockets.mbed.org<br />
2. ARM mbed 的 Websocket client 實作</p>
]]>
      
   </content>
</entry>
<entry>
   <title>ARM mbed 學習紀錄, #1：IoT、WoT 與 Physical</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2015/01/arm-mbed-1-physical-web.html" />
   <id>tag:www.jollen.org,2015:/blog//2.843</id>
   
   <published>2015-01-25T03:45:44Z</published>
   <updated>2015-01-25T10:11:08Z</updated>
   
   <summary>在 IoT 的技發發展藍圖裡，描述了 IoT 的 4 個發展階段，其中第 4 個階段就是 WoT。而目前正好處於第 4 個 IoT 發展階段。去年 Google 發起的 Physical Web 計畫，是一個非常先期的研究計畫，就是為了 IoT 的新階段預做準備。 IoT 的第 4 個階段，將聚焦在 Advanced Sensor Fusion 與 Physical-World Web 層面，這二個層面簡單來說，就是 WoT。根據維期百科上的定義，WoT 是 IoT 的 Application Layer，並且是使用 Web 技術來打造...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      在 IoT 的技發發展藍圖裡，描述了 IoT 的 4 個發展階段，其中第 4 個階段就是 WoT。而目前正好處於第 4 個 IoT 發展階段。去年 Google 發起的 Physical Web 計畫，是一個非常先期的研究計畫，就是為了 IoT 的新階段預做準備。

IoT 的第 4 個階段，將聚焦在 Advanced Sensor Fusion 與 Physical-World Web 層面，這二個層面簡單來說，就是 WoT。根據維期百科上的定義，WoT 是 IoT 的 Application Layer，並且是使用 Web 技術來打造 application。也就是說，IoT + Web-enabled technologies 就是 WoT。

對 WoT 來說，最重要的觀念，就是以 URL 來表示 IoT 裝置；為 IoT 加入 URL 的觀念，就是 Google 提出的 Physical Web 計畫。所以說，WoT 與 Physical Web 是一體兩面的觀念，都是 IoT 正進入的新發展階段。

雖然 WoT 都是使用目前已經存在的軟體技術，但許多觀念都要重新思考，例如：

* Architecture 與 Framework
* Composition Layer 的重新設計

一個重新定義的 application 框架，或是 frontend 的 Composition layer 設計，可能會是 WoT 的關鍵技術。因此，利用這次帶領 Mokoversity 農場計畫團隊，到深圳與 Seeed Studio 交流的機會，開始了相關的研究工作。目前已經完成的實驗性質開發，就是利用 virtual DOM 技術，來進行 UI 的 boundary composition。

目前的實驗計畫，選用的 IoT 平臺是 ARM mbed 系統，主要原因有：

* ARM mbed 是 full stack OS
* 更易於實作 REST API（mbed device driver）
* Apache 2 license 更易於商業發展

目前有許多 ARM mbed 的開發板，這些開發板並不是「另一個 Arduino」硬體，而是更能符合 WoT 理念的 RESTful device。同樣的硬體，不同的觀念、技術框架與商業思維，能帶來不同的產品思維與商業模式。所以，ARM mbed 與 WoT 帶來的，將是一場新的革命與機會。
      
   </content>
</entry>
<entry>
   <title>Life Hacking Startups</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2015/01/life-hacking-startups.html" />
   <id>tag:www.jollen.org,2015:/blog//2.842</id>
   
   <published>2015-01-05T08:30:20Z</published>
   <updated>2015-01-06T10:53:37Z</updated>
   
   <summary>文／Jollen Chen（原文刊載於：CTimes 2015 年 1 月號） Life hacking 是 1980 年代 Hacker 文化下的副產物。Hacker 的一個重要精神，就是製作能提高生產力（productivity）的工具，例如：命令列工具（command line tools）、快速鍵（shortcuts）或是一些程式設計的小技巧（programming skills）。 程式設計師有很多可以解決常見問題的巧妙方式（ingenious），比如說：利用 editorconfig 解決跨編輯器的問題。使用 editorconfig 也解決了不同人寫程式時的格式問題。Life hacking 文化同樣如此，利用一些方式或技巧，解決生活上的問題，或是提高自已的生產效率。其中一個知名的 life hacking 就是「2mm 法則」。 2mm 的差異，決定了足球射門得不得分，這就是 2mm 法則的一個例子。又如，知名演說家與名嘴，也是 2mm 的差異。2mm 法則是知名演說家 Tony Robbins 提出的 life hacking...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      文／Jollen Chen（原文刊載於：CTimes 2015 年 1 月號）

Life hacking 是 1980 年代 Hacker 文化下的副產物。Hacker 的一個重要精神，就是製作能提高生產力（productivity）的工具，例如：命令列工具（command line tools）、快速鍵（shortcuts）或是一些程式設計的小技巧（programming skills）。

程式設計師有很多可以解決常見問題的巧妙方式（ingenious），比如說：利用 editorconfig 解決跨編輯器的問題。使用 editorconfig 也解決了不同人寫程式時的格式問題。Life hacking 文化同樣如此，利用一些方式或技巧，解決生活上的問題，或是提高自已的生產效率。其中一個知名的 life hacking 就是「2mm 法則」。

2mm 的差異，決定了足球射門得不得分，這就是 2mm 法則的一個例子。又如，知名演說家與名嘴，也是 2mm 的差異。2mm 法則是知名演說家 Tony Robbins 提出的 life hacking 觀念。Tony Robbins 在 2007 年被富比士（Forbes）選為「Celebrity 100」。2mm 法則可以延伸到商業、健康與財務等各方面，當然也能延伸到創業活動上。

Life hacking 與技術創業家又有何關係？ 記得不久前，在 Mokoversity 舉辦的一場對談活動中，我提到了「成功，每個人都有不同的定義」。在 Medium 上的一位作者 Ali Mese 也提到：「How do you define success?」這或許應該是創業者的第一堂課。

當我們從上班族切換到創業者身份時，許多 Life 都要去 Hacking。如果你不知道如何幫自己或團隊定義「成功」，那創業又要如何成功呢？每個人對自己事業的成功，都有不同定義，所以必須先建立遵重與信任。例如，有人認為賺到錢，成為億萬富翁叫做成功。有人認為，能滿足自已的生活需要，然後創造出新奇有趣的產品，並從中獲得成就感，就叫成功。

如何定義成功，當然是很重要的 life hacking。Ali Mese 的文章提到，成功的創業者，不一定是輪了幾輪投資，然後拿到幾百萬資金的人。在台灣，有一個現象，就是拿到投資人的資金，或是有了 A 輪融資，或是被併購，就叫創業成功。在媒體的推波助瀾下，這也變成常規了。這是一個有 life hacking 文化的創業環境嗎？

在矽谷，擁有很成功的失敗經驗者，也被視為成功的創業者。所以，life hacking 看重的是創業的過程，一個 journey。在這個 journey 中，是否交到新朋友，找到可以互許終生的對象，是否得到家人的全面支持等等；以及，自己是否很享受這樣的過程。Life hacking 的另外一個層面就是，「從生活中思考」。

Life Hacking Startups 被認為是 2015 年的創業趨之一。比如說，你是創造一個讓生活更便利的產品，或是創造一個能解決大問題的服務；還是，只是 Coding 出一個功能強大的 App 呢？Life hacking 讓創業者思考解決生活問題的妙招，life hacking 也讓創業者更享受創業的 journey。

另一個 life hacking 的例子，就是筆者的 Mokoversity 農場計畫。這個計畫要利用大家的「黃金四小時」來創業。從 life hacking 的哲學告訴我們，「上班當然可以創業」。上班當然也能為創業預做準備，前提是，要有能力 hack 自己的生活。Life hacking startups 另一個層面的哲學，就是如此。

想創業，可是還不想放下全職工作，而且也有老婆跟小孩，還能創業嗎？這當然可以。最有名的例子就是 Ted Roden。Ted Roden 是 FancyHands  的創辦人，他在 New York Times 工作時負責 News.me 項目，就是利用這段時間，他建立了 FancyHands。Ted Roden 在 New York Times 期間，有老婆跟小孩要照顧，但還是成功發佈了 FancyHands，而且還募得資金。

Life hacking 是重要的 hacker 文化，當然也發展出像是 Hack College 這個的組織。成立於 2006 年的 Hack College 就是知名的 life hacking 學校；Hack College 提供大學生 life hacking 方面的知識。Hacker 擅於製作巧妙的工具來解決問題，創業旅途中所遇到的各種問題，例如：老闆、家人或時間等問題，都可以發揮 Hacker 精神，找到 shortcuts 來巧妙解決。Hacker 精神不只用在程式設計上，今年，Hack Your Life，創業去。
      
   </content>
</entry>
<entry>
   <title>Mokoversity 農場計畫 Hackathon</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/12/mokoversity-hackthon.html" />
   <id>tag:www.jollen.org,2014:/blog//2.841</id>
   
   <published>2014-12-22T04:36:32Z</published>
   <updated>2014-12-22T10:52:08Z</updated>
   
   <summary> 圖：Joker 跟大家分享 The Execution Premier 的讀書心得 Mokoversity 農場計畫進入到第六週的關鍵時刻，也是 ABC of XYZ 的 Stage B。 這個階段是一個 close door 的 hackathon，農場計畫的碼農們（coders）利用週末的二天時間，討論 strategy change agenda，並且 coding 自已的 prototype，為將來的 startup 做好準備工作。大家在一起 Coding Dreams，是一個很愉快的經驗。 這次的 hackathon 還有一個重要目的，就是展示 Web trends 2015 的重要技術。所以，我就以 mokoversity.com 當例子，從 strategy...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<img src="http://i.imgur.com/HtyMT08.jpg" width="800" />
圖：Joker 跟大家分享 The Execution Premier 的讀書心得

Mokoversity 農場計畫進入到第六週的關鍵時刻，也是 ABC of XYZ 的 Stage B。

這個階段是一個 close door 的 hackathon，農場計畫的碼農們（coders）利用週末的二天時間，討論 strategy change agenda，並且 coding 自已的 prototype，為將來的 startup 做好準備工作。大家在一起 Coding Dreams，是一個很愉快的經驗。

這次的 hackathon 還有一個重要目的，就是展示 Web trends 2015 的重要技術。所以，我就以 mokoversity.com 當例子，從 strategy change agenda 的角度，說明 mokoversity.com 重構的目標，包含中期策略與想法。

明年的 Web 技術發展，會進入到非常關鍵的時期，無論是新產品開發、創業、App 設計等，將會有很大的改變。在農場計畫第六週的「Web Trends 2015」課程中，為大家整理並分析了一些 Web trends；在 hackahton 期間，經由實際重構 mokoversity.com 的過程，讓大家看見新技術的特性、設計與架構。

<img src="http://i.imgur.com/6mfQz16.png" width="800" border="1" />

Mokoversity 重構後的新網站已經上線了，新首頁的背後，是這些技術：

1. 使用 Virtual Dom
2. 檢視了 Backbone Model 的 immutable data structure
3. 討論 SPA 與 immutable data structure 的設計與觀念
4. Mutable 與 Immutable 的 MVC 框架效能
5. 以 Underscore template 建立 virtual tree (vtree)
6. UI composition 與 composition boundary 實作
7. Subtree 的 diff 與 patch
8. 以 MVVM 設計軟體架構
9. Multiple data model 的設計與實作
10. 使用 Browserify 與 CommonJS
11. 提到了 ES6
12. Finite Stata Machine 與 UI interactivity
13. 使用了 Constructor pattern、prototype pattern 與 facade pattern

大家在 2014 的歲末，都儲備好 2015 的技術能量了。雖然我的 hackahton 任務，只是重構首頁的小題目，但對自已來說，卻是很充實的學習過程。

另外，雖然經過一些分析後，暫時不打算採用 React，但這是一個重要的 Web trends。Web trends 2015 年的設計主軸仍是 SPA，但技術上有許多不同。特別的是，這些技術已經開始進入到 sensor hardware 領域。

明年開始，Mokoversity 農場計畫，將開始供應 IoT 的內容。從 SPA + IoT 的角度，讓 Maker 打造更有趣的作品。歡迎到 www.mokoversity.com 了解農場計畫。]]>
      
   </content>
</entry>
<entry>
   <title>農場計畫 Week #1：Behavior-Driven Development</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/11/mokoversity-farm-1.html" />
   <id>tag:www.jollen.org,2014:/blog//2.840</id>
   
   <published>2014-11-19T08:13:17Z</published>
   <updated>2014-11-19T14:42:53Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫（why?），若無法閱讀內文，請點擊這裡。 ## Abstract Behavior-Driven Development（BDD）是以故事情節做為基礎，因此 BDD 的核心在 user story。從 user story 來發展 software prototype 的過程可以單純是 coding，並且使用開發者界的手法「code is document」，來讓代碼與文件合而為一。Code is document 的關鍵，首先取決於二個層面： * 代碼品質（code quality） * 專案管理（Git） 現在是一個軟體開發的先進時代，只要代碼品質夠好，它就是一份文件，所以你不必要另外花時間，就只是為了寫 Documentation。好的開發者，閱讀 code is document 的效率，是讀傳統文字文件的數十倍。 有了 code is document 的觀念，就可以明白為什麼在完成一個 user...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/11/mokoversity-farm-1.html" target="_blank">why?</a>），若無法閱讀內文，請點擊<a href="http://www.jollen.org/blog/2014/11/mokoversity-farm-1.html">這裡</a>。

<script id='markdown', type='text/plain'>

## Abstract

Behavior-Driven Development（BDD）是以故事情節做為基礎，因此 BDD 的核心在 user story。從 user story 來發展 software prototype 的過程可以單純是 coding，並且使用開發者界的手法「code is document」，來讓代碼與文件合而為一。Code is document 的關鍵，首先取決於二個層面：

* 代碼品質（code quality）
* 專案管理（Git）

現在是一個軟體開發的先進時代，只要代碼品質夠好，它就是一份文件，所以你不必要另外花時間，就只是為了寫 Documentation。好的開發者，閱讀 code is document 的效率，是讀傳統文字文件的數十倍。

有了 code is document 的觀念，就可以明白為什麼在完成一個 user story 後，就可以直接撰寫程式碼、製作第一個 Prototype。這是又直接、又有效率的做法：user story -> prototype。

要測試這個 prototype，可以想辦法將 user story 直接轉化（code generation）為測試步驟（step definitions）。以上介紹的 user story 與 step definitions，可以透過一些 BDD framework 工具來實現。

cucumber 是目前很受歡迎的 BDD framework，它採用 Gherkin 語法來撰寫 user story，並且將 user story 編譯為 step definitions 的 code stub（程式碼骨架）。

## User Story

用「故事情節」的方式，來表達、描述與表現你的功能（features），而不是用規格（spec）的方式。如果你想知道什麼叫「規格描述」，台灣 ODM / OEM 廠裡，應該隨地都可以撿到這種文件。

這個部份，BDD 用到很多方式跟軟體工具，不過從 Startup 的角度來看，其實一開始採用 story board  的方式，再搭配一段 story template 就夠了。一份典型的 story template 如下：

```
In Order To <biz value is derived>
As a <role>
I want <some feature> 
```

從這個 template 的句型來看，story 的敍述應該是「value first」，而不是 function first。一份簡單的 user story 可以極簡到使用「記事本」來撰寫，不過，為了易於管理，選用一個適合的 BDD 寫作架構還是有必要的。

## Cucumber and Gherkin

Cucumber[1] 是目前頗受歡迎的寫作框架，它原本是為 Ruby 語言所打造，不過現在也有 JavaScript 的版本：cucumber-js[2] 。Cucumber 採用 Gherkin 語法來描述 user story。Gherkin 語法所描敍出來的文件結構稱為 'Give-When-Then[3]'，這裡有一個簡單的例子：

```
 1 #
 2 # features/unsplash.feature
 3 #
 4 
 5 Feature: Unsplash feature
 6   As a traveler of photographer
 7   I want to post photos on website
 8   So that I can share with my excitings
 9 
10   Scenario: Post photo
11     Given User login
12     Given Use Facebook account
13     When Interact with upload element
14     Then You see the photo
```

以 user story 來表示 spec 是 BDD 的核心精神。同樣地，你可以用記事本、用自已的語意來撰寫 user story，然後用瀏覽器，以及「工人瀏覽」方式來測試。但有一個 BDD 框架，還是最省時省力的。

Cucumber-js 就提供了這樣的測試框架。要測試你的 features，要再加入二個東西：

* Support files
* Step definitions

Support files 要定義一個 *World* 類別，裡面要實作 *visit* method。Step definitions 就是測試 user story 的步驟，這個部份的程式碼骨架，可以透過 cucumber-js 來產生。

以下是 support files 與 step definitions 的例子，下一個階段再說明程式碼實作細節。

## Support Files

```
 1 // test/features/support/world.js
 2 
 3 module.exports = function() {
 4   var zombie = require('zombie')
 5     , HTML5  = require('html5');
 6 
 7   this.World = function World(callback) {
 8     this.browser = new zombie.Browser(/* {runScripts:true, debug:false, htmlParser:  HTML5} 
 9 */);
10 
11     this.page = function(path) {
12      return "http://localhost:3000" + path;
13     };
14 
15     this.visit = function(path, callback){
16       this.browser.visit( this.page(path), function(err, browser, status) {
17         callback(err, browser, status);
18       });
19     };
20 
21     callback(); // tell Cucumber we're finished and to use 'this' as the world instance
22   };
23 };
```

## Step Definitions

```
 1 // test/features/support/world.js
 2 'use strict';
 3 
 4 module.exports = function() {
 5   var zombie = require('zombie')
 6     , HTML5  = require('html5');
 7 
 8   this.World = function World(callback) {
 9     this.browser = new zombie.Browser(/* {runScripts:true, debug:false, htmlParser: HTML5} 
10 */);
11 
12     this.page = function(path) {
13      return "http://localhost:3000" + path;
14     };
15 
16     this.visit = function(path, callback){
17       this.browser.visit( this.page(path), function(err, browser, status) {
18         callback(err, browser, status);
19       });
20     };
21 
22     callback(); // tell Cucumber we're finished and to use 'this' as the world instance
23   };
24 };
```

## 實作

實作的方式當然是使用 HTML5 技術，也就是 HTML5/CSS/JS。從能力上來看，Full Stack Web Development 的技能是必備的。雖然 Full Stack Web Developer 的工作看似包山包海，要學習的主題也很廣泛，但有架構思維，也有主軸的話，其實學習可以很有效率；否則，學習再多，都是「碎片化」的學習方法，感覺學到或看過的東西很多，但每一種都只有「Hello World」等級。

這裡提到的架構思維就是 Single-Page Application - SPA。

## Feature: Unsplash Story

一份 .feature 檔描敍一個 user story。底下是一個例子，故事的主題叫做「Unsplash」。

```
 1 #
 2 # test/features/unsplash.feature
 3 #
 4 
 5 Feature: Unsplash feature
 6   In order to share my enjoys
 7   As a traveler of photographer
 8   I want to post photos on website
 9 
10   Scenario: Post photo
11     Given User login
12     When Interact with upload element
13     Then I should see "my photo"
14 
15   Scenario: Slideshow
16     Given The latest photo gallery
17     When Tap to next photo
18     Then I see one photo
19       And Full page
```

第 5 行的「Feature:」是 Gherkin 的語法，說明故事標題。標題底下的縮排區段，是故事敍述，請使用先前介紹的 user template 句型，來寫故事：In order to ... As a ... I want ...。

緊接著用「Scenario:」語法，來定義「功能」。Scenario 的寫法是使用「Given-When-Then」句型：

* Given：系統的狀態，例如：User login，表示系列要處在登入狀態
* When：使用者的動作，例如：Interact with upload element，表示使用者與上傳介面互動
* Then：outcomes，也就是輸出。例如：I should see "my photo"，表示畫面顯示使用者上傳的照片

一個 user story 可以包含數個 scenario，也就是多個功能。除此，Gherkin 也有「And, But」語法，例如第 18-19 行。Unsplash story 的 prototype：

http://innoboard.cc/unsplash

## Feature: Slidenow Story

設計一個使用 Markdown 語法的簡報服務，力求極簡易用。

```
 1 #
 2 # test/features/slidenow.feature
 3 #
 4 
 5 Feature: Slidenow feature
 6   In order to lively introduce something
 7   As a coder, developer and instructor
 8   I want to make slides in Markdown
 9 
10   Scenario: Read slides
11     Given Landing page showing slides items
12     When Click the slide item
13     Then I should see full screen "slide"
14 
15   Scenario: Submit a slide
16     Given The submit page
17       And User login
18     When Commit markdown document
19     Then I send a new slide
20       And Use CC4.0 license
```

Prototype 實作：

http://booklog.io

## 特別說明：Solution Storyboard vs User Story

Solution Storyboard（或簡稱 Story Board）是 101 Design Methods 的一個流程，一般是採用漫畫的方式呈現。這是非常有幫助的設計思考方法，細節請看 Leon 老師的摘要文件；以及 101 Design Methods 的 Model 6.7。

Story board 的範例說明裡，將 Mokoversity Farm 的思考，製作成簡報後，再實作為 landing page。但是請注意，這個 landing page 呈現的是一份「簡報」；但 user story 要實作的是 Prototype（App）。

Leon 老師在 hackpad 有一份 story board 說明，這個例子先將想法做成簡報（Presentation），再將簡報內容實作為  landing page。請注意，這份 landing page 是 idea 的「簡報」，而不是 idea 的實作。

同時也要注意，BDD 的 user story 屬於軟體工程的一環，它的目標是書寫 Scenario（也就是軟體功能），然後實作 prototype；BDD 不是用來製作 business plan 簡報的方法論，所以不能把 BDD 的 user story 跟 Design Thinking 或 Lean Startup 畫上等號。實際上，BDD 的 user story 是屬於數學上的 finite state machine（FSM）。

BDD 的 User story 要達到的目的是實作，也就是想法的實作；即 Prototype。

## 關於 Mokoversity 農場計畫

Mokoversity 農場計畫（Farm Team）是一個 Pre-Startup 的訓練場（Play Ground）。在農場裡可以學習 Coding、打造 Prototype 與建構 Entrepreneur Mindset，這裡更是一個 Entrepreneur 黃金圏（Golden Circle）。更多資訊，請訪問：[https://www.mokoversity.com/farm/zh-tw](https://www.mokoversity.com/farm/zh-tw)


## References

[1]: http://cukes.info

[2]: https://github.com/cucumber/cucumber-js

[3]: Given When Then, https://github.com/cucumber/cucumber/wiki/Given-When-Then

[4]: BDD in JavaScript: CucumberJS, http://custardbelly.com/blog/blog-posts/2014/01/08/bdd-in-js-cucumberjs/

</script>]]>
      
   </content>
</entry>
<entry>
   <title>Frontend Engineering－認識 Single Page Application（SPA）</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/09/single-page-application.html" />
   <id>tag:www.jollen.org,2014:/blog//2.839</id>
   
   <published>2014-09-18T17:06:21Z</published>
   <updated>2014-09-18T22:30:16Z</updated>
   
   <summary>想開始學網站製作嗎？先看看這篇文章，認識「網站製作」：不只是寫寫 HTML 文件。 關於 Single Page Application（SPA）的討論，較早的學術文章，可以追溯到由 Delft University of Technology 的 Software Engineering Research Group，所發表的一份技術報告：Migrating Multi-page Web Applications to Single-page Ajax Interfaces[1]。Ali Mesbah 與 Arie van Deursen 在這份 2006 年的技術報告裡，提出一個很重要的問題： &quot;web applications have suffered from poor interactivity and responsiveness...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="HTML5 &amp; JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[想開始學網站製作嗎？先看看這篇文章，認識「網站製作」：不只是寫寫 HTML 文件。

關於 Single Page Application（SPA）的討論，較早的學術文章，可以追溯到由 Delft University of Technology 的 Software Engineering Research Group，所發表的一份技術報告：Migrating Multi-page Web Applications to Single-page Ajax Interfaces[1]。Ali Mesbah 與 Arie van Deursen 在這份 2006 年的技術報告裡，提出一個很重要的問題：

"web applications have suffered from poor interactivity and responsiveness towards end users"

這個問題來自傳統的 Web Site 設計模式：「Multi-page」。為解決「poor interactivity and responsiveness」的問題，Single Page Application（以下簡稱 SPA）的設計模式（model）就被提出。從軟體工程（Software Engineering）的角度來看，SPA 必須有一個軟體框架，讓開發者以這個框架為基礎，來進行 Web Site 的開發；從這裡，可以很容易歸納出 2 個結論：

1. 傳統的 Web Site 採取多頁式（Multi-page）做法

2. 現在的 Web Site 開始轉移到 SPA 的觀念，採單頁式（Single-page）做法

從 Multi-page 到 Single-page，不只是將多個頁面，拼成一個頁面而已，而是提供 User 更偏向 Desktop application 的使用經驗[2]。實際上，將 Single-page 看做「把多個頁面組成一頁就好」是錯誤的觀念。怎麼讓 Single-page 的使用經驗，更像是 Desktop application 呢？第一個步驟，就是要把 UI 從 Server-side 移到 Client-side；第二個步驟，在 Client-side 實作 Application Logic。

這二個步驟就是學習 SPA 的第一課。學習 SPA 最好的方式，就是選擇一套適合自已的 SPA 框架，經由學習這個框架的過程，來理解上述這二個步驟的意義。SPA 觀念的提出，源自 AJAX 技術的流行；這麼多年來，有非常多能幫助我們實作 Single-page 的技術，甚致只用 jQuery AJAX 也可以做出 SPA。使用 jQuery AJAX 是一個做法，而且不需要學習像是 Backbone.js 或 AngularJS 的框架，但前提是，你要能接受不斷長高的 Callback Hell。當然，也有人把 Callback Hell 當做一個藝術，而樂此不彼。

無論如何，選擇一套 SPA 框架是比較建議的做法。好消息是，現在有許多優雅好用的方案，上述提及的 Backbone.js 與 AngularJS 是當中最知名的框架。

如果你不想殺雞用牛刀，也喜歡 Callback Hell 的自然美，其實可以在 Backbone.js（或其它框架）或 AJAX 之間做選擇。但差別在哪裡呢？以 Backbone.js 為例，它提供一些重要的機制：

1. Client-side URL Routing

2. Data Model

3. Model State

4. 整合 REST API

5. etc.

現在 Frontend 都要整合 REST API，所以使用 Backbone.js 會讓開發工作更便利、也更簡省時間。

O'Reilly 不久前出版了一本書，書名為：Developing Backbone.js Applications－Building Better JavaScript Applications[3]，更是直接了當地介紹，如何使用 Backbone.js 來製作 Single-page Application (SPA) Model 的 Web Frontend。

另外，只有平面設計的技能，現在並不足以幫助我們製作 SPA；換個角度來說，Frontend 製作，並不是用 Photoshop 等平面設計的工具，將設計好的 UI 製作成 HTML 文件。Frontend 與 Art Design 工作內容不同。比如說，Frontend 需要以 JavaScript 來撰寫 Application Logic，或是呼叫 REST API；正因為 Frontend 開發需要整合 REST API，所以最好能懂一點 Backend 的知識。這就是為什麼近年來，Full Stack 開發受到重視的原因。Art design 的工作可能只涉及美術設計。

最後，Frontend 的製作，並不是規定一定要使用 Single-page 的模式，但是從 User Experience 的角度來看，讓 Frontend 的操作就像是 Desktop Application，似乎是一個很棒的選擇。如果 Frontend 的 User Experience 就像是 Desktop Application，更可以使用打包工具，將 Web Frontend 打包成手機 App，還可以上架到商店。網站製作，已經不是以前的網站製作觀念了。所以，想要學習網站製作嗎？不如直接以 SPA 模式，開始你的第一個 Web Site 吧。

<h2>參考資源</h2>

[1]: Migrating Multi-page Web Applications to Single-page Ajax Interfaces, http://arxiv.org/pdf/cs/0610094v2.pdf

[2]: Single-page application, http://en.wikipedia.org/wiki/Single-page_application

[3]: Developing Backbone.js Applications, http://shop.oreilly.com/product/0636920025344.do
]]>
      
   </content>
</entry>
<entry>
   <title>Node.js 入門, #10：認識 JSON Stringify</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/07/nodejs-json-stringify.html" />
   <id>tag:www.jollen.org,2014:/blog//2.836</id>
   
   <published>2014-07-23T13:37:01Z</published>
   <updated>2014-07-23T18:37:28Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫（why?），若無法閱讀內文，請點擊這裡。 ## JSON Stringify 請注意，上述的 JSON 是一個型別（Type），是一個 Array Type。我們不能儲存或傳送「Type」，所以要將 Type 轉成字串（String）後，才能儲存或傳送。例如，對電腦來說，這是一個物件（Object）： ``` { &quot;name&quot;: &quot;James&quot; } ``` 我們把這個物件轉成字串： ``` &quot;{ \&quot;name\&quot;: \&quot;James\&quot; }&quot;&quot; ``` 對電腦來說，這才是字串。所以，將 JSON 物件（Object）轉成字串後，才能儲存或傳送。這個動作就叫 JSON Stringify（字串化）。當然，字串化過的 JSON 字串，要使用時，也要解析（Parse）回物件。 在 Node.js 裡如何做 JSON Stringify 呢？只要呼叫 JSON.stringify()...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Node.js &amp; RESTful" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法閱讀內文，請點擊<a href="http://www.jollen.org/blog/2014/04/nodejs-getting-started-2.html">這裡</a>。

<script id='markdown', type='text/plain'>

## JSON Stringify

請注意，上述的 JSON 是一個型別（Type），是一個 Array Type。我們不能儲存或傳送「Type」，所以要將 Type 轉成字串（String）後，才能儲存或傳送。例如，對電腦來說，這是一個物件（Object）：

```
{ "name": "James" }
```

我們把這個物件轉成字串：

```
"{ \"name\": \"James\" }""
```

對電腦來說，這才是字串。所以，將 JSON 物件（Object）轉成字串後，才能儲存或傳送。這個動作就叫 JSON Stringify（字串化）。當然，字串化過的 JSON 字串，要使用時，也要解析（Parse）回物件。

在 Node.js 裡如何做 JSON Stringify 呢？只要呼叫 JSON.stringify() 函數即可。例如：

```
var obj = { "name": "James" };    // 一個物件
var str = JSON.stringify(obj);    // 字串化
```

下面是簡約的寫法：

```
var str = JSON.stringify({ "name": "James" });    // 字串化
```

沿續先前的範例，將 requestHandler.js 加入 JSON Stringify 的處理。完整程式碼如下：

{title="07-websocket-data-push/requestHandler.js"}
```
// 07-websocket-data-push/requestHandler.js
 1 var querystring = require('querystring'); 
 2 
 3 /**
 4  * Global variables
 5  */
 6 var history = [ ];
 7 
 8 function start(response, query, clients) {
 9     console.log("Handler 'start' is started.");
10     console.log("Query string is: " + query);
11 }
12 
13 function send(response, query, clients) {
14     console.log("Handler 'send' is started.");
15     console.log("Query string is: " + query);
16 
17     var parsedstring = querystring.parse(query); 
18 
19     var obj = {
20         message: parsedstring.m,
21         username: parsedstring.u,
22         timestamp: (new Date()).getTime()
23     };
24 
25     history.push(obj);
26 
27     //////// DEBUG ////////
28     for (var i = 0; i < history.length; i++) {
29         console.log("["+i+"]: " + history[i].message);
30     }
31 
32     var json = JSON.stringify({ type: 'message', data: obj });
33 
34     // Data push to all clients
35     for (var i = 0; i < clients.length; i++) {
36         clients[i].sendUTF(json);
37     }
38 }
39 
40 exports.start = start;
41 exports.send = send;
```

第 19 行到第 23 行，將訊息封裝到物件裡，同時也加入使用者名稱，以及時間戳記（Timestamp）。第 32 行將物件字串化，這就是一個標準的 JSON 資枓了。接著，第 35 行到第 37 行，將這筆 JSON 資料，傳送給所有的 WebSocket Client 端。

</script>]]>
      
   </content>
</entry>
<entry>
   <title>Node.js 入門, #9：學習 JSON 格式</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/07/nodejs-json.html" />
   <id>tag:www.jollen.org,2014:/blog//2.835</id>
   
   <published>2014-07-23T13:35:28Z</published>
   <updated>2014-07-23T18:35:52Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫（why?），若無法閱讀內文，請點擊這裡。 ## 學習 JSON 格式 思考將要製作的 NoChat 聊天室範例，Server 要把收到的訊息，Push 給所有的 Client 端。Server 與 Client 所使用的標準資料交換格式，就是 JSON。如何把訊息打包成 JSON 格式？方式非常簡單。以表 2 為例，要將這個資料表，撰寫為 JSON 格式，只需要二個步驟： ## Step 1：以 JavaScript 物件表示一筆資料 例如，第一筆個人資料，以 JavaScript 物件來表示的話，只要用 *var* 來宣告此物件即可： ~~~~~~~~ var obj = { &quot;name&quot;:...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Node.js &amp; RESTful" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法閱讀內文，請點擊<a href="http://www.jollen.org/blog/2014/04/nodejs-getting-started-2.html">這裡</a>。

<script id='markdown', type='text/plain'>

## 學習 JSON 格式

思考將要製作的 NoChat 聊天室範例，Server 要把收到的訊息，Push 給所有的 Client 端。Server 與 Client 所使用的標準資料交換格式，就是 JSON。如何把訊息打包成 JSON 格式？方式非常簡單。以表 2 為例，要將這個資料表，撰寫為 JSON 格式，只需要二個步驟：

## Step 1：以 JavaScript 物件表示一筆資料

例如，第一筆個人資料，以 JavaScript 物件來表示的話，只要用 *var* 來宣告此物件即可：

~~~~~~~~
var obj = {
  "name": "Jollen",
  "score":  80
};
~~~~~~~~

大括號是 JavaScript 表示物件的語法。上述範例，我們宣告了 *obj* 物件。

## Step 2：轉換成標準 JSON 語法

去掉等號，以及等號左邊的物件宣告，結果如下：

~~~~~~~~
{
  "name": "Jollen",
  "score":  80
}
~~~~~~~~

請注意，結尾的分號也要一併去除。上述的表示方法，就是標準的 JSON 語法。這個例子用 JSON 來表示一筆個人資料。JSON 表示方法非常地簡單，只要會 JavaScript 保證 1 分鐘即可上手，不需要特意學習。

## Step 3：用陣列表示多個物件

|"name" 欄位    |"score" 欄位   |說明     | 
|==============|==============|==============|
|"Jollen"      |80             |第 1 筆使用者資料|
|"Paul"        |170            |第 2 筆使用者資料|
|"Peter"       |250            |第 3 筆使用者資料|
|"Ellaine"     |580            |第 4 筆使用者資料|

表 2 資料表

表 2 共有 4 筆個人資料，因此需要撰寫 4 個物件，每個物件之間用逗號隔開。試想，過去撰寫程式的經驗裡，我們用哪一個資料結構（Data Structure）來表示多筆型別（Data Type）相同的資料呢？答案是：陣列（Array）。

JavaScript 的陣列用中括號來宣告，例如：

~~~~~~~~
var string = ['Jollen', 'Paul', 'Peter'];
~~~~~~~~

這個例子宣告 *string* 陣列，裡頭有 3 個字串。用 JavaScript 怎麼表示 4 個物件的陣列呢？答案如下：

~~~~~~~~
var persons = [
  {
    "name": "Jollen",
    "score": 80
  },
  {
    "name": "Paul",
    "score": 170
  },
  {
    "name": "Peter",
    "score": 250
  },
  {
    "name": "Ellaine",
    "score": 580
  }
];
~~~~~~~~

我們只要把上述的 4 個物件，用陣列「群組」起來即可。和 Step 2 相同，保留以下的寫法即可：

~~~~~~~~
[
  {
    "name": "Jollen",
    "score": 80
  },
  {
    "name": "Paul",
    "score": 170
  },
  {
    "name": "Peter",
    "score": 250
  },
  {
    "name": "Ellaine",
    "score": 580
  }
]
~~~~~~~~

這就是表 2 的 JSON 表示方式了。將上述的 JSON 儲存為純文字，這個純文字檔就叫做 JSON Document，這就是 JSON Document 資料庫的概念。

同理，NoChat Server 收到訊息後，只要把訊息表示成 JSON 後，傳送給 Client 端即可。JSON 相當簡單易學，更是優秀的輕量級資料交換格式。

</script>]]>
      
   </content>
</entry>
<entry>
   <title>Node.js 入門, #8：認識 JSON 與 Web App 的概念</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/07/nodejs-json-web-app.html" />
   <id>tag:www.jollen.org,2014:/blog//2.834</id>
   
   <published>2014-07-23T13:26:53Z</published>
   <updated>2014-07-23T18:32:00Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫（why?），若無法閱讀內文，請點擊這裡。 ## Web-Oriented Architect Web 導向架構（WOA, Web-Oriented Architect）著重幾個觀念： - Device-Server 設計模式 - Device 端使用 Browser，以 Browser 做為執行環境（Runtime） - Server 端提供 APIs，即 PaaS 概念 - Device-Server 採用非同步通訊（Asynchronous communication） 事實上，非同步通訊大家都使用過，就是 AJAX；AJAX 的第一個 A 就是 Asynchronous。但是考量 Server 端的負載（Loading），以及百萬連線（Millions requests）等級的處理能力需求，應該儘量少用 AJAX 機制。這就是...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Node.js &amp; RESTful" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法閱讀內文，請點擊<a href="http://www.jollen.org/blog/2014/04/nodejs-getting-started-2.html">這裡</a>。

<script id='markdown', type='text/plain'>

## Web-Oriented Architect

Web 導向架構（WOA, Web-Oriented Architect）著重幾個觀念：

- Device-Server 設計模式
- Device 端使用 Browser，以 Browser 做為執行環境（Runtime）
- Server 端提供 APIs，即 PaaS 概念
- Device-Server 採用非同步通訊（Asynchronous communication）

事實上，非同步通訊大家都使用過，就是 AJAX；AJAX  的第一個 A 就是 Asynchronous。但是考量 Server 端的負載（Loading），以及百萬連線（Millions requests）等級的處理能力需求，應該儘量少用 AJAX 機制。這就是 Device-Server 與 Client-Server 的差別，大家可能還不太明白。所以，將二者的差別簡單整理如下：

- Client-Server 做法：在瀏覽器裡（Client）主動向 Server 請求內容，Client 定時（如：每隔5秒鐘）發出請求，持續更新內容。
- Device-Server 做法：在裝置端（Device）和 Server 建立連線，Server 主動將更新內容推送（Push）給裝置端，更明確地說，裝置裡的瀏覽器，瀏覽器再將新內容刷新。

這樣就很清楚了，傳統的 Client-Server 做法是「Data Pull」，即主動去拉資料；Device-Server 的做法是「Data Push」，即推送資料，由 Server 在必要時才將資料推送給 Device。Data Push 的經典代表作就是 BlackBerry（黑莓機）的郵件服務。

為什麼 AJAX 不好用？因為 Server 要冒著「不知道有多少 Client、不知道同時有多少 Requests」的風險，會增加 Load Balancer 佈署的成本；另外，當然就是即時性的問題（Live Streamming）。要達成 Data Push 的目的，有解決二個技術問題：

- Device 端要與 Server 建立永續性（Persistent）連線，也就是 Socket Connection
- Server 推送出去的資料，格式要有統一標準，且輕量化

要解決這二個問題，要使用到二項技術：WebSocket 與 JSON。從以上的說明，可以大略了解 HTML5 的威力在於「Web App」的應用領域，而不只是 Web Page 的製作：

- 從 Web Page 角度來看，以 Client-Server 為主，這像是傳統 PC 時代的使用案例
從 Web App 角度來看，將 Device-Server 為主

- Web App 的開發思惟，與 Web Page 有很大的不同。目前 Web App 的 UI 製作，採是強調跨螢幕與裝置的特性，這種設計稱為 Responsive Design。並且，Responsive Design 進向以行動裝置為預設值的做法，也就是「Mobie First」


## Web App 技術

從 Web App 的角度看 HTML5，以下是初學者可考慮優先切入學習的技術：

- PhoneGap：Device API 的標準，使用 JavaScript 呼叫 Device API 的好技術，Nitobi 公司是 PhoneGap 的開發商，這家公司現已被 Adobe Systems 收購

- WebSocket：HTML5 標準裡的一個技術

- Node.js：開發專用 Web Service 的技術，採用 JavaScript 語言

Apache Web Server 是通用型的 Web Server，主要提供頁面（Pages）服務。Node.js 則是 Web Service 的技術，用來開發專用的 Web Service APIs。

現在開發專用的 Web Service 非常重要，這是 PaaS 的靈魂。例如，開發股票報價專用 Web Server。過去常聽到的 Web Server，例如：Apache，都是一般用途的 Web Server，用來「host Web pages」。

現在 Client 端的網頁是用 JavaScript，Server 端的開發也可以用 JavaScript，Client/Server 通通都用 JavaScript，這是一個「All in JavaScript」的時代。


## 重要的資訊交換格式：JSON

傳統 Backend 的做法，會提供 Client 端一份 HTML5 的片斷文件，而不是格式化後的資料（Formatted），這是一個缺點。

如果 Server 回傳的是格式化後的資料，Client 端就可以更有效率地利用這些資料。試想，如果 Google 傳回的搜尋結果是一堆 HTML5，那我們不就還要再去 Parse 這份文件，才能取出真正的結果，然後才能再次利用這些資料（例如：再儲存為 CVS 格式）。

為了解決這個問題，必須要有一個標準，不能大家都用自已的 HTML5 文件，或是自定的格式。軟體工程師設計了一些標準。一開始提出的做法，是制定標準的XML標籤，這樣大家就可以統一文件格式了。但是還有一個問題，就是「資料量太大」。

試想，Server 要回傳二筆資料，這二筆資料都是電話號碼：

- 0911-111-111
- 0900-000-000

然後用XML來表示，就變成：

```
<Telephone>
   <Item>0911-111-111</Item>
   <Item>0900-000-000</Item>
</Telephone>
```

這種把資料打腫了才回傳的做法，大大浪費網路頻寬。上面只是一個簡單的例子，現實環境，要回傳的資料可能是一個 10MB 的 XML 文件，結果原始資料可能只有 1MB。

要解決這個問題，就要有一個輕量級（Light-weight）的資料交換格式，這項技術就是 JSON。所以，JSON 是 Client/Server 交換資料的一種格式，一種 Light-weight data exchange 技術。


</script>]]>
      
   </content>
</entry>
<entry>
   <title>Node.js 入門, #7：儲存用戶端 WebSocket 連線</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/07/nodejs-websocket-connections.html" />
   <id>tag:www.jollen.org,2014:/blog//2.833</id>
   
   <published>2014-07-23T13:18:38Z</published>
   <updated>2014-07-23T18:19:08Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫（why?），若無法閱讀內文，請點擊這裡。 ## 儲存用戶端 WebSocket 連線 要儲存所有的用戶端 WebSocket 連線，最簡便的方式是使用 Global Array： ``` // Connected WebSocket clients var clients = []; ``` 當用戶端與 Node.js 建立連線時，將會回呼上述提及的 onWsRequest() 函數。所以，儲存連線的程式碼，應該添加至這個地方。繼續加入程式碼如下： ``` function onWsRequest(request) { var connection = request.accept(&apos;echo-protocol&apos;, request.origin); console.log(&quot;WebSocket connection accepted.&quot;); //...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Node.js &amp; RESTful" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法閱讀內文，請點擊<a href="http://www.jollen.org/blog/2014/04/nodejs-getting-started-2.html">這裡</a>。

<script id='markdown', type='text/plain'>

## 儲存用戶端 WebSocket 連線

要儲存所有的用戶端 WebSocket 連線，最簡便的方式是使用 Global Array：

```
// Connected WebSocket clients
var clients = [];
```

當用戶端與 Node.js 建立連線時，將會回呼上述提及的 onWsRequest() 函數。所以，儲存連線的程式碼，應該添加至這個地方。繼續加入程式碼如下：

```
function onWsRequest(request) {
  var connection = request.accept('echo-protocol', request.origin);
  console.log("WebSocket connection accepted.");

  // Save clients (unlimited clients)
  clients.push(connection);

  connection.on('message', onWsConnMessage);
  connection.on('close', onWsConnClose);
}
```

以下目前為止的最新程式碼。

```
// 07-websocket-data-push/server.js
 1 var http = require("http");
 2 var url = require("url");
 3 var WebSocketServer = require('websocket').server;
 4 
 5 // Connected WebSocket clients
 6 var clients = [];
 7 
 8 function start(route, handlers) {
 9   function onRequest(request, response) {
10     var pathname = url.parse(request.url).pathname;
11     var query = url.parse(request.url).query;
12 
13     console.log("Request for " + pathname + " received.");
14 
15     route(pathname, handlers, response, query, clients);
16 
17     response.writeHead(200, {"Content-Type": "text/plain"});
18     response.write("Hello World");
19     response.end();
20   }
21 
22   var server = http.createServer(onRequest).listen(8080, function() {
23      console.log("Server has started and is listening on port 8080.");
24   });
25 
26   wsServer = new WebSocketServer({
27     httpServer: server,
28     autoAcceptConnections: false
29   });
30 
31   function onWsConnMessage(message) {
32     if (message.type == 'utf8') {
33       console.log('Received message: ' + message.utf8Data);
34     } else if (message.type == 'binary') {
35       console.log('Received binary data.');
36     }
37   }
38 
39   function onWsConnClose(reasonCode, description) {
40     console.log('Peer disconnected with reason: ' + reasonCode);
41   }
42 
43   function onWsRequest(request) {
44     var connection = request.accept('echo-protocol', request.origin);
45     console.log("WebSocket connection accepted.");
46 
47     // Save clients (unlimited clients)
48     clients.push(connection);
49 
50     connection.on('message', onWsConnMessage);
51     connection.on('close', onWsConnClose);
52   }
53 
54   wsServer.on('request', onWsRequest);
55 }
56 
57 // Export functions
58 exports.start = start;
```

接下來的任務是製作 Frontend（Client 端）；不過，現在是一個認識與學習 JSON 的絕佳時機。

</script>]]>
      
   </content>
</entry>
<entry>
   <title>Node.js 入門, #6：撰寫 WebSocket Server</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/07/nodejs-websocket-server.html" />
   <id>tag:www.jollen.org,2014:/blog//2.832</id>
   
   <published>2014-07-23T13:13:18Z</published>
   <updated>2014-07-23T18:16:29Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫（why?），若無法閱讀內文，請點擊這裡。 ## 認識 WebSocket WebSocket 是 HTML5 裡的一個標準，它是一種 TCP/IP 的連線技術。在協定部份，則是基於 HTTP（Over HTTP）協定。因此，WebSocket 標準定義了一些 HTTP Headers 來進行 Client/Server 的通訊。 WebSocket 分為 Client 端與 Server 端二個部份，本章要介紹的是利用 Node.js 技術，來開發 WebSocket Server。 目前有許多現成的 Node.js WebSocket 模組可使用，實作時，我們就不必自行處理複雜的 WebSocket 協定問題。 ## 安裝 WebSocket 模組...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Node.js &amp; RESTful" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法閱讀內文，請點擊<a href="http://www.jollen.org/blog/2014/04/nodejs-getting-started-2.html">這裡</a>。

<script id='markdown', type='text/plain'>

## 認識 WebSocket

WebSocket 是 HTML5 裡的一個標準，它是一種 TCP/IP 的連線技術。在協定部份，則是基於 HTTP（Over HTTP）協定。因此，WebSocket 標準定義了一些 HTTP Headers 來進行 Client/Server 的通訊。

WebSocket 分為 Client 端與 Server 端二個部份，本章要介紹的是利用 Node.js 技術，來開發 WebSocket Server。
目前有許多現成的 Node.js WebSocket 模組可使用，實作時，我們就不必自行處理複雜的 WebSocket 協定問題。

## 安裝 WebSocket 模組

本章所使用的 WebSocket 模組，要使用 npm 工具另外安裝。利用 npm 安裝 WebSocket-Node：

```
 $ npm install websocket
```

WebSocket-Node 原始碼可由 Github 上取得：

https://github.com/Worlize/WebSocket-Node

安裝，依據需要，可引入不同的模組。WebSocket-Node 提供 4 個模組如下：

- var WebSocketServer = require('websocket').server;
- var WebSocketClient = require('websocket').client;
- var WebSocketFrame  = require('websocket').frame;
- var WebSocketRouter = require('websocket').router;

NoChat 範例，將會使用 'server' 模組。

## 建立 WebSocket Server

基於先前的範例，繼續修改 server.js 的程式碼如下：

```
// 06-websocket-with-protocol/server.js
 1 var http = require("http");
 2 var url = require("url");
 3 var WebSocketServer = require('websocket').server;
 4 
 5 function start(route, handlers) {
 6   function onRequest(request, response) {
 7     var pathname = url.parse(request.url).pathname;
 8     var query = url.parse(request.url).query;
 9 
10     console.log("Request for " + pathname + " received.");
11 
12     route(pathname, handlers, response, query);
13 
14     response.writeHead(200, {"Content-Type": "text/plain"});
15     response.write("Hello World");
16     response.end();
17   }
18 
19   var server = http.createServer(onRequest).listen(8080, function() {
20      console.log("Server has started and is listening on port 8080.");
21   });
22 
23   wsServer = new WebSocketServer({
24     httpServer: server,
25     autoAcceptConnections: false
26   });
27 
28   function onWsConnMessage(message) {
29     if (message.type == 'utf8') {
30       console.log('Received message: ' + message.utf8Data);
31     } else if (message.type == 'binary') {
32       console.log('Received binary data.');
33     }
34   }
35 
36   function onWsConnClose(reasonCode, description) {
37     console.log(' Peer disconnected with reason: ' + reasonCode);
38   }
39 
40   function onWsRequest(request) {
41     var connection = request.accept('echo-protocol', request.origin);
42     console.log("WebSocket connection accepted.");
43 
44     connection.on('message', onWsConnMessage);
45     connection.on('close', onWsConnClose);
46   }
47 
48   wsServer.on('request', onWsRequest);
49 }
50 
51 // Export functions
52 exports.start = start;
```

先將 WebSocket-Node 的 'server' 匯入，如程式碼第3行。其它的修改細節條列如下：

- 第 19~26 行：將原本的 HTTP Server 物件，聚合至（傳遞）WebSocket Server。WebSocker Server 的物件名稱為 wsServer
- 第 48 行：在 wsServer 物件裡註冊一個 Request Handler，即 onWsRequest() 函數
- 第 40 行：當 WebSocket 的連線請求發生時，便回呼此函數
- 第 41 行：接受該 WebSocket 連線，第一個參數是 WebSocket Protocol，這是一個自定的協定名稱，用途由開發者定義
- 第 44~45 行：為此連線註冊 Message Handler 與 Close Handler 函數
- 第 28 行：收到用戶端傳送過來的訊息時，回呼此函數，後續將繼續擴充此函數，將收到的訊息儲存，並將訊息即時（Real-time）推送（Push）到所有的用戶端
- 第 36 行：該 WebSocket 連線關閉後，回呼此函數

學會建立 WebSocket Server 後，就可以開始建立與 Client 端的連線了。

</script>]]>
      
   </content>
</entry>
<entry>
   <title>Node.js 入門, #5：解析 Query String</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/07/nodejs-parse-query-string.html" />
   <id>tag:www.jollen.org,2014:/blog//2.831</id>
   
   <published>2014-07-23T13:11:04Z</published>
   <updated>2014-07-23T18:12:20Z</updated>
   
   <summary><![CDATA[本文章採用 Markdown 語法撰寫（why?），若無法閱讀內文，請點擊這裡。 ## 解析 Query String Client 端呼叫 Server 所提供的 Web Service API。所以，現在的關鍵是如何解析 Query String。如圖 2.2，Node.js 使用 querystring 模組來解析 Query String。先將 querystring 模組匯入，接著呼叫 parse() 函數： ``` var querystring = require('querystring'); var parsedstring = querystring.parse(“m=helll&u=jollen”); ``` 解析後的結果存放於 parsedstring 物件，回傳結果： ```...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Node.js &amp; RESTful" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法閱讀內文，請點擊<a href="http://www.jollen.org/blog/2014/04/nodejs-getting-started-2.html">這裡</a>。

<script id='markdown', type='text/plain'>

## 解析 Query String

Client 端呼叫 Server 所提供的 Web Service API。所以，現在的關鍵是如何解析 Query String。如圖 2.2，Node.js 使用 querystring 模組來解析 Query String。先將 querystring 模組匯入，接著呼叫 parse() 函數：

```
var querystring = require('querystring'); 
var parsedstring = querystring.parse(“m=helll&u=jollen”); 
```

解析後的結果存放於 parsedstring 物件，回傳結果：

```
{ m: 'hello', u: 'jollen' } 
```

parse() 函數有三個參數：

```
querystring.parse(str, [sep], [eq])
```

- str 是 Query String
- sep 是「Separator」，也就是字串的分隔字元，預設是 '$'，通常不做變數
- eq 則是字串與值的對應字元，預設是 '='，通常不做變數

了解如何解析 Query String 後，就可以開始進行後續的工程了。再次修改 requestHandlers.js，如下：

```
// 05-query-string/requestHandlers.js
 1 var querystring = require('querystring'); 
 2 
 3 /**
 4  * Global variables
 5  */
 6 var history = [ ];
 7 
 8 function start(response, query) {
 9     console.log("Handler 'start' is started.");
10     console.log("Query string is: " + query);
11 }
12 
13 function send(response, query) {
14     console.log("Handler 'send' is started.");
15     console.log("Query string is: " + query);
16 
17     var parsedstring = querystring.parse(query); 
18 
19     var obj = {
20         message: parsedstring.m,
21         username: parsedstring.u,
22         timestamp: (new Date()).getTime()
23     };
24 
25     history.push(obj);
26 
27     //////// DEBUG ////////
28     for (var i = 0; i < history.length; i++) {
29         console.log("["+i+"]: " + history[i].message);
30     }
31 }
32 
33 exports.start = start;
34 exports.send = send;
```

這裡利用一個全域陣列 *history* 來儲存訊息。將收到的訊息封裝成物件後， 再使用標準的陣列操作將物件放到陣列裡。另外，我們也將一個時間記號（Timestamp）一併封裝至該物件，用來紀錄接收到訊息的時間。

## 結論

到這裡完成了 Node.js 入門的學習：

- 學會撰寫第一個 Node.js 程式
- 學會啟動 HTTP Server
- 了解並實作 URL Routing
- 學會解析 Pathname 與 Query String



</script>]]>
      
   </content>
</entry>
<entry>
   <title>Node.js 入門, #4：認識 HTTP API</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/07/nodejs-http-api.html" />
   <id>tag:www.jollen.org,2014:/blog//2.830</id>
   
   <published>2014-07-23T12:46:53Z</published>
   <updated>2014-07-23T18:10:20Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫（why?），若無法閱讀內文，請點擊這裡。 ## 設計 HTTP API 完整的 NoChat 分為二個部份： - Backend（Server-side）將基於目前的 Node.js 程式碼繼續完善 - Frontend（Client-side）手機端的 App 將以 HTML5 + PhoneGap 來製作 NoChat 提供二個API，現在將 API 詳細定義如下。 - /start，建立與 Client 的 WebSocket 連線 - /send，送出訊息。 &apos;/send&apos; API 的 Query String 參數定義如表...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Node.js &amp; RESTful" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法閱讀內文，請點擊<a href="http://www.jollen.org/blog/2014/04/nodejs-getting-started-2.html">這裡</a>。

<script id='markdown', type='text/plain'>

## 設計 HTTP API

完整的 NoChat 分為二個部份：

- Backend（Server-side）將基於目前的 Node.js 程式碼繼續完善
- Frontend（Client-side）手機端的 App 將以 HTML5 + PhoneGap 來製作

NoChat 提供二個API，現在將 API 詳細定義如下。

- /start，建立與 Client 的 WebSocket 連線
- /send，送出訊息。

'/send' API 的 Query String 參數定義如表 1。這部份在前面已做過說明。

|參數    |值       |用途說明      |
|========|========|=============|
|m      |'hello'  | 指定要傳送的訊息 (message) |
|u      |'jollen' | 指定 Username |

表 1 API 的參數

## 測試案例

以下設計一個簡單的測試案例，在完成第一個 NoChat 的 Prototype 後，將以下列步驟進行測試：

1. 在 localhost 啟動 Node.js

2. 打開 client.html 聊天網頁

3. client.html 呼叫 API：http://localhost:8080/start，Server 回傳 "OK" 訊息

4. client.html 與 Server 建立 WebSocket 連線

5. clieht.html 開始接收 Node.js 推送（Data Push）的即時訊息

傳送訊息給 Node.js 的測試步驟：

1. 開啟一個新的瀏覽器視窗

2. 使用瀏覽器呼叫 API：http://localhost:8080/send?m=hello

3. Node.js 收到訊息，並透過 WebSocket 將訊息 Push 給所有的用戶端

這還不算是一個真正的使用案例(Use Case)，但至少可以幫助我們實作出第一個Prototype。

## 關於 Web Service

前一篇文章中的圖 2.2，是大家所熟悉的 HTTP API 形式。許多網站，像是：Google、Facebook 等，都有開放 HTTP API 供開發者存取它們的服務。以 NoChat 來說，透過上述二個 API 可以向 Server 請求服務。因此，Node.js 的重心，就是在發展 Web Service。

Web Service 的 API 定義，未來將重構為 REST 標準。基於 HTTP 的 Web Service API，是目前為止，我們所學到的重要觀念。

此外，呼叫 HTTP API 的方式，可使用 GET 與 POST 二種 HTTP 方式（HTTP Method），這二種方式都是定義在 HTTP 裡的標準。REST 標準，也引用了其它的 HTTP Method。

目前，NoChat 仍暫時以 Query String 的方式來傳遞參數。

</script>]]>
      
   </content>
</entry>
<entry>
   <title>Node.js 入門, #3：URL Routing 觀念與實作</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/07/nodejs-url-routing-practice.html" />
   <id>tag:www.jollen.org,2014:/blog//2.829</id>
   
   <published>2014-07-23T12:39:01Z</published>
   <updated>2014-07-23T17:45:40Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫（why?），若無法閱讀內文，請點擊這裡。 延續前二篇文章的範例，接著介紹 Node.js 最基本也最重要的觀念－URL Routing。範例網址：https://github.com/jollen/html5-websocket-nodejs ## URL Routing 這是處理 URL（HTTP Request）與 Query String 的核心觀念，這是利用 Node.js 開發 Web Service 的重要步驟。讓我們先來了解 Routing 的寫法，再來探討它的觀念。 首先，先改寫 server.js 模組如下： ``` // 03-route/server.js 1 var http = require(&quot;http&quot;); 2 var url = require(&quot;url&quot;); 3...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Node.js &amp; RESTful" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法閱讀內文，請點擊<a href="http://www.jollen.org/blog/2014/04/nodejs-getting-started-2.html">這裡</a>。

<script id='markdown', type='text/plain'>

延續前二篇文章的範例，接著介紹 Node.js 最基本也最重要的觀念－URL Routing。範例網址：https://github.com/jollen/html5-websocket-nodejs

## URL Routing

這是處理 URL（HTTP Request）與 Query String 的核心觀念，這是利用 Node.js 開發 Web Service 的重要步驟。讓我們先來了解 Routing 的寫法，再來探討它的觀念。

首先，先改寫 server.js 模組如下：

```
// 03-route/server.js
 1 var http = require("http");
 2 var url = require("url");
 3 
 4 function start(route) {
 5   function onRequest(request, response) {
 6     var pathname = url.parse(request.url).pathname;
 7     console.log("Request for " + pathname + " received.");
 8     console.log("Request url: " + request.url);
 9 
10     route(pathname);
11 
12     response.writeHead(200, {"Content-Type": "text/plain"});
13     response.write("Hello World");
14     response.end();
15   }
16 
17   http.createServer(onRequest).listen(8888);
18   console.log("Server has started.");
19 }
20 
21 // Export functions
22 exports.start = start;
```

Routing 觀念的主要用途是處理 URL，所以我們利用 url 模組來取出 URL 裡的 pathname，並將 pathname 交給 route() 函數來處理。這裡很特別的地方是，start() 函數裡所呼叫的 route()函數，是透過參數列傳遞進來的，這和模組的 Closure 特性有關係，觀念說明如下：

- route() 函數實作在 router 模組，而不是 server.js 模組
- 目的是將 Routing 的功能，拆成單獨的模組來維護
- route() 函數由 router.js 模組提供，必須引用 router 模組

在這裡範例裡，我們由 index.js 引入 router.js 模組，並且將裡頭的 router() 函數，透過參數列交給 start()函數。如此一來，start() 也可以呼叫到 route() 函數了。

這個部份，可以選擇另外一個實作方法：在 server.js 裡引用 router.js 模組。不過，就概念上來說，範例的實作方式好一些。原因如下。

- Decompostion：將 router.js 與 server.js 模組的相依性解除
- Component-based software engineering：將 router.js 與 server.js 做成獨立的模組，他們之間如果沒有相依性，就可以做為二個不同的模組來使用。例如，將 router.js 模組抽換成其它專案的 Routing 模組，並且 server.js 可以重用。Node.js 的軟體架構，主軸是模組化，即 Component-based 軟體工程的觀念

目前透過 npm 指令，不但可以安裝到各式不同的 Node.js 模組，甚致可以將自已的模組出版（Publish）給其他開發者使用。

Node.js 的事件處理機制，採用典型的 Callback Functions 做法。

接著，要開始處理 Pathname 與 Query String 的解析，請先參考圖 2.2。

![圖 2.2：API 與 Query String](23/figure-2_2.png)
圖 2.2：API

改寫 index.js 主程式如下：

```
// 03-route/index.js
1 var server = require("./server");
2 var router = require("./router");
3 
4 server.start(router.route);   // 傳遞route物件
```

將 Routing 的演算法製作成獨立的模組，並將 router() 函數傳遞給 start()，函數的參數，可以傳遞一個函數，這個觀念就是 Lambda。router.js 完整程式碼如下：

```
// 03-route/router.js
1 function route(pathname) {
2     console.log("Route this request: " + pathname);
3 }
4 
5 exports.route = route;
```

請注意，這個範例雖然陽春，但是展示了一個非常重要的觀念：

- 函數就是物件，所以我們把 *route* 物件交給 start() 函數，讓 start() 函數去使用物件
- 直接在 start() 裡呼叫 route() 函數也可以，為什麼不這樣做？因為這不是 JavaScript 的觀念，倒是有點像是標準 C 語言呼叫函數的觀念，同時也會降低程式碼的可維護性

接下來，要讓 route() 解析 pathname。例如，我們定義了二個 API：

- http://localhost:8080/start，用來連接伺服器並接收即時訊息
- http://localhost:8080/send，送出文字訊息

分別要處理二個 pathname 如下：

- /start，呼叫專屬的 Handler 'start()' 來處理
- /send，呼叫專屬的 Handler 'send()' 來處理

實作的關鍵來了，我們要利用 Request Handler 的觀念來實作，首先，修改 index.js 如下：

```
// 04-request-handlers/index.js
 1 var server = require("./server");
 2 var router = require("./router");
 3 var handlers = require("./requestHandlers");
 4 
 5 // 使用 Object 來對應 pathname 與 request handlers
 6 var req = {
 7    "/": handlers.start,
 8    "/start": handlers.start,
 9    "/send": handlers.send
10 };
11 
12 // 傳遞 request handler 
13 server.start(router.route, req);
```

上述的二個 Handler 函數：start() 與 send() 將另行實作於 requestHandlers 模組。requestHandlers 模組匯出 start() 與 send() 函數，分別處理相對應的 pathname。

因此，主程式在第 6 行到第 10 行的地方，利用 *req* 物件來對應這個關係。在呼叫 start() 時，將 req 物件傳入。

另外，JavaScript 雖然不是物件導向式語言，但仍要以物件的觀念來撰寫。所以，我們將 *req* 以 var 語法定義成 object。很多時候，或許也能以 associative array 來實作，但並不是很建議。

以下就是一個以 associative array 的實作範例，原則上不推薦：

```
 1 var server = require("./server");
 2 var router = require("./router");
 3 var handlers = require("./requestHandlers");
 4 
 5 // 使用 associative array 來對應 pathname 與 request handlers
 6 var req = {};
 7
 8 req["/"] = handlers.start;
 9 req["/start"] = handlers.start;
10 req["/send"] = handlers.upload;
11 
12 // 傳遞 request handler 
13 server.start(router.route, req);
```

修改後的 router.js 如下：

```
// 04-request-handlers/router.js
 1 function route(pathname, handlers, response) {
 2     console.log("Route this request: '" + pathname + "'");
 3 
 4     // 檢查 pathname 是否有對應的 request handlers
 5     if (typeof handlers[pathname] == "function") {
 6         handlers[pathname](response);
 7     } else {
 8         console.log("No request handler for this pathname: '" + pathname + "'");
 9     }
10 }
11 
12 exports.route = route;
```

再次修改 server.js 如下：

```
// 04-request-handlers/server.js
 1 var http = require("http");
 2 var url = require("url");
 3 
 4 function start(route, handlers) {
 5   function onRequest(request, response) {
 6     var pathname = url.parse(request.url).pathname;
 7     console.log("Request for " + pathname + " received.");
 8 
 9     route(pathname, handlers, response);
10 
11     response.writeHead(200, {"Content-Type": "text/plain"});
12     response.write("Hello World");
13     response.end();
14   }
15 
16   http.createServer(onRequest).listen(8080);
17   console.log("Server has started.");
18 }
19 
20 // Export functions
21 exports.start = start;
```

最重要的模組：requestHandlers.js，完整程式碼如下：

```
// 04-request-handlers/requestHandlers.js
 1 function start(response) {
 2     console.log("Handler 'start' is started.");
 3 }
 4 
 5 function send(response) {
 6     console.log("Handler 'send' is started.");
 7 }
 8 
 9 exports.start = start;
10 exports.send = send;
```

到這裡，已經完成了一份很基本的 Web Service 實作。接下來，我們要將這個成果發展成一個即時聊天軟體，就命名為 NoChat。NoChat 將會是一個完全使用 HTML5 技術開發的即時聊天軟體。

</script>]]>
      
   </content>
</entry>
<entry>
   <title>Web Starter Kit: 環境與開始動手</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/06/web-starter-kit-2.html" />
   <id>tag:www.jollen.org,2014:/blog//2.828</id>
   
   <published>2014-06-27T07:57:40Z</published>
   <updated>2014-06-27T13:08:04Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫（why?），若無法閱讀內文，請點擊這裡。 本文介紹 Web Starter Kit 的入門第一步：簡單認識開發環境，並開始修改第一個 Web App。首先，必須根據 [Web Starter Kit](https://developers.google.com/web/fundamentals/tools/setup/setup_kit#install-tooling) 官方網站上的說明，安裝 Web Starter Kit 所需的開發環境。 從架構面來看，Web Starter Kit 提供二個環境： * Node.js 的 Runtime * 一套 Web App 的 HTML5 文件（ Mobile-optimized HTML 模板與 CSS 定義） Web Starter...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Node.js &amp; RESTful" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法閱讀內文，請點擊<a href="http://www.jollen.org/blog/2014/06/web-starter-kit-2.html">這裡</a>。

<script id='markdown', type='text/plain'>

本文介紹 Web Starter Kit 的入門第一步：簡單認識開發環境，並開始修改第一個 Web App。首先，必須根據 [Web Starter Kit](https://developers.google.com/web/fundamentals/tools/setup/setup_kit#install-tooling) 官方網站上的說明，安裝 Web Starter Kit 所需的開發環境。

從架構面來看，Web Starter Kit 提供二個環境：

* Node.js 的 Runtime
* 一套 Web App 的 HTML5 文件（ Mobile-optimized HTML 模板與 CSS 定義）

Web Starter Kit 並非像是 Android SDK 提供完整的 IDE 環境，所以使用 Web Starter Kit 前，仍有一些背景知識與工具要事前準備好。第一個必備工具，當然就是 Editor 了。撰寫程式碼，包含 HTML5 與 CSS，最佳首選當然就是 Sublime Text 3。Web Starter Kit 官方也推薦這個編輯器；這個編輯器是工程師的基本裝備。

![圖 1: 編譯](http://i.imgur.com/9fiUTeb.png)

Web Starter Kit 內容比較單純：就只有 Node.js 的 Runtime，以及一套 HTML5 文件模板。不過，它確實簡化許多繁鎖的技術細節。例如，現在的 Node.js 開發者，每個人都有不同的環境，有些人用 Grunt，有些人用 Gulp；同樣是使用 Grunt 環境，每個人撰寫的 Tasks 又不一樣。

使用 HTML5 來開發 Web App，大家的 Page Structure 又不同，每個人還會有自已的 CSS 定義；如果是 RWD 的話，Media Query 的寫法又不一致（對螢幕寬度的定義標準不一）。如果現在大家都直接引用 Web Starter Kit，這一切都可以成為標準。所以，Web Starter Kit 或許有機會把 Multi-Device HTML5 App 的開發與 User Experience 標準化。


## Step 1: 編譯

下載並完成 Web Starter Kit 的環境安裝後，直接在 *web-starter-kit-0.2.0-beta/* 目錄下執行 *gulp* 指令，編譯 *app/* 下的內容。編譯後的結果，會存放至 *dist/* 目錄下。

![圖 2: 編譯](http://i.imgur.com/XKyfmzq.png)

## Step 2: 執行

編譯後，再執行 *gulp serve* 指令，啟動 Node.js 的 Web Server。Web Starter Kit 的 gulp 環境支援 Live Reload；這時，gulp 會自動開啟瀏覽器，並且自動瀏覽我們的 Web App。

![圖 3: 啟動 Node.js Web Server](http://i.imgur.com/n4KzH0F.png)

![圖 4: 第一個 Web App](http://i.imgur.com/PTEJ8YW.png)

## Step 3: 體驗 Live Reload

開啟 *app/* 目錄下的 *index.html* 文件，這就是在上個步驟所看到的網頁。你會發現，*index.html* 已經將 ViewPort、Page Structure 等各種技術細節，都事先定義完成了。我們的第一個 Web App 就從這裡開始。

首先，可以找到 &lt;header&gt; 區塊，接著將裡頭的 &lt;h1&gt; 文字修改為「InnoBoard」：

```
        <header class="app-bar promote-layer">
            <div class="app-bar-container">
                <button class="menu"><img src="images/hamburger.svg"></button>
                <h1 class="logo">InnoBoard</h1>
                <section class="app-bar-actions">
                <!-- Put App Bar Buttons Here -->
                </section>
            </div>
        </header>
```

存檔的同時，會發現 gulp 幫我們重新「整理網頁」了，而且重速相當快。這個功能就叫做 Live Reload。

</script>
]]>
      
   </content>
</entry>
<entry>
   <title>認識 Web Starter Kit</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/06/web-starter-kit-1.html" />
   <id>tag:www.jollen.org,2014:/blog//2.827</id>
   
   <published>2014-06-27T07:55:04Z</published>
   <updated>2014-06-27T13:02:16Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫（why?），若無法閱讀內文，請點擊這裡。 Bootstrap 是一個廣受歡迎的 CSS Framework，它有現成的 Grid System 可以支援 Responsive Web Design（RWD）網頁製作。Responsive Web Design是製作多屏（Multi-Device）網頁的技術，RWD 能讓網頁同時在 PC、平板與手機等不同的 Screen 上顯示。 一些 App 開發者，會以 HTML5 的技術來製作 App。除了直接撰寫 Media Query 外，利用像是 Bootstrap 這樣的 CSS Framework 也大有人在。現在，HTML5 App 開發者又多了另外一個選擇了：[Web Starter Kit](https://developers.google.com/web/starter-kit/)。Web Starter Kit 是...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Node.js &amp; RESTful" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法閱讀內文，請點擊<a href="http://www.jollen.org/blog/2014/06/web-starter-kit-1.html">這裡</a>。

<script id='markdown', type='text/plain'>

Bootstrap 是一個廣受歡迎的 CSS Framework，它有現成的 Grid System 可以支援 Responsive Web Design（RWD）網頁製作。Responsive Web Design是製作多屏（Multi-Device）網頁的技術，RWD 能讓網頁同時在 PC、平板與手機等不同的 Screen 上顯示。

一些 App 開發者，會以 HTML5 的技術來製作 App。除了直接撰寫 Media Query 外，利用像是 Bootstrap 這樣的 CSS Framework 也大有人在。現在，HTML5 App 開發者又多了另外一個選擇了：[Web Starter Kit](https://developers.google.com/web/starter-kit/)。Web Starter Kit 是 Google 官方出品的工具，它的主要目的就是幫助開發者，製作 Responsive Web Design 的 App。

## 主要特色

根據 Web Starter Kit 的官方說明，這套工具的主要特色如下：

* 提供一個 Mobile-optimized 的 HTML5 文件模板
* 提供 RWD 的能力
* 提供一些視覺化的組件（Component）
* 提供一套基於 GulpJS Build System 的環境

在 2013 年以前，Node.js 開發者會使用 Grunt 來搭建工作環境；Grunt 是一個 Task Runner 環境，用來撰寫一些「任務」，例如：啟動 Node.js 主程式的任務、或是最小化 CSS 的任務。這有點像是 Makefile 環境。

## 使用 Gulp.js

Gulp.js 在 2014 年橫空出世，有一種完全取代 Grunt 的感覺。 Gulp.js 的特點是使用了 Node.js 的 Streams  系統，Streams 是一個非常重要的 Node.js 特色。Streams 提供了抽象的 Read/Write 接口，並且基於 EventEmitter。

EventEmitter 又是什麼東西呢？這是一個 Node.js 的事件處理系統，Backend 開發者會用它來實作 Workflow Automation。總而言之，基於 Streams 的 Gulp 擁有更好的處理效能。

此外，寫過 Gruntfile.js （Grunt 的設定檔）的開發者都知道，Gruntfile.js 雖然也是使用 JavaScript 語法，但程式碼內容並不好看；意思是，感覺不像是在寫 Node.js 程式。Gulp.js 就很有寫程式的感覺。Web Starter Kit 會採用 Gulp.js 一點都不另人意外。

## Responsive Web Design Patterns

Web Starter Kit 的另一個特點是，它把 Responsive Web Design 歸納成一套 Patterns，稱為 Responsive Web Design Patterns。個人認為，這是 Web Starter Kit 非常重要的貢獻。雖然類似這種 Mobile-optimized UI Patterns 不在少數（例如 Android App 就有自已的 UI Patterns），但 Web Starter Kit 為繁為簡、汲取各家之優點，整理出 5 個基礎的模式，對於使用 HTML5 來開發 Multi-Deivce Apps 是非常重要的 Milestone。這項貢獻有助於達到二個重要目的：

* Unified user experience。未來可以統一操作方式：提供使用者一致性的操作經驗。
* Device experience。Web Starter Kit 的目標是 Multi-Device，所以提供好的、一致性的裝置使用經驗，就是一個重要的技術工作。

Web Starter Kit 的 Responsive Web Design Patterns 看起來，直接引用了大家已經習慣多時的操作介面，而不是重新發明，例如：Off canvas；Off canvas 是在設計 Web 時，很常用的一種選單設計方式。所以，依循 Web Starter Kit 的這 5 個 Patterns 來設計 UI，理論上可以讓使用者「無痛上手」你的 App。

## Mobile-optimized HTML5 模板

在 Web Starter Kit 的 *app/* 目錄下，可以找到一個 *index.html* 檔案，這就是 Web Starter Kit 提供的 "Hello, World" 模板。在這個模板裡，已經定義好 ViewPort、iOS web apps meta data、page structure 等基本資訊，這些重覆性的工作，都不需要再自已實作了；所以，開啟這個檔案，開始擴充你的第一個 Web app 吧。

</script>]]>
      
   </content>
</entry>
<entry>
   <title>Node.js 入門, #2：Node.js 模組</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/04/nodejs-getting-started-2.html" />
   <id>tag:www.jollen.org,2014:/blog//2.826</id>
   
   <published>2014-04-15T15:58:19Z</published>
   <updated>2014-04-15T21:04:07Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫（why?），若無法閱讀內文，請點擊這裡。 ## 製作 Node.js 模組 學習 Node.js 的第一件事情，就是了解如何將程式碼模組化，簡單來說，就是製作一個程式庫 Node.js 的模組隱含著 Closure 的特性。 JavaScript 比較講求模組化，所以我們重構 hello.js。先將 Web Server 的部份獨立成一個模組，程式碼規劃如下： - index.js：主程式 - server.js：啟動Web server的模組 index.js的完整程式碼如下： ``` // 02-modules/hello.js var server = require(&quot;./server&quot;); server.start(); ``` 主程式的部份，以 require() 函數將 server 模組（即...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Node.js &amp; RESTful" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法閱讀內文，請點擊<a href="http://www.jollen.org/blog/2014/04/nodejs-getting-started-2.html">這裡</a>。

<script id='markdown', type='text/plain'>

## 製作 Node.js 模組

學習 Node.js 的第一件事情，就是了解如何將程式碼模組化，簡單來說，就是製作一個程式庫 Node.js 的模組隱含著 Closure 的特性。

JavaScript 比較講求模組化，所以我們重構 hello.js。先將 Web Server 的部份獨立成一個模組，程式碼規劃如下：

- index.js：主程式
- server.js：啟動Web server的模組

index.js的完整程式碼如下：

```
// 02-modules/hello.js
var server = require("./server");

server.start();
```

主程式的部份，以 require() 函數將 server 模組（即 server.js 檔案）引入，接著呼叫模組裡的 start() 函數。server.js 完整程式碼如下：

```
// 02-modules/server.js
 1 var http = require("http");
 2 
 3 function start() {
 4   function onRequest(request, response) {
 5     console.log("Request for " + pathname + " received.");
 6 
 7     response.writeHead(200, {"Content-Type": "text/plain"});
 8     response.write("Hello World");
 9     response.end();
10   }
11 
12   http.createServer(onRequest).listen(8080);
13   console.log("Server has started.");
14 }
15 
16 // Export functions
17 exports.start = start;
```

程式碼第 3 行到第 16 行的地方，我們實作了一個函數，並且將它匯出。請特別留意，沒有匯出的函數，將不是 Public，它不能被外部的人呼叫。exports 是 Node.js 的一個 Global object，用來讓我們匯出模組裡的函數，成為 Public Function。

目前為止，我們發現了一些觀念：

- Frontend 與 Backend 都使用 JavaScript 做為主要的程式語言
- Frontend 與 Backend 都要模組化，並引入 Closure 觀念
- Frontend 與 Backend 的 Module / Closure，相念相通，實作方式不同

### Chaining Pattern

另外，server.js 裡也做了一些改寫。程式碼第 4 行的地方，以具名函數的方式重新實作，目的是讓程式碼更具可維護性。此外，程式碼第 14 行的地方：

```
http.createServer(onRequest).listen(8080);
```

物件接著下一個物件來連續呼叫多個方法的寫法，就叫 Chaining Pattern（鏈接模式）。這個設計模式的目的，同樣是為了提升程式碼的可維護性：不但能簡化程式碼，更能讓程式碼能構成一個句子。

在接下來的範例裡，我們將善用具名函數以及 Chaining Pattern 來提昇程式碼的可維護性。

</script>]]>
      
   </content>
</entry>
<entry>
   <title>Node.js 入門, #1：Hello World</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/04/nodejs-getting-started-1.html" />
   <id>tag:www.jollen.org,2014:/blog//2.825</id>
   
   <published>2014-04-15T15:51:31Z</published>
   <updated>2014-04-15T21:02:55Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫（why?），若無法閱讀內文，請點擊這裡。 ## Node.js 入門, #1：Hello World Node.js 並不是使用於 Client-side，它使用於 Server-side。有關 Node.js 的說明，可參考 Node.js 官方網站。在繼續進行範例說明前，請先備妥這份文件： http://nodejs.org/api/ 另外，也請參考 Node.js 官方網站的說明，來安裝 Node.js 環境。關於環境安裝，以及 Node.js 的入門觀念，可參考由 MokoVersity 所提供的免費線上課程： http://www.mokoversity.com/course/html5/nodejs-overview ## 取得範例 本文所撰寫的 Node.js 程式碼，皆可在 Github 上取得： https://github.com/jollen/html5-websocket-nodejs 接下來，讓我們用一個連貫性的實例：即時通訊軟體，來為大家介紹 Node.js 技術。 ## 第一個...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Node.js &amp; RESTful" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法閱讀內文，請點擊<a href="http://www.jollen.org/blog/2014/04/nodejs-getting-started-1.html">這裡</a>。

<script id='markdown', type='text/plain'>

## Node.js 入門, #1：Hello World

Node.js 並不是使用於 Client-side，它使用於 Server-side。有關 Node.js 的說明，可參考 Node.js 官方網站。在繼續進行範例說明前，請先備妥這份文件：

http://nodejs.org/api/

另外，也請參考 Node.js 官方網站的說明，來安裝 Node.js 環境。關於環境安裝，以及 Node.js 的入門觀念，可參考由 MokoVersity 所提供的免費線上課程：

http://www.mokoversity.com/course/html5/nodejs-overview

## 取得範例

本文所撰寫的 Node.js 程式碼，皆可在 Github 上取得：

https://github.com/jollen/html5-websocket-nodejs

接下來，讓我們用一個連貫性的實例：即時通訊軟體，來為大家介紹 Node.js 技術。

## 第一個 Node.js 程式

Node.js 能提供 Web Server 的能力。所以，不免俗地先了解 "Hello, World" 的寫法：

```
// 01-create-server/hello.js
 1 var http = require('http');
 2 
 3 var httpServer = http.createServer(function (req, res) {
 4   res.writeHead(200, {'Content-Type': 'text/html'});
 5   res.end('<h1>Hello World</h1>\n');
 6 });
 7 
 8 httpServer.listen(8080);
 9 
10 console.log('Server running at http://127.0.0.1:8080/');
```

程式碼第 3 行的地方，呼叫 http 模組的 createServer() 函數來建立一個 Web Server 物件。建立 Web Server 物件，並且啟動一個 Web Server，是  Node.js  技術的第一個步驟。

createServer()函數的說明如下：

```
http.createServer([requestListener])
```

createServer() 執行成功後傳回 Web Server 物件，參數 requestListener 是一個 Request Handler Function，用來處理 request 事件。關於 Node.js 的事件處理技術，後續再做說明。當 request 事件發生時，Request Handler Function 將被 Callback，並帶有二個參數：

- req：http.ServerRequest的實例化(instance)
- res：http.ServerResponse的實例化

將上述的範例，儲存為 hello.js，並且利用 node 指令執行：

$ node hello.js 

安裝 Node.js 後，就可以取得 node 命令。

這是執行 Node.js 程式碼的陽春版做法，後續將導入 forever 工具，以進階的方式來執行 Node.js 程式。

 Node.js 採用 Google 所開發的 V8 JavaScript 引擎，原本 V8 引擎是設計給瀏覽器使用的 JavaScript 引擎，現在有開發者把它抽離出來，變成一個獨立的直譯器，讓 JavaScript 程式碼升格為 Server-Side Script。

我們利用瀏覽器連到 http://127.0.0.1:1234/。

## V8 JavaScript引擎介紹

JavaScript 引擎將成為手持裝置的重要技術。早期的 Android 系統，使用的 JavaScript 引擎稱為 JavaScriptCore (JSC)，這是由 Apple 所開發的 JavaScript 引擎，並且包含在 Webkit 中。因為一些原因，Google 也決定開發自已的 JavaScript 引擎，稱之為 V8。

技術上，JSC 與 V8 的設計理念不同，一般相信，新一代的 V8 引擎效能比 JSC 引擎更好。Android 2.3 加入了 V8 引擎，若想使用最近的 V8 引擎，就要使用 Android 2.3 以上的版本。

## 為什麼要使用 Node.js？

到這裡，大家可能會有一個疑問。為什麼不使用現有的 Web Server 來開發 Web Service 就好，例如使用 Apache。非要使用 Node.js 技術不可嗎？這個問題的答案，要從 Thread Model 說起。

典型的 Web Server 以 Multi-thread 架構來實作「Concurrency」，也就是以建立 Thread 的方式，來處理處理事件（Events）。但是過多的 Thread 會造成伺服器的負擔：

- 假設一個 Thread 可以處理 10 個事件
- 同時處理 1000 個事件，就必須建立 100 個 Thread
- 大量的 Thread 在分時作業系統裡，會造成 Context-Switch Overhead，讓每一個 Thread 處理事件的時間拉長，形成效能低落的現象

由此可知:

- 若是將 Multi-thread 架構，應用在「處理巨量的同時連線請求」上，伺服器的負擔就會很大
- Multi-thread 架構的軟體，可能在系統產生過多的 Thread，過多的 Thread 除造成伺服器的負載增加外，也需要大量的記憶體

是否有替代方案呢？將上述的 Multi-thread 架構，改為 Event Loop 架構即可。Node.js 的訴求之一就是：採用 Event Loop 架構。此外，Node.js 採用 JavaScript 程式語言，JavaScript 本身也有一些很好的語言特性：

- 具備 Lambda 運算子，大量使用暱名函數（anonymous function）與 Closure（封閉性）觀念
- 使用 Callback Object 做為函數的參數（Lambda），易於處理 Non-blocking Operation 與 Event Handling

Node.js 本身的 I/O 操作，也大多是（幾乎）Non-blocking 的機制。這點與 PHP 有很大的不同。這樣的機制，對於消化巨量的連線請求，有非常大的幫助。

</script>]]>
      
   </content>
</entry>
<entry>
   <title>我用 Markdown 語法</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/04/use-markdown-syntax.html" />
   <id>tag:www.jollen.org,2014:/blog//2.824</id>
   
   <published>2014-04-15T15:14:11Z</published>
   <updated>2014-04-15T20:43:15Z</updated>
   
   <summary>過去，我的文章大多以純文字方式撰寫，技術筆記也是。大部份的文章與筆記，都會整理到部落格和大家分享。我的部落格後台是採用 MovableType 這個古老的系統，因為一些原因（個人的一些特殊喜好），所以至今仍使用這套軟體。不管是 WordPress 或 MovableType，都需要登入後台，並且還要以 HTML 標籤語法來加工文章。 這一年多因為工作習慣的改變，以及使用網路習慣的改變，登入後台更新文章並不方便，加上還要處理 HTML 的加工，所以就不常更新部落格了。文章就靜靜地躺在我的硬碟裡。 直到去年，我開始使用 Markdown 語法來整理這些文字，原因是，希望將整理過的文字，批次出版成 E-book。Markdown 語法自然成為最佳方案之一。自助出版平臺，例如：Leanpub，都能支援 Markdown 格式。利用 Pandoc 也能將 Markdown 製作成簡報，非常方便。 將 Markdown 再轉為 HTML 雖然很簡單，但又要多做一個工。不如把 Markdown 內文，直接貼到部落格就好：加上一段「Client-side Markdown Parsing」的程式碼即可一勞永逸。 Markdown 語法真是打遍天下，不管是編修 Wiki，或是撰寫 Github 專案的說明，還是在 Github issues 裡貼文，都難不到。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[過去，我的文章大多以純文字方式撰寫，技術筆記也是。大部份的文章與筆記，都會整理到部落格和大家分享。我的部落格後台是採用 MovableType 這個古老的系統，因為一些原因（個人的一些特殊喜好），所以至今仍使用這套軟體。不管是 WordPress 或 MovableType，都需要登入後台，並且還要以 HTML 標籤語法來加工文章。

這一年多因為工作習慣的改變，以及使用網路習慣的改變，登入後台更新文章並不方便，加上還要處理 HTML 的加工，所以就不常更新部落格了。文章就靜靜地躺在我的硬碟裡。

直到去年，我開始使用 Markdown 語法來整理這些文字，原因是，希望將整理過的文字，批次出版成 E-book。Markdown 語法自然成為最佳方案之一。自助出版平臺，例如：Leanpub，都能支援 Markdown 格式。利用 Pandoc 也能將 Markdown 製作成簡報，非常方便。

將 Markdown 再轉為 HTML 雖然很簡單，但又要多做一個工。不如把 Markdown 內文，直接貼到部落格就好：加上一段「<a href="http://www.jollen.org/blog/2013/08/client-side-markdown-parsing.html">Client-side Markdown Parsing</a>」的程式碼即可一勞永逸。

Markdown 語法真是打遍天下，不管是編修 Wiki，或是撰寫 Github 專案的說明，還是在 Github issues 裡貼文，都難不到。

]]>
      
   </content>
</entry>
<entry>
   <title>Software 與 NoHardware － 不只是硬體的時代</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/02/nohardware.html" />
   <id>tag:www.jollen.org,2014:/blog//2.823</id>
   
   <published>2014-02-06T03:18:47Z</published>
   <updated>2014-02-06T10:04:24Z</updated>
   
   <summary>因為 Mokoversity 計畫，筆者近期有機會和團隊成員，以及各界專家，交換許多對產業的看法。因此，有了 NoHardware 的想法。在這裡提出與大家分享。 近來聊到，如何媒合（Bridge）軟體人與硬體人時，筆者提到，現在的時代，不應該太過於強調軟體人與硬體人。意思是，不去鼓勵軟體人就只做軟體，也不鼓勵硬體人只做硬體。所以，軟體人與硬體人的媒合機制，有點被筆者打了回票。因為，「媒合」是一種消極的做法，更積極的做法是從「自已」出發。 硬體人也可以學 Coding，這不就是硬體人做軟體的起步嗎。因此，培養全端能力（Full Stack）就是實現想法，將想法實現為產品的關鍵。這並不是強調「單打獨鬥」的做事方式，而是將內心想法 Prototyping 出來的重要能力。有了 Prototyping 後，接下來就是尋找專業伙伴，進入專業分工、團隊運作的階段。這是一個「跨領域學習、再交流結合」的時代。 又如，Designer 也可以是 Coder，Coder 也可以是 Designer，這就是 Mokoversity 的精神：站在全民寫程式的角度。當 Designer 也是 Coder 時，就可以 Reinvent 很多事、物。 為什麼硬體廠做出來的硬體就是硬體？因為他們過度依賴「專業分工」，所以沒有火種：公司內部沒有能在硬體上點火的軟體人，也沒有能在軟體上點火的硬體人。 NoHardware－Not Only Hardware 從事 Backend 開發的工程師都聽過 NoSQL[1]，它的意思是 Not Only SQL。傳統的關聯式資料（RDMBS）採用 SQL 查詢語法，來新增、刪除、查詢與修改資料庫。NoSQL 是一種不採用...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[因為 Mokoversity 計畫，筆者近期有機會和團隊成員，以及各界專家，交換許多對產業的看法。因此，有了 NoHardware 的想法。在這裡提出與大家分享。

近來聊到，如何媒合（Bridge）軟體人與硬體人時，筆者提到，現在的時代，不應該太過於強調軟體人與硬體人。意思是，不去鼓勵軟體人就只做軟體，也不鼓勵硬體人只做硬體。所以，軟體人與硬體人的媒合機制，有點被筆者打了回票。因為，「媒合」是一種消極的做法，更積極的做法是從「自已」出發。

硬體人也可以學 Coding，這不就是硬體人做軟體的起步嗎。因此，培養全端能力（Full Stack）就是實現想法，將想法實現為產品的關鍵。這並不是強調「單打獨鬥」的做事方式，而是將內心想法 Prototyping 出來的重要能力。有了 Prototyping 後，接下來就是尋找專業伙伴，進入專業分工、團隊運作的階段。這是一個「跨領域學習、再交流結合」的時代。

又如，Designer 也可以是 Coder，Coder 也可以是 Designer，這就是 Mokoversity 的精神：站在全民寫程式的角度。當 Designer 也是 Coder 時，就可以 Reinvent 很多事、物。

為什麼硬體廠做出來的硬體就是硬體？因為他們過度依賴「專業分工」，所以沒有火種：公司內部沒有能在硬體上點火的軟體人，也沒有能在軟體上點火的硬體人。

<strong>NoHardware－Not Only Hardware</strong>

從事 Backend 開發的工程師都聽過 NoSQL[1]，它的意思是 Not Only SQL。傳統的關聯式資料（RDMBS）採用 SQL 查詢語法，來新增、刪除、查詢與修改資料庫。NoSQL 是一種不採用 SQL 做為查詢語法的資料庫系統；從 2009 年開始，因為大量數據與分散式儲存的需求提昇，使得 NoSQL 受到相當程度的矚目。MongoDB 與 CouchDB 是非常知名的 NoSQL 資料庫。

智能手機在 2007 年開始逐步改變人類的生活習慣。PC 至今仍然存在，並沒有完全被智能手機取代，但是相當多的資訊應用都已經被智能手機取代了。有了 iOS 與 Android 後，大家發現了 App 的便利性，所以不斷從 App Store 與 Play Store 上下載各種 App；接著，像是 WhatsApp、LINE 這類的即時通訊軟體，取代了 PC 時代的 MSN。2013 年 4 月，有 14 年歷史的 MSN 吹熄燈號。

2010 年開始，手機通訊軟體改變了傳統網站的通訊方式，人們的習慣，過去是從 PC 上使用即時通訊軟體，現在已經轉變成在手機上使用通訊軟體。然而，並不是把 MSN 移植到手機上就叫「手機通訊」。筆者認為，「手機通訊」帶來的改變，和「開放源碼運動」本質相同：他們都改變了「社會文化」，而不是只有「使用習慣而已」。

手機通訊時代，帶來的社會文化改變，也帶來產業與商業規則的改變。手機製造商，不再把手機當做硬體來製造與銷售。手機製造商，不再用 PC 思惟去思考手機。智能手機時代，讓手機硬體，不再只是硬體。所以，手機，並不只是硬體－Hadware is not only hardware，就像 NoSQL 一樣，現在是 NoHardware 的時代。

The Economist 不久前的專題「The new GE: Google, everywhere[2]」，更清楚地指出，Google 把自已重新定位為「Hardware Re-inventor」。當硬體不再只是硬體時，就要加入更多的創意與想法，這需要大量的軟體工程去實現。

NoHardware 不但只是 Not Only Hardware，背後更有「只有硬體還不夠」以及「重新發明硬體」的涵義。

<strong>矽谷的硬體創業潮</strong>

大約在 2012 年開始，矽谷出現一波硬體創業風朝[3]，到了 2013 年底，這波風潮因為穿戴裝置與自造者（Maker）的關係，形成一個強力的創業生態圈。在這個硬體創業生態圈裡，「創業加速器」當然成為重要的角色。

筆者在 2013 年 10 月份，受邀至深圳參加第二屆的 Android World 開發者大會，這屆大會談的創業，除了開放平臺外，也提到了硬體創業的現象。然而，以硬體製造優勢自居的台灣產業，卻沒有站在這波「硬體創業」的浪頭；這就算了，台灣已經完全被硬體創業圏排除在外，關於這點，可以從二個現象來觀察：

有矽谷越來越多的硬體創業加速器，前往深圳獲取資源，而不是來台灣
非常多創新硬體都是在深圳生產，透過深圳的硬體產業試量或產量
發表過著名的「免費」一書作者 Chris Anderson 在 2013 年 11 月時來台演講，他在今年所發表的新書「自造者」，談的就是「每個人都能製造硬體」的時代，這不正與「每個人都在寫程式」的時代，相互呼映嗎？不管是軟體或硬體，台灣跟不上前一波的軟體復興運動，似乎也無法跟進這波的硬體復興運動。

台灣的硬體廠，仍然可以繼續做硬體，因為這是台灣產業的好價值。要尋求突破，就要心中沒有硬體，做到 NoHardware 的精神。

<strong>參考資源
</strong>

[1]: http://zh.wikipedia.org/zh-tw/NoSQL "NoSQL"
[2]: http://www.economist.com/news/business/21594259-string-deals-internet-giant-has-positioned-itself-become-big-inventor-and "The new GE: Google, everywhere"
[3]: http://www.pingwest.com/highway1/ "Highway1"]]>
      
   </content>
</entry>
<entry>
   <title>Coding 就是 Writing：寫程式是一種作文能力</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2014/01/coding-likes-writing.html" />
   <id>tag:www.jollen.org,2014:/blog//2.838</id>
   
   <published>2014-01-14T06:59:21Z</published>
   <updated>2014-09-18T21:09:56Z</updated>
   
   <summary>（文／Jollen，原文刊載於 Mokoversity） 「每個人都要學 Coding」、「全民 Coding」，這是近一年來最特別的現象。大家都來學 Coding，也是 MokoVersity 的理念。 寫作文 為什麼要學習程式設計？並不是為了將自己訓練成軟體開發專家，而讓自己能夠具備「寫作」的能力。 從寫作（Writing）的角度來討論程式設計，就好像小時候大家都在學校，學習寫字與作文一樣。 如果，你是個設計師，內心深處充滿著許多想法，而這些想法可能必須以程式設計的方式來呈現： 這就是為什麼設計師要學習程式設計的原因。會寫作，你就可能用作文的方式，完整表達自已的想法。為什麼要自已寫作文？因為很難透過他人來「轉述」心裡最深處的思想，或是感覺。 設計師的許多想法，特別是一些細節，除了透過自己親自動作來實作原型（Prototype）外，並不容易經由工程人員，幫你完整實現想法。透過他人的筆，很難完整表現自已的想法：工程師並不能幫助設計師，完整表現出想法。 所以，我們可以換個角度思考。當你有許多想法時，可以自已寫作，透過文章的方式來表達，並將它發佈在網路上，和許多人討論分享。 同樣的，也能把這個概念，套用在「每個人都要學習寫設計」的角度。如果我有一些想法，而且也可以很快的用程式碼來「寫作」的話，就能了解為什麼 Coding 就是另一種 Writing 的能力。這已經成為人們在社會上生活的基本技能了。 現在在國外，特別是美國，正在推行小朋友學習程式設計的運動。一些學校，從小學開始教導小學生，如何將自己的想像，以程式碼的方式表現在電腦螢幕上。 教導這些小學生寫程式，並不是希望他可以成為最厲害的工程師，而是希望他們能夠將自己的思維，具體表達出來而已。 美國總統歐巴馬，在 Computer Science Education Week 上提到：「Learning these skills isn’t just important for your future, it’s important for our...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[（文／Jollen，原文刊載於 <a href="https://www.mokoversity.com/post/Coding%20就是%20Writing：寫程式是一種作文能力">Mokoversity</a>）

「每個人都要學 Coding」、「全民 Coding」，這是近一年來最特別的現象。大家都來學 Coding，也是 MokoVersity 的理念。

<h2>寫作文</h2>

為什麼要學習程式設計？並不是為了將自己訓練成軟體開發專家，而讓自己能夠具備「寫作」的能力。 從寫作（Writing）的角度來討論程式設計，就好像小時候大家都在學校，學習寫字與作文一樣。

如果，你是個設計師，內心深處充滿著許多想法，而這些想法可能必須以程式設計的方式來呈現： 這就是為什麼設計師要學習程式設計的原因。會寫作，你就可能用作文的方式，完整表達自已的想法。為什麼要自已寫作文？因為很難透過他人來「轉述」心裡最深處的思想，或是感覺。

設計師的許多想法，特別是一些細節，除了透過自己親自動作來實作原型（Prototype）外，並不容易經由工程人員，幫你完整實現想法。透過他人的筆，很難完整表現自已的想法：工程師並不能幫助設計師，完整表現出想法。

所以，我們可以換個角度思考。當你有許多想法時，可以自已寫作，透過文章的方式來表達，並將它發佈在網路上，和許多人討論分享。

同樣的，也能把這個概念，套用在「每個人都要學習寫設計」的角度。如果我有一些想法，而且也可以很快的用程式碼來「寫作」的話，就能了解為什麼 Coding 就是另一種 Writing 的能力。這已經成為人們在社會上生活的基本技能了。

現在在國外，特別是美國，正在推行小朋友學習程式設計的運動。一些學校，從小學開始教導小學生，如何將自己的想像，以程式碼的方式表現在電腦螢幕上。 教導這些小學生寫程式，並不是希望他可以成為最厲害的工程師，而是希望他們能夠將自己的思維，具體表達出來而已。

美國總統歐巴馬，在 Computer Science Education Week 上提到：「Learning these skills isn’t just important for your future, it’s important for our country’s future[1]。」學習程式設計技能，並不只是為了自已的未來，也是未了整個國家的未來。Computer Science Education Week 正在推廣 “Hour of Code” 活動。

所以，每個人都要學習程式設計的原因，並不是為了能夠成為 Super coder。就像， 小時候在學校，我們都要學習寫字，但不是要每個人長大後，都成為作家。美國是科技創新的中心，美國體認到 Coding 技能對國家發展的重要性，對於「人人都要學 Coding」的觀念，接受度很高，而且還有很多名人自發性的協助推廣。

美國紐約市市長彭博的二○一二年新年希望，就是學會程式設計。彭博報名參加的程式語言課程，是由 CodeCademy 推出的 Code Year 活動。類似的免費程式語言課程，也越來越多。NBA 球星 Chris Bosh 也說「Here’s Why You Should Learn to Code[2]」，他參加許多 Code.org 的程式設計課程。

學 Coding 就像寫作文，寫作文不是要人人成為作家，寫程式也不是要人人成為工程師。從小朋友的角度，或許他們不知道，在大人的世界裡：許多人認為 Coding 是工程師的事情。

比如說，學習基本的 Frontend 開發並不難，基本的 JavaScript 搭配 Twitter Bootstrap，就能做出很棒的作品。所以，認為 Coding 是一個深奧難懂的學問，或是對學習 Coding 沒自信，又或是認為這是工程師的專有技能，大概只是大人們給自已太多束縛而已。

<h2>參考資源</h2>

[1]: http://www.wired.com/wiredenterprise/2013/12/obama-code/ "Obama Says Everyone Should Learn How to Hack"

[2]: http://www.wired.com/opinion/2013/10/chris-bosh-why-everyone-should-learn-to-code/ "NBA Superstar Chris Bosh: Here’s Why You Should Learn to Code"]]>
      
   </content>
</entry>
<entry>
   <title>開放創新（Open Innovation）是治理公司的思想</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2013/12/open-innovation-thinking.html" />
   <id>tag:www.jollen.org,2013:/blog//2.822</id>
   
   <published>2013-12-20T08:03:03Z</published>
   <updated>2014-04-15T20:09:16Z</updated>
   
   <summary>開放創新是治理公司的思想 文／Jollen Chen（原文刊載於 CTimes 雜誌 2014 年 1 月號） 三星不久前成立了 Open Innovation Center，正好台灣的宏碁也在努力進行轉型，並且提出「自建雲」做為轉型的方向。在這裡，筆者希望從三星的 Open Innovation Center 來討論「開放創新」與公司治理的關係，並且提出一些對宏碁轉型的個人看法。 三星的 Open Innovation Center 本質上是一個「公司治理」的方法，這是一種人才政策，也是三星在「開放」的潮流下，十年來的第三次人才政策轉變。Open Innovation Center 並不是在做「創新研發」，而是吸引有想法、具創新思維的人才，進入到這個中心，藉由三星的資源，扶植這些人才創業，讓這些人才進行「研發」工作。 由此來看，三星的政策應該是採取精英政策，而不是為了吸引大量的創新人才，主要的原因之一是，三星的 Open Innovation Center 將天使投資與併購看成是一項業務，而不是為了招攬有能力的開發人員。創新研發的重點在人才，人才的重點在「正確的人才政策」，有了正確的人才政策，這些人才就會流進來你的生態體系，幫你做「創新研發」。台灣廠商只是從「創新研發」的字面去解讀的話，並無法深入了解三星 Open Innovation Center 的目標是什麼，以及它的戰略是什麼。 不久前，筆者在解讀三星的 Open Innovation Center 文章裡，提出二個給傳統硬體製造商的建議。這二個建議都是以開放創新做為主要戰略。開放創新談的是公司治理政策，再加上創業活動是全球的熱門活動，因此從投資與收購的角度切入，看來是一個最佳化的策略。比如說，Wearable Devices（比如：手錶），這些裝置是「創新的硬體」，而不是「製造的硬體」或「Cost-down...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      開放創新是治理公司的思想

文／Jollen Chen（原文刊載於 CTimes 雜誌 2014 年 1 月號）

三星不久前成立了 Open Innovation Center，正好台灣的宏碁也在努力進行轉型，並且提出「自建雲」做為轉型的方向。在這裡，筆者希望從三星的 Open Innovation Center 來討論「開放創新」與公司治理的關係，並且提出一些對宏碁轉型的個人看法。

三星的 Open Innovation Center 本質上是一個「公司治理」的方法，這是一種人才政策，也是三星在「開放」的潮流下，十年來的第三次人才政策轉變。Open Innovation Center 並不是在做「創新研發」，而是吸引有想法、具創新思維的人才，進入到這個中心，藉由三星的資源，扶植這些人才創業，讓這些人才進行「研發」工作。

由此來看，三星的政策應該是採取精英政策，而不是為了吸引大量的創新人才，主要的原因之一是，三星的 Open Innovation Center 將天使投資與併購看成是一項業務，而不是為了招攬有能力的開發人員。創新研發的重點在人才，人才的重點在「正確的人才政策」，有了正確的人才政策，這些人才就會流進來你的生態體系，幫你做「創新研發」。台灣廠商只是從「創新研發」的字面去解讀的話，並無法深入了解三星 Open Innovation Center 的目標是什麼，以及它的戰略是什麼。

不久前，筆者在解讀三星的 Open Innovation Center 文章裡，提出二個給傳統硬體製造商的建議。這二個建議都是以開放創新做為主要戰略。開放創新談的是公司治理政策，再加上創業活動是全球的熱門活動，因此從投資與收購的角度切入，看來是一個最佳化的策略。比如說，Wearable Devices（比如：手錶），這些裝置是「創新的硬體」，而不是「製造的硬體」或「Cost-down 的硬體」，後二者是台灣的強項。然而，傳統硬體商要進入「創新的硬體」，沒有人才，就沒有轉型機會。

傳統硬體廠如何解決人才的問題？扮演天使投資人的角色，一定是一個好方法。從這個角度也可以了解，為什麼三星要在矽谷成立 Open Innovation Center。因為，人才政策涉及到一個根本的問題：具創新思維的人才，不管是軟體人，或硬體人，因為他們熱愛自由，不喜歡受拘束，所以讓他們成為員工，並且上班打卡，很明顯就是錯誤的公司治理方法。又如，這些人才，也不可能在人力銀行找工作，所以傳統的招募政策，也是錯誤的政策。

Open Innovation Center 以號召、吸引、投資、扶植與併購的戰略，建立正確的人才政策，取得「創新研發」的能量，再透過資源協助，或參與的方式共同開發。所以，開放創新的機制，並不是由廠商直接投入研發工作，也不是在公司內部舉辦「腦力激盪」會議。從這個角度來看，就可以了解宏碁再次轉型之路，仍有很大的思維改變空間。

不只是軟體，開放創新的思維，包含硬體，最明顯的例子就是「自造者」。發表過著名的「免費」一書作者 Chris Anderson 在 2013 年 11 月時來台演講，他在今年所發表的新書「自造者」，談的就是「每個人都能製造硬體」的時代，這不正與「每個人都能寫程式」的 App 時代，相互呼映嗎？

從自造者的角度來看，每個人都可以做硬體，也可以把產品放在網路上集資，成立公司。台灣的硬體廠商，應該如何去看「自造者時代」呢？開放創新的思維，仍然是最好的角度。硬體廠可以透過天使投資人的角度，參與自造者的創業活動，再投入自身的硬體製造資源等，形成一個健康的生態體系。

不管是軟體或硬體，台灣跟不上前一波的軟體復興運動，似乎也無法跟進這波的硬體復興運動。一個在台灣的國際品牌，近期正在努力轉型的公司，從新聞媒體上所做的觀察發現，「思維」仍然是舊式思維。筆者所謂的思維，是「如何把事情做對」的思考，而不是單純的「要做什麼」的問題。比如說，我們都知道雲端是一個好題目，所以筆者認同「雲端」的方向，但如果沒有完整配套規劃，這場腦力激盪會議，就沒有太大的意義了：只要坐在家裡上網，每個人都知道雲端是個好題目。

所謂的配套，就是執行面的問題，比如說：人才很重要，沒有人才，再好的題目，都很難產出結果。為了不讓一個好的轉型機會，淪為會議室裡的談話，所以這裡需要的是人才，有了人才，就會有執行力。需要人才時，一個對的人才政策是關鍵。人才政策談的是公司治理方法，而不是挖角或招幕。

所以，公司治理政策就要做相對的調整：以開放創新思維，建立人才政策。例如：成立「自建雲天使投資基金」，用以投資年輕人的雲端公司，取代傳統的招募員工做法。這儘只是思維的一個小改變，但卻可以達到三贏的效果：公司扮演天使投資人，創業家能有很大的發展舞台，開發者可以很快樂地跟隨創業家打併。

      
   </content>
</entry>
<entry>
   <title>Node.js + Express.js 應用 - Middleware 觀念解說</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2013/11/expressjs-middleware.html" />
   <id>tag:www.jollen.org,2013:/blog//2.821</id>
   
   <published>2013-11-14T13:24:53Z</published>
   <updated>2014-04-15T20:51:16Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫，若無法閱讀內文（why?），請點擊這裡。 Express.js 的 Middlware 分為二個部份：所有 URL 與特定 URL。要了解 Middlware 的觀念，最快的方法就是實作「頁面保護」的功能。現在，讓我們為 &apos;/hello&apos; URL 加上密碼 &apos;123456&apos; 的保護。 ## 使用 *app.get()* 撰寫 Middlware 針對特定 URL 加入 Middleware，必須透過 *app.get()* 函數的第二個參數。實作步驟如下。 ### Step 1：加入 Middleware 延續上一章的範例，為 &apos;/hello&apos; 加入一個 Middleware： ``` app.get(&apos;/hello&apos;, function (req,...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Node.js &amp; RESTful" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本文章採用 Markdown 語法撰寫，若無法閱讀內文（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），請點擊<a href="http://www.jollen.org/blog/2013/11/expressjs-middleware.html">這裡</a>。

<script id='markdown', type='text/plain'>

Express.js 的 Middlware 分為二個部份：所有 URL 與特定 URL。要了解 Middlware 的觀念，最快的方法就是實作「頁面保護」的功能。現在，讓我們為 '/hello' URL 加上密碼 '123456' 的保護。

## 使用 *app.get()* 撰寫 Middlware

針對特定 URL 加入 Middleware，必須透過 *app.get()* 函數的第二個參數。實作步驟如下。

### Step 1：加入 Middleware

延續上一章的範例，為 '/hello' 加入一個 Middleware：

```
app.get('/hello', function (req, res, next) { }, hello.index);
```

說明如下：

- 第 2 個參數，是一個暱名函數，這個暱名函數就是 '/hello' 的 Middleware
- 第 3 個參數，是原本處理 URL Routing 的函數

Middleware 會收到 3 個參數：

- *req* 是 Request 物件，存放這此請求的所有資訊
- *res* 是 Response 物件，用來回應該請求
- *next* 用來控制流程，後續說明

當使用者輸入密碼時，就要撰寫一段控制流程來處理，典型的控制流程邏輯如下：

```
if (password == '123456') {
	send_page();
} else {
	end_request();
}
```

但 Express.js 並不是用這種方式，來實作流程方式。如何為 '/hello' 加入控制邏輯呢？請看步驟 2。

### Step 2：找出密碼

使用 Query String 來傳入密碼，這是最簡便的方式（也是最糟的做法）。Express.js 可以幫助我們解析 Query String，這是 Express.js 框架的另一個優點。我們就不必像第 3 章介紹的內容一樣，自已去撰寫解析 Query String 的程式碼。

Express.js 將解析好的 Query String 放在 *req.query* 物件裡，現在先直接將它印出。修改程式碼如下：

```
app.get('/hello', function (req, res, next) {
	console.log(req.query);
}, hello.index);
```

啟動 *app.js* 後，利用瀏覽器開啟 http://localhost:3000/hello?passwd=123456 網址。接著，可以在 Console 畫面看到這段訊息：

```
Express server listening on port 3000
{ passwd: '123456' }
GET /hello?passwd=123456 200 306ms - 135b
```

還有一個可能讓你嚇一跳的現象：瀏覽器的畫面是空白的，而且一直打轉。感覺好像是卡住了，這是怎麼會事兒呢？修改程式碼如下：

```
app.get('/hello', function (req, res, next) {
	console.log(req.query);
	next();
}, hello.index);
```

Express.js 傳入的 *next* 參數，實際上是一個 Lambda。呼叫 *next()* 表示「進行下一個流程」的意思，所謂的下一個流程，當然就是執行 *hello.index* 函數。

加上 *next()* 後，就能在瀏覽器上看到原本的畫面了。所以，我們只要判斷 *req.query.passwd* 就知道密碼是否正確。不過，還有更好的做法，Express.js 的功能可不是只有這樣。

### Step 3：使用內建 Middleware

Express.js 內建幾個好用的 Middleware：

- basicAuth()
- bodyParser()
- compress()
- cookieParser()
- cookieSession()
- csrf()
- directory()

像「使用者驗證」這麼常見的「流程」，Express.js 就有提供 *basicAuth()* Middleware。再次修改程式碼如下：

```
app.get('/hello', express.basicAuth('jollen', '12345678'), hello.index);
```

*basicAuth()* 使用 HTTP 的方式做認證，並不是 Query String 的做法。只要再次瀏覽網頁，就可以看到一個非常熟悉的畫面，如下圖。

<img src="http://www.jollen.org/blog/2013/11/14/figure-9_1.png" width="640" />

圖 9-1 使用 *basicAuth()* Middleware

同時，在 Node.js 的 Console 也可以看到以下訊息：

```
GET /hello 401 10ms
```

這表示 *basicAuth()* 使用的是 HTTP 401 認證方式。

### Step 4：控制流程

將上述的寫法，重構為更清楚的「流程」觀念：

```
app.get('/hello', express.basicAuth('jollen', 'abcdef'));
app.get('/hello', hello.index);
```

這其實是較為常見，而且更好的寫法。觀念整理如下：

- 請注意，過去將第 2 個參數解釋為 URL Routing 的 Handler，在這裡則是解釋為 Middleware
- 所以，'/hello' 現在有 2 個 Middleware
- 瀏覽 URL 時，依「順序」來呼叫 Middleware
- 順序指的是程式碼的寫法順序
- *basicAuth()* 先被呼叫
- *basicAuth()* 會進行使用者驗證
- 如果驗證成功，就會呼叫 *next()* 進到下一個「流程」
- 下一個「流程」就是 *hello.index* 函數

這是 Express.js Middleware 的基本觀念，也是初學者必學的主題。

## Middleware 與流程控制

Express.js 使用 Middleware 來實作流程控制，我們可以發揮一些巧思，讓流程控制的程式碼邏輯更優雅。比如說，'/hello' 現在的流程是：

1. 使用者驗證
2. 進行一些環境設定的調整
3. 送出頁面

如果使用典型的 if...else... 來實作，肯定會寫出很醜的 Node.js 程式碼。反之，利用 Middleware 的觀念來實作，不但觀念簡單，程式碼也更優雅：

```
app.get('/hello', express.basicAuth('jollen', 'abcdef'));
app.get('/hello', hello.config);
app.get('/hello', hello.index);
```

完整的 *hello.js* 如下：

{title="hello.js"}
```
1 exports.index = function(req, res, next) {
2   res.render('hello');
3 };
4 
5 exports.config = function(req, res, next) {
6   console.log("Do some configs here...");
7   next();
8 };
```

使用者通過驗證後，會進到 *hello.config* 流程。重要的觀念補充如下：

- 在 *hello.config* 裡要記得呼叫 *next()*
- 請注意，以上 2 個暱名函數都加上了第 3 個參數 *next*，成為 Middleware

Express.js Middleware 很像是 URL 的 Plugin，例如上述的範例，可以想像成是在 '/hello' 裡，加入 *hello.config* 的插件。

以下是截至目前為止，最新版本的 *app.js*。

{title="app.js"}
```
 1 var express = require('express');
 2 var routes = require('./routes');
 3 var user = require('./routes/user');
 4 var http = require('http');
 5 var path = require('path');
 6 var hello = require('./routes/hello');
 7 
 8 var app = express();
 9 
10 // all environments
11 app.set('port', process.env.PORT || 3000);
12 app.set('views', path.join(__dirname, 'views'));
13 app.set('view engine', 'jade');
14 app.use(express.favicon());
15 app.use(express.logger('dev'));
16 app.use(express.json());
17 app.use(express.urlencoded());
18 app.use(express.methodOverride());
19 app.use(app.router);
20 app.use(express.static(path.join(__dirname, 'public')));
21 
22 // development only
23 if ('development' == app.get('env')) {
24   app.use(express.errorHandler());
25 }
26 
27 app.get('/', routes.index);
28 app.get('/users', user.list);
29 
30 app.get('/hello', express.basicAuth('jollen', 'abcdef'));
31 app.get('/hello', hello.config);
32 app.get('/hello', hello.index);
33 
34 http.createServer(app).listen(app.get('port'), function(){
35   console.log('Express server listening on port ' + app.get('port'));
36 });
```

目前為止的範例，都是為特定的 URL 來撰寫 Middleware。

## 使用 *app.use()* 撰寫 Middlware

Express.js 的 Middleware，也能針對所有的 URL，方式是使用 *app.use()* 函數。例如，我想為「所有的 URL」加上使用者認證的「流程」，做法非常簡單。以下是修改後的 *app.js*：

{title="app.js"}
```
 1 var express = require('express');
 2 var routes = require('./routes');
 3 var user = require('./routes/user');
 4 var http = require('http');
 5 var path = require('path');
 6 var hello = require('./routes/hello');
 7 
 8 var app = express();
 9 
10 // all environments
11 app.set('port', process.env.PORT || 3000);
12 app.set('views', path.join(__dirname, 'views'));
13 app.set('view engine', 'jade');
14 
15 app.use(express.favicon());
16 app.use(express.logger('dev'));
17 app.use(express.json());
18 app.use(express.urlencoded());
19 app.use(express.methodOverride());
20 app.use(express.basicAuth('jollen', '654321'));
21 app.use(app.router);
22 app.use(express.static(path.join(__dirname, 'public')));
23 
24 // development only
25 if ('development' == app.get('env')) {
26   app.use(express.errorHandler());
27 }
28 
29 app.get('/', routes.index);
30 app.get('/users', user.list);
31 
32 app.get('/hello', hello.config);
33 app.get('/hello', hello.index);
34 
35 http.createServer(app).listen(app.get('port'), function(){
36   console.log('Express server listening on port ' + app.get('port'));
37 });
```

各位是否能看出當中的細節？說明如下：

- 第 20 行，使用 *app.use()* 來加入 *basicAuth()* Middleware，表示針對所有的 URL
- 第 21 行，為所有 URL 加入了 URL Rounter，*app.router* 是 Express.js 內建的 URL Router
- 第 20 行與第 21 行，依照「流程」的邏輯，應該是先進入 *basicAuth()* 流程，再到 URL Routing 的流程
- 如上，也就是說，這 2 行的順序是不能修改的，否則就會變成「先做 URL Routing、再做使用者驗證」的錯誤

此外，我們也發現，Express.js 預設加入了這些 Middleware：

```
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
```

*express.static()* 這個 Middleware 是用來指定 "Static Files" 的路徑。典型的 Use Case 是將 Static Files 放在 public/ 目錄下，比如，瀏覽器送出這個請求：

```
GET /style.css
```

當 *app.router* 無法處理這個檔案的 Routing 時，就會進到 *express.static()* 流程，這時 Express.js 會到 *public/* 子目錄下搜尋這個檔案，最後將 *public/style.css* 送出。Static files 一般指的是 CSS、JavaScript、圖片、影片、靜態 HTML 文件等。

Middleware 的「順序」，非常的重要。所有的 Middleware 都是依照寫作順序逐一呼叫。通常，較早先被使用的 Middleware 為 *express.logger()*，這是 Middleware 的 Log System，用來紀錄 HTTP 的請求。

由上述程式碼的順序來看，*express.logger()* 會紀錄下幾乎所有的資訊，包含 HTTP 請求、送出的 Static Files 等。如果不想把 Static Files 放到紀錄訊息裡呢？只要調整其順序即可：

```
app.use(express.favicon());
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.logger('dev'));
```

這個順序，可以讓 *express.logger()* 紀錄最少量的資訊。

## 常用的 Express.js Middleware

以下介紹幾個經常使用的 Middleware。

### 使用 *compress()*

Express.js 內建 *express.compress()* Middleware，這個 Middleware 可以把 Response Data 壓縮，節省網路頻寬，當然也就縮短 Response Data 所需的時間。修改後的程式碼如下：

```
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.compress());
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(express.basicAuth('jollen', '654321'));
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
```

請注意，*express.compress()* 的順序要放在比較前面。

### 使用 *cookieParser()*

這是一個用來處理 HTTP Cookies 的 Middleware。它可以協助我們解析 Cookies，並將所有的 Cookies 放在 *req.cookies* 物件（Key-Value Pairs 格式）。寫法如下：

```
app.use(express.cookieParser());
```

比如說，有一個 Cookies 叫做 *purchase_id*，使用這個 Middleware 就可以透過 *req.cookies.purchase_id* 讀取該 Cookies 的值。

### 使用 *cookieSession()*

提供 Sessions 機制的 Middleware。為 *app.js* 加入 Sessions 功能：

```
app.use(express.cookieSession());
```

因為 Express.js 的 Sessions 是建構在 Cookies 的機制之上，所以為了防止 Sessions 被不當修改，可以傳入 *secret* 參數：

```
app.use(express.session({
    secret: 'N1j2o3l4l5e6n7'
}));
```

此外，也可以設定 Cookies 的屬性：

```
app.use(express.session({
    secret: 'N1j2o3l4l5e6n7',
    cookie: { path: '/', httpOnly: true, maxAge: null }
}));
```

上述設定是原本的預設值。

## 結論

Node.js + Express.js 初學者，務必了解 Middleware 的觀念，並且學會使用 Middleware 做流程控制。關於 Middleware 的實作，可分為特定 URL 與所有 URL，這是 Express.js 開發的基本功。網路上有一些支援 Express.js 的 Workflow 模組，也都是基於 Middleware 的觀念來實作。
</script>]]>
      
   </content>
</entry>
<entry>
   <title>Publish Early 早期出版新文化</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2013/10/publish-early.html" />
   <id>tag:www.jollen.org,2013:/blog//2.801</id>
   
   <published>2013-10-25T05:02:16Z</published>
   <updated>2014-04-15T20:36:04Z</updated>
   
   <summary>本文章採用 Markdown 語法撰寫（why?），若無法閱讀內文，請點擊這裡。 資訊圖書的出版要進入一個新時代了。因為資訊科技進步神速，以及開放內容（Open Content）的推波助瀾，過去資訊相關圖書的出版模式將再次改變。 過去最明顯的現象就是專業電腦書的輕薄化。輕薄化有二個意涵：第一、內容簡明扼要，甚致沒有太多的鋪陳，讀者的背景知識必須充份；第二、頁數變少，過去幾年，新技術的電腦書，或是主題限定在一定範圍的電腦書，頁數大多維持在 200 頁附近。 輕薄短小、簡潔有力 對筆者來說，這種輕薄化的電腦書，可以帶來無比舒適，以及有效率的閱讀。雖然這類型電腦書的頁數少，但內容可不簡單，不但意簡言賅，直達技術的核心，對於重要觀念的講解，也相當精確。當然，閱讀這種電腦書，就要具備一定的背景知識。 現在，由於技術進步更快，使得寫作到實體出版的速度遠不及技術的變化。實體書已經無法扮演傳播知識的良好角色了。所以，現在我們可以看到資訊出版再度進入新的轉變期。一個是電子書與自助出版的盛行。例如：Amazon Single 可以提供作者一個自助出版的管道。另一個則是 Micro Book 概念的出現。Amazon Single 的出現，其實也是想幫助作者出版 Micro Book 作品。 以電子書、電子出版與微型書的模式，讓知識能快速傳遞到讀者手上，這種新的出版模式，才能跟上技術的快速變化。 ## 微型書 近二年來，電腦出版業似乎出現一波微型書（Micro Book）的出版風潮。所謂的微型書，就是頁數介於 50-80 頁的電腦書。這類型的電腦書，一般都是先採取電子書或電子出版形式，最後出版商再印製實體書上架販售。 Micro Book 本身的文字內容，大多在網路上能免費取得，但網路上的文章形式過於鬆散，所以 Micro Book 在這個時代，有另外一種價值。台積長董事長張忠謀先生，在 2000 年一場講座中說：「網路無益於知識的累積。」如果我們要讓網路上的內容 （Content）變成自已的知識（Knowledge），系統化地整理並編篆這些免費內容是很重要的工作。 就是因為免費內容太多，我們更需要專家為我們去整理並編篆這些內容，Micro Book 就是一個很好的解決方案，因為它的出版相當快速（一般是三個月內），不必等到完整的書寫完後再出版（可能費時一年），甚致可以做到隨時改版（Publish...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本文章採用 Markdown 語法撰寫（<a href="http://www.jollen.org/blog/2014/04/use-markdown-syntax.html" target="_blank">why?</a>），若無法閱讀內文，請點擊<a href="http://www.jollen.org/blog/2013/10/publish-early.html">這裡</a>。

<script id='markdown', type='text/plain'>
資訊圖書的出版要進入一個新時代了。因為資訊科技進步神速，以及開放內容（Open Content）的推波助瀾，過去資訊相關圖書的出版模式將再次改變。

過去最明顯的現象就是專業電腦書的輕薄化。輕薄化有二個意涵：第一、內容簡明扼要，甚致沒有太多的鋪陳，讀者的背景知識必須充份；第二、頁數變少，過去幾年，新技術的電腦書，或是主題限定在一定範圍的電腦書，頁數大多維持在 200 頁附近。

<h2>輕薄短小、簡潔有力</h2>

對筆者來說，這種輕薄化的電腦書，可以帶來無比舒適，以及有效率的閱讀。雖然這類型電腦書的頁數少，但內容可不簡單，不但意簡言賅，直達技術的核心，對於重要觀念的講解，也相當精確。當然，閱讀這種電腦書，就要具備一定的背景知識。

現在，由於技術進步更快，使得寫作到實體出版的速度遠不及技術的變化。實體書已經無法扮演傳播知識的良好角色了。所以，現在我們可以看到資訊出版再度進入新的轉變期。一個是電子書與自助出版的盛行。例如：Amazon Single 可以提供作者一個自助出版的管道。另一個則是 Micro Book 概念的出現。Amazon Single 的出現，其實也是想幫助作者出版 Micro Book 作品。

以電子書、電子出版與微型書的模式，讓知識能快速傳遞到讀者手上，這種新的出版模式，才能跟上技術的快速變化。

## 微型書

近二年來，電腦出版業似乎出現一波微型書（Micro Book）的出版風潮。所謂的微型書，就是頁數介於 50-80 頁的電腦書。這類型的電腦書，一般都是先採取電子書或電子出版形式，最後出版商再印製實體書上架販售。

Micro Book 本身的文字內容，大多在網路上能免費取得，但網路上的文章形式過於鬆散，所以 Micro Book 在這個時代，有另外一種價值。台積長董事長張忠謀先生，在 2000 年一場講座中說：「網路無益於知識的累積。」如果我們要讓網路上的內容 （Content）變成自已的知識（Knowledge），系統化地整理並編篆這些免費內容是很重要的工作。

就是因為免費內容太多，我們更需要專家為我們去整理並編篆這些內容，Micro Book 就是一個很好的解決方案，因為它的出版相當快速（一般是三個月內），不必等到完整的書寫完後再出版（可能費時一年），甚致可以做到隨時改版（Publish Often）的服務。花一年去編寫並出版的實體電腦書，等到上市後，不但內容也老了（這一點都不誇張），而且技術人員根本等不及它的出版。

微型書是技術工程人員的寶物，它能幫助我們將免費內容形成個人的知識。因為免費內容太多，微型書能讓技術學習者接軌這些免費內容，這是一個免費內容的新時代，微型書有著它的時代價值。

## Publish Early, Publish Often

軟體技術的更新速度很快，微型書不但能快速出版，傳遞新知識到每個人手上，也能節省學習者的時間。目前網路上有許多 E-Book 的出版平臺，上面出版的電腦書，很多都是非常新的主題，而且篇幅都不長。這對新知識的吸收很有幫助。

在 Leanpub 上面可以找到很多「寫作中的書」，讀者可以先購買寫作中的書，提早學習新知識。這種讀書與寫書的新文化，頗值得推廣。筆者不只開始養成閱讀這些「早期出版」圖書的習慣，也開始對創作早期出版品產生興趣。

筆者開始在 Leanpub 的平臺上，[<a href="https://leanpub.com/u/jollen" target="_blank" rel="nofollow">嚐試進行早期寫作</a>]，將原本部落格式的寫作，轉移成書藉的寫作習慣。這樣的轉變目的，是希望讓寫作的結構更好，成為優質寫作者。
</script>]]>
      
   </content>
</entry>
<entry>
   <title>深入淺出 JavaScript Lambda</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2013/10/javascript-lambda.html" />
   <id>tag:www.jollen.org,2013:/blog//2.818</id>
   
   <published>2013-10-17T16:57:32Z</published>
   <updated>2014-04-15T20:34:38Z</updated>
   
   <summary> 註：本文節錄自「Node.js &amp; HTML5 開發思惟與入門學習」一書，並原文重現。 本章的目標，是提昇初學者的開發功力。經過前面 4 個章節的介紹，學習到許多基本觀念與技術。接下來，將從三個不同的層面，深化目前所學到的觀念與技術： JavaScript 語言 Web Service 架構 Node.js 觀念 本章先從 JavaScript 語言開始。JavaScript 最重要的觀念是 Closure，這可以說是 JavaScript 初學者的第 1 堂。Closure 與暱名函數有很緊密的關係，這要由 Lambda 的觀念開始講起。 Lambda Lambda（λ）是一個希臘字母（Λ 是它的大寫字母），用來表示許多觀念： 物理學家用來表示波長的符號 數學家用來表示空字串的符號 電腦科學家用來表示暱名函數（Anonymous Function）的符號 Lambda 在電腦科學領域，用來表示暱名函數，目的是進行運算。為了尋找一個語法簡易的運算表示方式，電腦科學家會這麼做。 Step 1：取得一個具名的函數 例如一個加法函數： sum(x)...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Node.js &amp; RESTful" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<div class="wiki-page"> 

<p>註：本文節錄自「<a href="https://leanpub.com/html5-javascript-thinking" target="_blank">Node.js & HTML5 開發思惟與入門學習</a>」一書，並原文重現。</p>

<p>本章的目標，是提昇初學者的開發功力。經過前面 4 個章節的介紹，學習到許多基本觀念與技術。接下來，將從三個不同的層面，深化目前所學到的觀念與技術：</p>
<ul>
<li>JavaScript 語言</li>
<li>Web Service 架構</li>
<li>Node.js 觀念</li>
</ul>
<p>本章先從 JavaScript 語言開始。JavaScript 最重要的觀念是 Closure，這可以說是 JavaScript 初學者的第 1 堂。Closure 與暱名函數有很緊密的關係，這要由 Lambda 的觀念開始講起。</p>
<h2>Lambda</h2>
<p>Lambda（λ）是一個希臘字母（Λ 是它的大寫字母），用來表示許多觀念：</p>
<ul>
<li>物理學家用來表示波長的符號</li>
<li>數學家用來表示空字串的符號</li>
<li>電腦科學家用來表示暱名函數（Anonymous Function）的符號</li>
</ul>
<p>Lambda 在電腦科學領域，用來表示暱名函數，目的是進行運算。為了尋找一個語法簡易的運算表示方式，電腦科學家會這麼做。</p>
<h3>Step 1：取得一個具名的函數</h3>
<p>例如一個加法函數：</p>
<pre><code>sum(x) = x + 2
</code></pre>

<p>函數 sum() 是具名函數，利用 JavaScript 來實作的話，寫法如下：</p>
<pre><code>function sum(x) {
     return x + 2;
}
</code></pre>

<h3>Step 2：改寫為暱名函數</h3>
<p>Lambda 希望可以找到一個能運算的表示方法，而且要簡單，去除掉函數名稱，就是一個方式。沒有具體名稱的函數，就稱為暱名函數（Anonymous Function）。如果表示暱名函數呢？上述範例，以 Lambda 來表示的話，只要改寫成：</p>
<pre><code>λx.x + 2
</code></pre>

<p>用 JavaScript 來實作的話，要如何撰寫呢？方式如下：</p>
<pre><code>(function(x) {
     return x + 2;
})();
</code></pre>

<p>這就是第 1 章介紹的 Closure 觀念，最後加上的一對括號，稱為立即函數，意思是立即執行此暱名函數的意思。立即函數，以物件導向的角度來看，也可以解釋為立即實例化。</p>
<h3>Step 3：使用 <em>var</em> 來宣告暱名函數</h3>
<p>JavaScript 的 <em>var</em> 關鍵字用來宣告變數，所以也可以把暱名函數做為運算子（Operator）來宣告變數。例如：</p>
<pre><code>var lambda = (function(x) {
     return x + 2;
})();
</code></pre>

<p>變數 <em>lambda</em> 被指定（Assign）為一個暱名函數。從 JavaScript 語言的角度來看，Closure 用來封裝出 Module，所以 <em>lambda</em> 變數也可以解釋成「一個模組」。宣告一個暱名函數的變數時，可以不需要 Closure。也可以採用以下的寫法：</p>
<pre><code>var lambda = function(x) {
     return x + 2;
};
</code></pre>

<p>事實上，這個寫法更為普遍。一些文章也把這種寫法，稱做 Function Expressions。</p>
<p>有一個重要的觀念要釐清，上述的寫法，正規的解釋方式是「宣告暱名函數的變數」，所以 <em>lambda</em> 是一個變數，不能解釋為函數。如果說 <em>lambda</em> 是一個函數宣告，觀念上就不對了。不能單就 JavaScript 語法的角度來做解釋。</p>
<p>以 JavaScript 來說，函數宣告的寫法為：</p>
<pre><code>function lambda(x) {
     return x + 2;
};
</code></pre>

<p>這個時候，<em>lambda</em> 就是一個函數。那一種寫法比較好呢？理論上，採用暱名函數宣告的方式較佳，因為 JavaScript 本身是一種 Lambda 的程式語言。</p>
<h2>Callback Function</h2>
<p>Lambda 本質上是一種表示方法，用來表示 Input 與 Output。所以，要表示一個平方的運算的話，寫法如下：</p>
<pre><code>λx.x*x
</code></pre>

<p>這個運算式，也可以做為另一個 Lambda 式子的 Input，請看以下的說明。</p>
<h3>Step 1：撰寫第一個計算平方的 Lambda 表示式</h3>
<p>做法如下：</p>
<pre><code>λx.x*x
</code></pre>

<h3>Step 2：把上述的式子做為另一個 Lambda 的輸入</h3>
<p>有一個 f(x) = x + 2 的函數，用 Lambda 來表示的話，寫法如下：</p>
<pre><code>(λx.x+2)
</code></pre>

<p>如果要把 Step 1 的結果，做當上面式子的 <em>x</em>（輸入），合併後的寫法為：</p>
<pre><code>(λx.x*x)(λx.x+2)
</code></pre>

<p>讓我們來筆算看看：</p>
<ul>
<li>x = 3 時，λx.x*x 的 Output 為 9</li>
<li>9 做為 λx.x+2 的 Input，成為 9 + 2，Output 為 11</li>
<li>答案就是 11</li>
</ul>
<p>(λx.x*x)(λx.x+2) 等價於 9 + 2。</p>
<h3>Step 3：使用 JavaScript 來實作</h3>
<p>怎麼把 (λx.x*x)(λx.x+2) 寫成程式碼呢？非常簡單，由於 Output 就是返回值，所以等於「讓暱名函數的返回值，當做另一個暱名函數的參數」。程式碼如下：</p>
<pre><code>var lambda = function(x) { return x + 2 };
var result = lambda(function(x) { return x * x} (3) );

console.log(&quot;Result: &quot; + result);
</code></pre>

<p>這個輸出的輸出結果為 11。這可不是在賣弄程式碼，而是實現出 (λx.x*x)(λx.x+2) 這個 Lambda 演算。以暱名函數來表示 Lambda 是很常見的做法，但其實反應出 JavaScript 語法上的不足。如果能有一個更簡易的語法，讓我們表示 Lambda，這段程式碼就會比較精簡。</p>
<p>所以，這很可能要從修改 JavaScript 語法的角度，來做強化。未來，新的 ECMAScript（JavaScript 的語法標準）或許可以讓我們這樣寫程式：</p>
<pre><code>function(x) { return x + 2 }  // 複雜的寫法
x =&gt; x + 2                            // 希望可以有這種精簡的語法
</code></pre>

<p>再舉一個例子：</p>
<pre><code>var result = (x =&gt; x * x) 3;  // 左結合寫法，輸入值 3 放在最右邊，最後 result 為 9
</code></pre>

<p>如果將 Lambda 做為函數的參數：</p>
<pre><code>[1, 2, 3, 4, 5]
     .map(function(x) { return x * x });
</code></pre>

<p>未來或許能簡化為：</p>
<pre><code>[1, 2, 3, 4, 5]
     .map(x =&gt; x * x);             // 希望可以有這種精簡的語法
</code></pre>
 
<p>在 ECMAScript 還沒有正式加入相關語法前，我們目前還是只能使用暱名函數的寫法。</p>
<h2>使用 TypeScript</h2>
<p>在深入了解 Lambda 的觀念後，就能知道根本之道在於「新的 JavaScript 語法」。目前有一些 Open Source 程式庫，就試著在解決這個問題。唯有透徹底了解 Lambda 的觀念，才能知道這些程式庫目地何在。</p>
<p>筆者推薦的解決方案是：TypeScript。這是一個由 Microsoft 所開發的工具，實際上是一個 Compiler。TypeScript 提供了擴充的 JavaScript 語法，可藉由 TypeScript 編譯為標準的 JavaScript 語法。</p>
<p>首先，必須先使用 npm 安裝 TypeScript 工具：</p>
<pre><code>$ npm install -g typescript
</code></pre>

<p>接著，以 TypeScript 的語法撰寫 JavaScript 程式碼。TypeScript 的語法就是 JavaScript 語法，只是提供了許多好用的擴充語言，因此學習上並沒有障礙。以下是一個 TypeScript 範例：</p>
<pre><code>var square = (x) =&gt; x * x
console.log(square(3));
</code></pre>

<p>將程式碼儲存為 l.ts 後，再利用 TypeScript 編譯：</p>
<pre><code>$ tsc l.ts
</code></pre>

<p>編譯後可以得到 l.js 檔案，以下是 l.js 的內容：</p>
<pre><code>var square = function (x) {
    return x * x;
};
console.log(square(3));
</code></pre>

<p>看到編譯後的程式碼後，馬上可以反應出這個觀念：TypeScript 提供一個簡單好用的 Lambda 語法。當然，TypeScript 的功能很豐富，這只是牛刀小試。</p>

</div>]]>
      
   </content>
</entry>
<entry>
   <title>解讀三星的開放創新中心</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2013/09/samsung-open-innovation-center.html" />
   <id>tag:www.jollen.org,2013:/blog//2.820</id>
   
   <published>2013-09-27T03:57:02Z</published>
   <updated>2013-10-25T08:57:50Z</updated>
   
   <summary>文/Jollen Chen（原文刊載於 CTimes 雜誌 2013 年 10 月號） 自從三星將開放源碼做為軟體經營的主要戰略後，現在又更進一步，在矽谷設立開放創新中心（Samsung Open Innovation Center），藉此打造更大的人才平臺。三星的開放源碼戰略，仍至於開放創新中心，都圍繞在「人才」的層面。 三星在 2013 年 9 月 14 日於矽谷舉辦的「創業公司如何全球化」會議中提到，三星開放創新中心的工作，主要為創業加速器（accelerator）和投資。創業加速器與投資，很明顯就是從天使投資人的角度，成為創業者早期的投資人。 三星，一家已經是世界上最大的硬體製造公司，用微觀的角度，去做宏觀的事情。開放創新，將會是開放軟體後，另一個改變世界的力量。從 2013 年開始，第一波的網路創業潮開始，這一年可說是 Startup 元年；Startup 創業風潮，是開放創新的代表性文化。三星在成為世界的硬體巨獸後，還能保有如此膽大心細的公司文化，預見不久的未來，大約在 2013 下半年左右，第四代的新三星雛型將浮現；我們將能推斷，三星的下一波競爭力將建構在硬體結合創新的網路服務上。 軟體與硬體的整合，其戰場將更進一，延伸到軟體、硬體與服務的整合。2013 年出現大量的 Startup、天使投資機構與創業加速器，這個現象幾乎能斷定未來三年內，也就是 2014~2016 年間，將是網路產業的另一波革命。傳統的硬體製造商，面對新一波來勢兇兇的變革，要怎麼因應？筆者提出幾個建議： 1. 開放創新做為公司的經營戰略：這點與開放源碼的戰略地位相同，都在於「人才」的部份。傳統的招募制度，已經無法吸引到優秀的軟體人才；傳統的招募制度，可能完全失靈。 2. 經營開放創新業務：三星的開放創新中心，將開放創新中心做為一項業務。筆者認為這是相當可行的觀念，將「天使投資」與「收購」做為主要業務，不但能取得大量的外部創新資源，也能達到直接吸納（收編）人才的目的。 創業如果是開放創新的主要文化，我們就要把員工的觀念，提昇到創業者的層次；把專案的觀念，提昇到育成與加速器輔導的層次。最後，把收購做為是一項業務。在開放創新的生態體系中，創業家、天使投資人與收購者，是不可或許的三個元素。如今，能做為收購者的超大型企業，或是手上握有現金，具收購實力的中大型企業，將面臨市場開發飽和的問題；收購新創公司，將可成為成長的一個動力。 三星開放創新中心的 Marc Shedroff...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      文/Jollen Chen（原文刊載於 CTimes 雜誌 2013 年 10 月號）

自從三星將開放源碼做為軟體經營的主要戰略後，現在又更進一步，在矽谷設立開放創新中心（Samsung Open Innovation Center），藉此打造更大的人才平臺。三星的開放源碼戰略，仍至於開放創新中心，都圍繞在「人才」的層面。

三星在 2013 年 9 月 14 日於矽谷舉辦的「創業公司如何全球化」會議中提到，三星開放創新中心的工作，主要為創業加速器（accelerator）和投資。創業加速器與投資，很明顯就是從天使投資人的角度，成為創業者早期的投資人。

三星，一家已經是世界上最大的硬體製造公司，用微觀的角度，去做宏觀的事情。開放創新，將會是開放軟體後，另一個改變世界的力量。從 2013 年開始，第一波的網路創業潮開始，這一年可說是 Startup 元年；Startup 創業風潮，是開放創新的代表性文化。三星在成為世界的硬體巨獸後，還能保有如此膽大心細的公司文化，預見不久的未來，大約在 2013 下半年左右，第四代的新三星雛型將浮現；我們將能推斷，三星的下一波競爭力將建構在硬體結合創新的網路服務上。

軟體與硬體的整合，其戰場將更進一，延伸到軟體、硬體與服務的整合。2013 年出現大量的 Startup、天使投資機構與創業加速器，這個現象幾乎能斷定未來三年內，也就是 2014~2016 年間，將是網路產業的另一波革命。傳統的硬體製造商，面對新一波來勢兇兇的變革，要怎麼因應？筆者提出幾個建議：

1. 開放創新做為公司的經營戰略：這點與開放源碼的戰略地位相同，都在於「人才」的部份。傳統的招募制度，已經無法吸引到優秀的軟體人才；傳統的招募制度，可能完全失靈。

2. 經營開放創新業務：三星的開放創新中心，將開放創新中心做為一項業務。筆者認為這是相當可行的觀念，將「天使投資」與「收購」做為主要業務，不但能取得大量的外部創新資源，也能達到直接吸納（收編）人才的目的。

創業如果是開放創新的主要文化，我們就要把員工的觀念，提昇到創業者的層次；把專案的觀念，提昇到育成與加速器輔導的層次。最後，把收購做為是一項業務。在開放創新的生態體系中，創業家、天使投資人與收購者，是不可或許的三個元素。如今，能做為收購者的超大型企業，或是手上握有現金，具收購實力的中大型企業，將面臨市場開發飽和的問題；收購新創公司，將可成為成長的一個動力。

三星開放創新中心的 Marc Shedroff 說：「他認為做加速器、投資和收購已經不是三星的一個選擇，而已經是一項關鍵業務。」開放創業是一項業務（Business），所以三星與創業者之間，應該是一種生意關係。筆者認為，這是很合理的，這是一個很公平的 Win-Win 關係。

在開放創新的生態系統中，創業家、天使投資機構與收購者，是最主要的三個角色。預計從 2013 年底開始，這會是開放創新模式的主要商業模式；並且會持續至少五年的時間。現階段看來，三星不但掌握住了未來五年的產業主流價值，而且還在這個開放創新的主流價值浪潮中，扮演天使投資機構與收購者的雙重角色。
      
   </content>
</entry>
<entry>
   <title>改用 Client-Side Markdown Parsing</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2013/08/client-side-markdown-parsing.html" />
   <id>tag:www.jollen.org,2013:/blog//2.817</id>
   
   <published>2013-08-31T08:44:11Z</published>
   <updated>2013-10-14T20:42:55Z</updated>
   
   <summary>Markdown 的解析可以從 Server-side 來做，也可以由 Client-side 進行。如果是從 Server-side 來解析，我在目前專案裡採用的是 [marked]。這是很不錯的 Markdown parser，並且支援 [GitHub flavored markdown]。 Marked 也有一份 Client-side 的 port，稱為 [Strapdown.js]，Strapdown.js 也支援 GitHub flavored markdown。有於以下 3 個原因，後來我將 Server-side parsing 的做法，修改為 Client-side parsing： 1. UX - 原先採用 Server-side (RESTful) + Backbone way...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="HTML5 &amp; JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Markdown 的解析可以從 Server-side 來做，也可以由 Client-side 進行。如果是從 Server-side 來解析，我在目前專案裡採用的是 [<a href="https://github.com/chjj/marked" target="_blank">marked</a>]。這是很不錯的 Markdown parser，並且支援 [<a href="https://help.github.com/articles/github-flavored-markdown" target="_blank">GitHub flavored markdown</a>]。

Marked 也有一份 Client-side 的 port，稱為 [<a href="http://strapdownjs.com" target="_blank">Strapdown.js</a>]，Strapdown.js 也支援 GitHub flavored markdown。有於以下 3 個原因，後來我將 Server-side parsing 的做法，修改為 Client-side parsing：

1. UX - 原先採用 Server-side (RESTful) + Backbone way 的做法，使用者體驗比較不好

2. Better SEO - RESTful 與 Backbone way 的做法，使得 HTML 文件本身並不夾帶靜態文字，較不利於 SEO。雖然可以採用 Google 建議的方式，但會讓 URL 長的不好看

3. Editable - 將 markdown 以靜態方式放置在 HTML 文件裡，除了有利 SEO 外，未來也可以實用成 Client editable，讓 User 可以線上編輯 markdown 內容

目前，Server-side 的做法是利用 &lt;script> 標籤來放置 markdown 內文。

* Jollen's Blog 將透過 Booklog 平臺，將日誌以 Ebook 形式集結為更系統化的電子書，歡迎<a href="http://booklog.io" target="_blank">關注</a>。]]>
      
   </content>
</entry>
<entry>
   <title>Startup Engineering 演講</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2013/08/startup-engineering.html" />
   <id>tag:www.jollen.org,2013:/blog//2.816</id>
   
   <published>2013-08-26T15:22:15Z</published>
   <updated>2013-08-26T20:25:18Z</updated>
   
   <summary>我在 Android Day 2013 上的 [Keynote 演講]。 創業熱潮在全球發燒，並從網路、Apps延燒到開放硬體，如今，開發者不僅可以在應用上創新，成為創業家也不過是一線之隔。不過，從開發者到創業家，除了熱情，還需要具備更多條件。 《Startup Engineering》是Stanford大學所開的一門知名課程，目的是有系列的教導軟體創業的技術、設計、行銷與運籌。在這場演講中將剖析軟體創業不可不知的必要條件。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[我在 Android Day 2013 上的 [<a href="http://www.android-day.com/schedule.html" target="_blank">Keynote 演講</a>]。 創業熱潮在全球發燒，並從網路、Apps延燒到開放硬體，如今，開發者不僅可以在應用上創新，成為創業家也不過是一線之隔。不過，從開發者到創業家，除了熱情，還需要具備更多條件。 《Startup Engineering》是Stanford大學所開的一門知名課程，目的是有系列的教導軟體創業的技術、設計、行銷與運籌。在這場演講中將剖析軟體創業不可不知的必要條件。

<iframe class="imgur-album" width="100%" height="550" frameborder="0" src="http://imgur.com/a/s75C7/embed"></iframe>]]>
      
   </content>
</entry>
<entry>
   <title>談開放創新與管理：精實軟體開發</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2013/07/lean-software-development.html" />
   <id>tag:www.jollen.org,2013:/blog//2.815</id>
   
   <published>2013-07-28T13:40:41Z</published>
   <updated>2013-10-14T20:43:25Z</updated>
   
   <summary>文／Jollen Chen（原文刊載於 CTImes 雜誌，2013 年 8 月號） Lean Software Development，精實軟體開發。另一個開放創新與管理的支柱就是 Lean Software Development。Lean Sfotware Development 的概念源自日本 Toyota 的生產系統，後由 Agile 社群將之導入軟體工程領域，成為敏捷開發模式的重要思想基礎。在敏捷開發模式的發展過程中，Lean Software Development 的觀念不斷被討論；不久後，便由 Mary Poppendieck 與 Tom Poppendieck 將其發展成一套系統化的模式，Mary 與 Tom 同時也提出了 22 套工具，以落實 Lean Development。這是 Lean Software Development 的起源。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[文／Jollen Chen（原文刊載於 CTImes 雜誌，2013 年 8 月號）

Lean Software Development，精實軟體開發。另一個開放創新與管理的支柱就是 Lean Software Development。Lean Sfotware Development 的概念源自日本 Toyota 的生產系統，後由 Agile 社群將之導入軟體工程領域，成為敏捷開發模式的重要思想基礎。在敏捷開發模式的發展過程中，Lean Software Development 的觀念不斷被討論；不久後，便由 Mary Poppendieck 與 Tom Poppendieck 將其發展成一套系統化的模式，Mary 與 Tom 同時也提出了 22 套工具，以落實 Lean Development。這是 Lean Software Development 的起源。

直至今日，App 產業的成形，以及大量的創新網路服務被發展出來，又再強化了 Lean Software Development 的重要的。現在軟體產業，已由技術導向的行業，轉變為文化與創意的產業。因此，Lean Software Development 方法論，結合 Lean Startup 創業模式，成為重要的管理思想。

今日的軟體開發，講究精實模式（Lean Software Development），敏捷開發方法的 Kanban 方法論，部份相當符合精實模式的精神。Kanban 方法論追求打造一個自我組織型（Self-Organized）的研發團隊，且主要以外部開發者為主要資源。這一點與Chesbrough的理念不謀而合（Chesbrough 2006）。這個部份的管理經驗，是台灣各大硬體廠所久缺的重要元素。

Lean Software Development 的其中一個法則（Lean Principles）就是：滅少不必要的浪費，這點與精實創業（Lean Startup） 的觀念一致，也和原始 Toyota 的精實生產系統一致。這個觀念在許多討論 Lean Startup 的文章都有提到。對於新創團隊來說，所謂減少不必要的浪費，可以先以下二個角度開始。
creativeLabs Office

第一、避免不必要的內部溝通成本。Lean Startup 要表達的深層精神應該是：「先推出最有用的功能」，並專注服務固定的幾位使用者，讓第一批使用者滿足你所推出的產品。敏捷開發與 Lean Software Development 都提出實際的工具（有些工具指的是一套系統化方法），來幫助團隊解決這個問題。

第二、善用外部資源。以筆者近期的一個 Startup 計畫為例，將這個網站上線的硬體成本，大約只要美金300元左右；這與12年前的環境相差百倍以上。當時，我可能需要一個小型機房，或是 Co-Location 服務，加上頻寬費用，初期資金可不止要3萬塊美元。善用各種免費資源，或是付費服務（例如：Amazon EC2），都能減少不必要的浪費。另一個浪少良費與提昇效率的方式，就是使用開放源碼元件，這也是 Open Innovation 的核心觀念之一。

我看到有些現象是，新創公司盲目追求組織架構，許多傳統科技公司的新創過程，也太過於強調組織策略，這些經常埋下了日後的敗因。一個精實模式下的軟體開發，經常不需要依賴傳統的組織策略。對於經營 Startups 的團隊來說，在日後取得創投的資金浥注後，需要好好地思考這個議題。

例如，現在的組織策略，很難說明如何使用 Github 這樣的工具，創造成功的 Startup 計畫。更不用談，有些 Startup 團隊，更是以虛擬團隊的形式運作。在這裡提到的組織策略議題，並非要表達組織策略不具重要性，而是要強調如何採用新的管理方式來執行它：不能一味地 COPY 別人的組織結構與管理方法。

Lean Software Development 與 Lean Startup 同樣講求效率與消除浪費，如何善用現有的各項工具、技術與資源，以及導入新的管理方法與開發觀念，都是 Startup 團隊必須要不斷學習的新知識。到這裡就不難看出，Lean Software Developemnt 與 Open Innovation 的思考，是相輔相成的關係。 

* Jollen's Blog 將透過 Booklog 平臺，將日誌以 Ebook 形式集結為更系統化的電子書，歡迎<a href="http://booklog.io" target="_blank">關注</a>。]]>
      
   </content>
</entry>
<entry>
   <title>談開放創新與管理：外部的力量</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2013/06/open-innovation.html" />
   <id>tag:www.jollen.org,2013:/blog//2.814</id>
   
   <published>2013-06-27T11:28:12Z</published>
   <updated>2013-10-14T20:43:47Z</updated>
   
   <summary>文／Jollen Chen（原文刊載於 CTImes 雜誌，2013 年 7 月號） Open Innovation，開放創新。University of California, Berkeley 的 Henry Chesbrough 教授在他的著作 Open Innovation: The new imperative for creating and profiting from technology 裡提出了開放創新 (Open Innovation) 一詞。 Henry Chesbrough 教授目前是 University of California, Berkeley 的開放創新中心 (Center...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[文／Jollen Chen（原文刊載於 CTImes 雜誌，2013 年 7 月號）

Open Innovation，開放創新。University of California, Berkeley 的 Henry Chesbrough 教授在他的著作 Open Innovation: The new imperative for creating and profiting from technology 裡提出了開放創新 (Open Innovation) 一詞。 Henry Chesbrough 教授目前是 University of California, Berkeley 的開放創新中心 (Center for Open Innovation) 總監。開放創新從多個面象來探討研究與發展 (RD) 的新現象，當中最為人津津樂道的就是開放源碼 (Open Source) 文化。開放創新探討「創新」的新模式，其中最基本的課題就是，分析產業如何取得創新的泉源。

在 Chesbrough 教授的開放創新著作裡，特別討論到典型的內部 RD 團隊，不再是公司重要的策略資產，為什麼呢？主要的原因是網路與社群的興起，讓很大比例的創新是來自於公司外部，而不是公司內部。Hacker 文化則是主要的一個原因。八零年代開始，網際網路急速地發展。被稱為 Hacker 的軟體高手，透過網路集結並分享自已的軟體；其中有一個相當有代表性的人物，叫做Richard M. Stallman。他特別喜歡讓大家「自由地」使用或修改他的軟體，例如：GCC (Linux 與 Android 使用的編譯器)、GDB (Linux 與 Android 使用的除錯器) 等。

Richard Stallman的理念得到Hacker們的熱烈迴響。於是為了保障「使用與修改軟體」的「自由」，他成立了一個基金會，稱為「自由軟體基金會 (FSF, Free Software Foundation)」。FSF組成了一個律師團，擬定了一份保障「軟體使用與修改自由」的授權合約，供取得這些軟體的個人或廠商共同遵守，這份合約就是名聞遐邇的公眾授權條款 GPL (General Public License)。

在開放創新的討論裡，GPLv2 成為重要的議題，包括隨後而至的 Apache 授權條款，都是開放創新的源動力。Hacker、社群、GPLv2 與 Apache、自由軟體與開放源碼，都是開放創新的元素。以 GPL 授權釋出的開放源碼軟體，最知名的就是 Linux 作業系統核心。

這是 Hacker 文化下的代表性產物。透過網路的連結，Linux kernel由超過五十萬個開發者共同「集體創作」而成，這也是現今我們所熟知的「社群文化」。許多新技術與新概念，就在這個社群裡產生了，所以，許多大公司便開始參與 Linux 作業系統核心的開發社群，這些公司也 Donate 社群。

Chesbrough 教授在他的著作裡也提到，在開放創新的模式下，創新想法與 IP 的取得方式更為多樣化，其中一個方式便是透過 donation 的模式來取得。另一個知名的開放創新模式，稱為 Hackathon。1999 年開始了第一次的 Hackathon 活動，這是開發者的聚會，一些開發者聚集在一起，在很短的時間內，把想法撰寫成實際可執行的程式碼。

知名的 PhoneGap 專案，就是在某一次的 Hackathon 活動中誕生。PhoneGap 是開放式創新的代表性專案之一，IBM 曾贊助 PhoneGap 開發一段時間。PhoneGap 的開發團隊後來也成立公司，這家專門開發 PhoneGap 的開發商，後來被 Adobe 併購。

從 Dreamwaver 5.5 版開始，設計師可以利用網頁的模式來開發手機 App，這完全是 PhoneGap 專案的功勞。拜開放創新模式下產生的 PhoneGap 之賜，Adobe 的 Dreamwaver 產品線，取得了一些創新。從 Linux kernel 開始，到現在的 PhoneGap，這都不是任何一家公司的成果，這些都來自於外部的力量。難怪 Chesbrough 教授會這麼強調「外部的力量」。

近期筆者與幾家科技廠的高階主管，討論到開放創新的管理模式時，他們會認為這是一個有待證明的管理模式，並且因為這種模式過於鬆散，這種無法集中管理的專案，是不會成功的。可見這些傳統核板的管理思惟，已經成為台灣硬體產業轉型的障礙了。

* Jollen's Blog 將透過 Booklog 平臺，將日誌以 Ebook 形式集結為更系統化的電子書，歡迎<a href="http://booklog.io" target="_blank">關注</a>。]]>
      
   </content>
</entry>
<entry>
   <title>創業者也能扮演天使投資人</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2013/05/working-with-angel-funders.html" />
   <id>tag:www.jollen.org,2013:/blog//2.811</id>
   
   <published>2013-05-30T12:38:41Z</published>
   <updated>2013-10-14T20:44:11Z</updated>
   
   <summary>去年開始，我想在 Moko365 的基礎之上，以天使投資模式，從事一些專案開發工作，所以有一些朋友，以為我轉行做創投了。 但是天使投資對我來說，並不是投資行業，而是一種全新的創業形式。所以，我自已喜歡用 Startup 來對比天使投資（Angel investors）。 一個顛覆傳統的時代，是創業家的時代，現在就是一個傳統不斷被顛覆的時代，所以我相信，未來十年，甚至二十年的時間，創業家將不斷製造有用的創新產品或服務。而更彰顯這個時代特點的是軟體創新事業。如果你有一個想法，並且也有一筆很小的資金，你就可以很快推出軟體到市場上去測試顧客的反應。 於是，提供小額冒險資金的天使投資人，以及精實模式（Lean Startup）的概念，變成現在當紅顯學。所以，我的公司只要準備一筆小額的預算，就可以讓一個概念（Idea）付諸實行，或許是睹一把的心態，也或許是真正看好一個專案的潛力，但是本質上就是一個創業的行動。所以，天使投資對我來說，是一種創業的新模式，而不是創投行業。 許多人注意到這些不斷出現的新創公司，有它的獨特價值，所以願意透過小額投資的方式，去支持這些新創團隊。所以這有點像是掏金文化。小額出資者在創新軟體的世界，用力挖金礦，哪怕亂槍打鳥，壓對一個團隊，就像挖到黃金一樣，所有投資都能獲得巨大的回報。 近一年來，我也和許多創投或天使投資人接觸，個人非常認同天使投資人對新創企業的價值，在西方國家，有非常多成功的天使投資案；我發現，成功的天使投資人，他們和新創團隊站在一起，他們認為是和團隊共同在創業。這點非常的重要，把天使投資當做一個職業，把自已變成創業者之一，是天使投資者的精神。 天使投資者此刻是和創業團隊站在同一陣線，並且提供自已的人脈與經驗，這是天使投資的另一個精神，「扮演導師（Mentor）的角色」。我們會發現，有許多投資案，特別是在台灣，投資者（出資人、金主）與創業團隊，一開始就是一種對立的關係，並且在雙方利益談判上，互不相讓，這對軟體創業者來說，是一個不利的現象。所以雙方如果不能互讓一步，尋求合作、創造利益，金主就是在跟自已的錢過不去，創業家是和到手的機會過不去：變成二邊都是睹客，睹一把看看會不會中獎，公司會不會成功。 很令人興奮的事情在台灣發生了，過去台灣產業不具備天使投資環境，所以產業欠缺創造力，失去轉型能力；而現在，不斷有產業經驗豐富的天使投資者出現，並且積極尋找台灣與國外的投資對象。台灣政府對技術創業與新創事業，也提出了非常友善的政策。這或許能讓台灣從硬體製造的經濟，進入到軟體創新的經濟。 和天使合作 筆者在台灣接觸了許多天使投資人，或是天使投資團隊。我也在轉換自已的想法，以天使投資的角度，去看待自已未來的創業活動。同時，更希望未來能和更多的天使合作，並且也希望他們都能思考：天使投資也是自已在創業，是一種創業活動，而不是出資者。 軟體創業者在 Zero stage 時，找對天使投資者，會有很大的加分效果，因為等於你邀請了有影響力或豐富資源的伙伴，加入到創業團隊，成為創業者之一。浮士德的交易是將自已的靈魂交給魔鬼，以換取驚人的才華與能力，所以又叫魔鬼交易。 天使投資人與創業家並不是魔鬼交易的關係，所以創業家不是在把自已的靈魂出賣，換取資金與豐富的資源。所以在未來和天使們的合作過程中，我不會因為天使的個人喜好，去改變自已的信念，也不會動搖原有的核心價值，如果我是天使的身份，我也不希望創業團隊，因我的個人喜好，失去自已的靈魂。如果不是這樣的話，天使就是魔鬼，我就是和魔鬼在做交易了；並且，原本想當天使的我，也成為魔鬼了。 * Jollen&apos;s Blog 將透過 Booklog 平臺，將日誌以 Ebook 形式集結為更系統化的電子書，歡迎關注。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[去年開始，我想在 Moko365 的基礎之上，以天使投資模式，從事一些專案開發工作，所以有一些朋友，以為我轉行做創投了。 但是天使投資對我來說，並不是投資行業，而是一種全新的創業形式。所以，我自已喜歡用 Startup 來對比天使投資（Angel <s>investors</s>）。

一個顛覆傳統的時代，是創業家的時代，現在就是一個傳統不斷被顛覆的時代，所以我相信，未來十年，甚至二十年的時間，創業家將不斷製造有用的創新產品或服務。而更彰顯這個時代特點的是軟體創新事業。如果你有一個想法，並且也有一筆很小的資金，你就可以很快推出軟體到市場上去測試顧客的反應。

於是，提供小額冒險資金的天使投資人，以及精實模式（Lean Startup）的概念，變成現在當紅顯學。所以，我的公司只要準備一筆小額的預算，就可以讓一個概念（Idea）付諸實行，或許是睹一把的心態，也或許是真正看好一個專案的潛力，但是本質上就是一個創業的行動。所以，天使投資對我來說，是一種創業的新模式，而不是創投行業。

許多人注意到這些不斷出現的新創公司，有它的獨特價值，所以願意透過小額投資的方式，去支持這些新創團隊。所以這有點像是掏金文化。小額出資者在創新軟體的世界，用力挖金礦，哪怕亂槍打鳥，壓對一個團隊，就像挖到黃金一樣，所有投資都能獲得巨大的回報。

近一年來，我也和許多創投或天使投資人接觸，個人非常認同天使投資人對新創企業的價值，在西方國家，有非常多成功的天使投資案；我發現，成功的天使投資人，他們和新創團隊站在一起，他們認為是和團隊共同在創業。這點非常的重要，把天使投資當做一個職業，把自已變成創業者之一，是天使投資者的精神。

天使投資者此刻是和創業團隊站在同一陣線，並且提供自已的人脈與經驗，這是天使投資的另一個精神，「扮演導師（Mentor）的角色」。我們會發現，有許多投資案，特別是在台灣，投資者（出資人、金主）與創業團隊，一開始就是一種對立的關係，並且在雙方利益談判上，互不相讓，這對軟體創業者來說，是一個不利的現象。所以雙方如果不能互讓一步，尋求合作、創造利益，金主就是在跟自已的錢過不去，創業家是和到手的機會過不去：變成二邊都是睹客，睹一把看看會不會中獎，公司會不會成功。

很令人興奮的事情在台灣發生了，過去台灣產業不具備天使投資環境，所以產業欠缺創造力，失去轉型能力；而現在，不斷有產業經驗豐富的天使投資者出現，並且積極尋找台灣與國外的投資對象。台灣政府對技術創業與新創事業，也提出了非常友善的政策。這或許能讓台灣從硬體製造的經濟，進入到軟體創新的經濟。

<strong>和天使合作</strong>

筆者在台灣接觸了許多天使投資人，或是天使投資團隊。我也在轉換自已的想法，以天使投資的角度，去看待自已未來的創業活動。同時，更希望未來能和更多的天使合作，並且也希望他們都能思考：天使投資也是自已在創業，是一種創業活動，而不是出資者。

軟體創業者在 Zero stage 時，找對天使投資者，會有很大的加分效果，因為等於你邀請了有影響力或豐富資源的伙伴，加入到創業團隊，成為創業者之一。浮士德的交易是將自已的靈魂交給魔鬼，以換取驚人的才華與能力，所以又叫魔鬼交易。

天使投資人與創業家並不是魔鬼交易的關係，所以創業家不是在把自已的靈魂出賣，換取資金與豐富的資源。所以在未來和天使們的合作過程中，我不會因為天使的個人喜好，去改變自已的信念，也不會動搖原有的核心價值，如果我是天使的身份，我也不希望創業團隊，因我的個人喜好，失去自已的靈魂。如果不是這樣的話，天使就是魔鬼，我就是和魔鬼在做交易了；並且，原本想當天使的我，也成為魔鬼了。

* Jollen's Blog 將透過 Booklog 平臺，將日誌以 Ebook 形式集結為更系統化的電子書，歡迎<a href="http://booklog.io" target="_blank">關注</a>。]]>
      
   </content>
</entry>
<entry>
   <title>瀏覽器引擎的黃金時代開始：Blink 出現、三星來了 </title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2013/04/blink-servo-war-of-rendering-engine.html" />
   <id>tag:www.jollen.org,2013:/blog//2.810</id>
   
   <published>2013-04-28T18:28:25Z</published>
   <updated>2013-04-28T23:35:57Z</updated>
   
   <summary>文／Jollen Chen（原文刊載於 CTimes 雜誌） Google 在 2013 年的 4 月份發佈了一則消息：將開發新的瀏覽器引擎。這是瀏覽器界的大事，這代表著瀏覽器競賽已經進入了一個新的里程碑。這個新的瀏覽器引擎稱為 Blink，不過它並不是全新的開發專案，Blink 是 WebKit 的一個分支。目前，最新版本的 Chrome 瀏覽器已經改採 Blink 引擎。 Blink 直接採用 WebKit 的原始程式碼，並不是從新做起。這叫人好奇 Google 為何不繼續在 WebKit 引擎上開發，卻硬是將 WebKit 給「fork」了出來？這是瀏覽器引擎的競爭下，一個積怨已久的問題，簡單來說，這是一個商業策略，並不是單純的技術考量。今年二月份，Opera 宣佈每個月有超過 3 億使用者，在使用它們的瀏覽器，同時，Opera 也將開始貢獻 WebKit 專案。這個事件應該是 Google 決定開啟 Blink 計畫的主因之一。 Apple 在...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="HTML5 &amp; JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      文／Jollen Chen（原文刊載於 CTimes 雜誌）

Google 在 2013 年的 4 月份發佈了一則消息：將開發新的瀏覽器引擎。這是瀏覽器界的大事，這代表著瀏覽器競賽已經進入了一個新的里程碑。這個新的瀏覽器引擎稱為 Blink，不過它並不是全新的開發專案，Blink 是 WebKit 的一個分支。目前，最新版本的 Chrome 瀏覽器已經改採 Blink 引擎。

Blink 直接採用 WebKit 的原始程式碼，並不是從新做起。這叫人好奇 Google 為何不繼續在 WebKit 引擎上開發，卻硬是將 WebKit 給「fork」了出來？這是瀏覽器引擎的競爭下，一個積怨已久的問題，簡單來說，這是一個商業策略，並不是單純的技術考量。今年二月份，Opera 宣佈每個月有超過 3 億使用者，在使用它們的瀏覽器，同時，Opera 也將開始貢獻 WebKit 專案。這個事件應該是 Google 決定開啟 Blink 計畫的主因之一。

Apple 在 2005 年公佈了 WebKit 原始程式碼，接著受到多家瀏覽器開發商採用，其中一個便是 Chrome。經過多年發展，WebKit 變成一個好用現成的瀏覽器引擎。於是，Opera 也開始採用，並貢獻程式碼。這豈不是 WebKit 引擎的一大勝利。眼看第一階段的瀏覽器引擎大戰，將由 WebKit 引擎勝出，Google 大概不會坐視不管，特別是 WebKit 引擎已經有超過 40% 的市場份額了。

Blink 似乎是為了與 WebKit 有所區隔，或說是為了與 Apple 切割的一個策略產品。但是，制衡 WebKit 並不是 Google 官方的解釋。根據 Google 的說法，Chrome 與 WebKit 的 multi-process 架構不同，讓二者結合只會增加軟體的複雜度，於是 Blink 專案誕生。不過，最後 Google 又提到，多個瀏覽器引擎的存在，可以改善整個 open web ecosystem 的體質，讓它更健康。無論是明示或暗示，這意謂著 Blink 專案同時有著技術上，以及商業上的考量。

回到行動瀏覽器，Opera 擁有這個市場的最多份額。隨著 Google 發佈 Blink 計畫，Opera 很快的也宣佈轉進 Blink 引擎。不管是巧合，還是特意安排，這都是 Blink 計畫的一大勝利：Google 毫不費力，便取得了在行動瀏覽器引擎的重要位子。瀏覽器引擎大戰最精采的一刻還沒結束，幾乎在同一時間，Mozilla 與三星也發佈消息，宣佈在 ARM 平臺上，合作開發新一代的瀏覽器引擎，稱為 Servo。Servo 引擎的重點是具備支援多核心 (Multi-Core) 架構的能力，並且已釋出原始程式碼。

三星的行動裝置多核心處理器，具有相當高的工藝水準，它的多核心軟體研發方面，也是兵強馬壯，實力堅強。因此，Servo 計畫的未來性更加吸引人。以技術能量來論，三星與 Mozilla 的 Servo 引擎，實力不輸 Blink 引擎。筆者認為，Servo 引擎的關鍵在於，三星能不能利用它在行動裝置市場的領先地位，將 Servo 推上一把，使它與 Opera 抗衡。

至於 Apple，此時也不必要有什麼動作，因為 Safari 瀏覽器與 iPhone 裝置是密不可分的關係，Safari 使用的是 WebKit 引擎，而行動版 Safari 瀏覽器的成敗，完全取決於 iPhone 與 iPad 裝置的銷售量。總結來看，瀏覽器引擎大戰，是要繼續三分天下了， 競爭者變成 WebKit、Blink 與 Servo。此外，還有一個影響因素是 HTML5 標準，這又是另一個層面的問題了。最後，此刻最傷腦筋的，應該是微軟。
      
   </content>
</entry>
<entry>
   <title>簡報：讓 HTML5 走進 IPTV Framework</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2013/04/html5-iptv-framework.html" />
   <id>tag:www.jollen.org,2013:/blog//2.809</id>
   
   <published>2013-04-23T05:21:01Z</published>
   <updated>2013-04-23T10:33:18Z</updated>
   
   <summary>Moko365 與 OESF 於 4/16 日舉辦一場有關 IPTV 的研討會，目的是探討 ITU-T 所制定的 H.762 標準。 H.762 技術採用部份 HTML5 標準，成為一個 IPTV 的互動多媒體環境。根據筆者近期的開發心得，H.762 對於 TV Apps 的開發仍有所不足，因此在這個演講裡，筆者分享了一些想法，並提出 H.762 的修正建議。這個修正建議，主要是希望能把 HTML5 技術帶入 IPTV Framework 裡。 對 IPTV 標準有興趣的朋友或廠商，歡迎多加交流。簡報網址如下： HTML5 in IPTV Framework...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="HTML5 &amp; JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Moko365 與 OESF 於 4/16 日舉辦一場有關 IPTV 的<a href="http://www.oesf-global.com/event/seminar-ip-tv-20130416-en/" target="_blank">研討會</a>，目的是探討 ITU-T 所制定的 H.762 標準。

H.762 技術採用部份 HTML5 標準，成為一個 IPTV 的互動多媒體環境。根據筆者近期的開發心得，H.762 對於 TV Apps 的開發仍有所不足，因此在這個演講裡，筆者分享了一些想法，並提出 H.762 的修正建議。這個修正建議，主要是希望能把 HTML5 技術帶入 IPTV Framework 裡。

對 IPTV 標準有興趣的朋友或廠商，歡迎多加交流。簡報網址如下：

<a href="http://www.slideshare.net/jollen/html5-iptvframework-r2">HTML5 in IPTV Framework</a>]]>
      
   </content>
</entry>
<entry>
   <title> SmartTV 與客廳：更大的 App 戰場、更多的商業模式</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2013/03/smart-tv-apps.html" />
   <id>tag:www.jollen.org,2013:/blog//2.807</id>
   
   <published>2013-03-01T09:06:16Z</published>
   <updated>2013-04-21T22:17:45Z</updated>
   
   <summary>文／Jollen Chen（原文刊載於 WIRED.tw） 今年（2013）是電視大戰的一年，不過身為軟體人與創業者，更關心的是另一個角度的問題：電視大戰，將會演變為客廳大戰，軟體與網路創業家們，你們是催手。 電視將不再只是電視機，從只是看電視頻道，到能連接網路；這樣的電視機就叫做 IPTV 或 SmartTV。 它正在走手機過去的發展道路。過去手機，從單純的通話功能，演變成現在的 SmartPhone。 IPTV 與 SmartTV 以模糊概念來說，都是「可以連到網路」的電視。不過就定義來看，這分屬於二種不同的產品概念。傳統的電視採用類比訊號方式傳送節目，而 IPTV 則是以數位方式傳送節目。所以，IPTV 就是我們經常聽到的數位電視。IPTV 透過數位機上盒（Set-top-box）來接收節目。Set-top-box 將接受到的數位內容，以 HDMI 輸出方式顯示在電視機上。 SmartTV 則是另一個概念。SmartTV 也稱做 Connected TV，即連網電視。SmartTV 本身內建一個作業系統（OS），這讓電視機本身很像是一台電腦。就像 SmartPhone 也內建作業系統，本身就是一台小型電腦一樣。根據 Wikpedia 上的定義，SmartTV 等於 SmartPhone。從這個角度來看，SmartTV 無疑是 SmartPhone 的延伸。 透過 IPTV 無法觀看網路電視（例如：PPS.TV），因為機上盒可能不支持。但透過 SmartTV，只要安裝...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[文／Jollen Chen（原文刊載於<a href="http://wired.tw/author/jollen-chen" target="_blank"> WIRED.tw</a>）

今年（2013）是電視大戰的一年，不過身為軟體人與創業者，更關心的是另一個角度的問題：電視大戰，將會演變為客廳大戰，軟體與網路創業家們，你們是催手。

電視將不再只是電視機，從只是看電視頻道，到能連接網路；這樣的電視機就叫做 IPTV 或 SmartTV。 它正在走手機過去的發展道路。過去手機，從單純的通話功能，演變成現在的 SmartPhone。

IPTV 與 SmartTV 以模糊概念來說，都是「可以連到網路」的電視。不過就定義來看，這分屬於二種不同的產品概念。傳統的電視採用類比訊號方式傳送節目，而 IPTV 則是以數位方式傳送節目。所以，IPTV 就是我們經常聽到的數位電視。IPTV 透過數位機上盒（Set-top-box）來接收節目。Set-top-box 將接受到的數位內容，以 HDMI 輸出方式顯示在電視機上。

SmartTV 則是另一個概念。SmartTV 也稱做 Connected TV，即連網電視。SmartTV 本身內建一個作業系統（OS），這讓電視機本身很像是一台電腦。就像 SmartPhone 也內建作業系統，本身就是一台小型電腦一樣。根據 Wikpedia 上的定義，SmartTV 等於 SmartPhone。從這個角度來看，SmartTV 無疑是 SmartPhone 的延伸。

透過 IPTV 無法觀看網路電視（例如：PPS.TV），因為機上盒可能不支持。但透過 SmartTV，只要安裝 PPS.TV 的 App，就可以連上網路看影片。這個情境又表達了 IPTV 與 SmartTV 的另外一個差異：SmartTV 有 SDK，可以撰寫 App，也可以安裝 App。Set-top-box 可不一定能辦到這件事。這意謂著「TV App programming」的時代悄然而至。

TV App 會是引燃客廳大戰的火苗。從產業觀點，電視已經不再只是單純的硬體製造業，也不單單只是供應鍊的問題。新的電視產業，會很像是這五年的 SmartPhone 產業，也有 App、也有社群、也有服務等等。台灣的硬體產業，勢必要儘快從這個新的角度去看 SmartTV，而不是在過去的製造與成本問題來看這個新機會。

另一方面，TV App 的開發，也多了另一個選擇，它就是 HTML5。簡單說，電視內建一個瀏覽器（TV Browser）來執行 HTML5 App，並存取網路服務。以 HTML5 來開發 TV App 或 TV Service，雖然說這不一定是強制的標準，但可能是最能創造商業價值的標準。

科技業的遊戲規則，有一個硬道理：標準本身好不好，技術含量高不高，都不重要。重要的是，標準能不能產出商業價值。這點在軟體的遊戲圏裡，更是攻不可破的道理。因此，ITU Telecommunication 標準組織，便制定了 H.760 系列的標準供電視行業使用。

以 H.762 來說，這是一個多媒體互動 App 的標準，而 H.762 便是採用了 HTML5 技術。 ITU Telecommunication 過去所制定的 H.264 標準，現在也成為重要的影音編解碼標準。簡單易懂的說法是，H.762 是 TV App 的國際標準。TV 也開始重視 App 開發了。

過去在手機 App 與網路奮戰的創業家們，SmartTV 來臨了，這不是一個新的戰場，而是我們所熟悉的 App 與網路的老戰場。SmartTV 讓軟體創業家的戰場更大了些。過去做好的一些準備，或許在未來的 SmartTV 行業就可以開始收割了。

SmartPhone 有了 SDK 後，手機大戰開始。SmartTV 也有 SDK，可以安裝 App。一家人坐在客廳沙發上，將不只是對著 SmartTV 看節目。人類的客廳與居家生活形態也將產生很大的變化。SDK 與開發者，又將成為客廳大戰的催手。創業家也將在客廳裡，創造出更多的商業模式。]]>
      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] 關於 SurfaceFlinger::createSurface() 的 DisplayID</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2013/02/surfaceflinger-display-id.html" />
   <id>tag:www.jollen.org,2013:/blog//2.808</id>
   
   <published>2013-02-04T12:53:49Z</published>
   <updated>2013-04-21T22:16:30Z</updated>
   
   <summary><![CDATA[近期為幾家科技廠進行 Android 的企業內訓，課程主題著重於 Framework 層。最近的內訓主題是 Android Graphics 系統。今天 (2/4) 在講解 SurfaceFlinger Server 建立 Surface 時，提到這個方法： 1287 sp&lt;ISurface&gt; SurfaceFlinger::createSurface( 1288 ISurfaceComposerClient::surface_data_t* params, 1289 const String8& name, 1290 const sp&lt;Client&gt;& client, 1291 DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1292 uint32_t...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[近期為幾家科技廠進行 Android 的企業內訓，課程主題著重於 Framework 層。最近的內訓主題是 Android Graphics 系統。今天 (2/4) 在講解 SurfaceFlinger Server 建立 Surface 時，提到這個方法：

<p><pre>1287 sp&lt;ISurface&gt; SurfaceFlinger::createSurface(
1288         ISurfaceComposerClient::surface_data_t* params,
1289         const String8& name,
1290         const sp&lt;Client&gt;& client,
1291         DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1292         uint32_t flags)
</pre></p>

其中 DisplayID 參數的部份，代表 Screen。這部份可以參照 /system/lib/egl/egl.cfg 設定檔，例如，以下的設定：

<p><pre>0 1 qcom</pre></p>

第一個數字代表 Display，第二個數字代表 Implementation，最後的字串為 TAG，用來與 HGL 程式庫匹配。上述設定指定 Display 設定為 0，代表 Default (LCD)，有些 Android 系統可為 1，代表 HDMI。

此外，Display 參數在實例化 Layer 時也會用到：

<p><pre>1303     //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1304     sp&lt;Layer&gt; normalLayer;
1305     switch (flags & eFXSurfaceMask) {
1306         case eFXSurfaceNormal:
1307             normalLayer = createNormalSurface(client, d, w, h, flags, format);
1308             layer = normalLayer;
1309             break;
1310         case eFXSurfaceBlur:
1311             // for now we treat Blur as Dim, until we can implement it
1312             // efficiently.
1313         case eFXSurfaceDim:                                                
1314             layer = createDimSurface(client, d, w, h, flags);
1315             break;
1316         case eFXSurfaceScreenshot:
1317             layer = createScreenshotSurface(client, d, w, h, flags);
1318             break;
1319     }
</pre></p>

在實例化 Layer 時，可指定 Layer 的 Display。附帶一提，Android 的 Surface 分為四大類，一般 App 使用的是 Normal Surface，其它還有 Blur Surface、Dim Surface 與 Screenshot Surface。Dim Surface 是支援 Android Power Management (Wakelock) 的特殊 Surface。]]>
      
   </content>
</entry>
<entry>
   <title>鴻海「八屏一雲」計畫：導入 HTML5 與技術關鍵</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2013/01/foxconn-go-8panel.html" />
   <id>tag:www.jollen.org,2013:/blog//2.806</id>
   
   <published>2013-01-25T08:12:36Z</published>
   <updated>2013-01-25T15:15:56Z</updated>
   
   <summary>文／Jollen Chen（原文刊載於 CTimes 雜誌 2013 年 2 月份） 八屏一雲是鴻海科技集團擎畫的技術藍圖。鴻海科技集團協助 Moko365 舉辦 HTML5 相關課程，筆者有幸擔任系列課程的主要講師，在整理相關技術的過程中，得到了一些心得。使用 HTML5 做為八屏裝置的核心技術時，有什麼關鍵的地方要特別注意？筆者整理了幾個議題，在此與大家分享。 第一、跨裝置。這是第一個「八屏一雲」的重要技術工作。從技術的角度來說，「八屏一雲」，要能跨裝置（cross-device），而好的技術莫過於 HTML5。HTML5 是一個標準，透過此標準來開發 Web App；Web App 必須透過瀏覽器來執行。我們說，Web App 的執行環境（runtime）是瀏覽器。 第二、跨瀏覽器。 第二次瀏覽器大戰開始於2010年左右，大概是 HTML5 標準即將發佈，以及智慧型手機發展進入最高峰，二個時間的交匯點。現今，在 HTML5 世界裡，較具代表性的瀏覽器是 Firefox、Safari 以及 Chrome。 由於每一個瀏覽器實作 HTML5 標準的程度不一，並且實作上還會有一些小差異，因此，讓 Web App 能做到跨瀏覽器（cross-browser）成為另一個重要任務。還好，這個工作是階段性的，不過倒是能讓開發者忙碌很長一段時間。 第三、善用...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="HTML5 &amp; JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      文／Jollen Chen（原文刊載於 CTimes 雜誌 2013 年 2 月份）

八屏一雲是鴻海科技集團擎畫的技術藍圖。鴻海科技集團協助 Moko365 舉辦 HTML5 相關課程，筆者有幸擔任系列課程的主要講師，在整理相關技術的過程中，得到了一些心得。使用 HTML5 做為八屏裝置的核心技術時，有什麼關鍵的地方要特別注意？筆者整理了幾個議題，在此與大家分享。

第一、跨裝置。這是第一個「八屏一雲」的重要技術工作。從技術的角度來說，「八屏一雲」，要能跨裝置（cross-device），而好的技術莫過於 HTML5。HTML5 是一個標準，透過此標準來開發 Web App；Web App 必須透過瀏覽器來執行。我們說，Web App 的執行環境（runtime）是瀏覽器。

第二、跨瀏覽器。 第二次瀏覽器大戰開始於2010年左右，大概是 HTML5 標準即將發佈，以及智慧型手機發展進入最高峰，二個時間的交匯點。現今，在 HTML5 世界裡，較具代表性的瀏覽器是 Firefox、Safari 以及 Chrome。

由於每一個瀏覽器實作 HTML5 標準的程度不一，並且實作上還會有一些小差異，因此，讓 Web App 能做到跨瀏覽器（cross-browser）成為另一個重要任務。還好，這個工作是階段性的，不過倒是能讓開發者忙碌很長一段時間。

第三、善用 Media Query。這是 CSS3 裡的標準，簡單說，它可以幫助開發者自動偵測目前的裝置屬性，並且依不同的屬性來套用不同的 CSS 設計。為不同裝置撰寫不同的 CSS 樣式，並依裝置的不同來選取套用，這就是 Media Query 的功能。

很麻煩的是，現今的瀏覽器仍有 Media Query 支援不足的問題。例如：rem 單位在 Media Query 的區域裡可能失效。這是瀏覽器的不足，理論上未來的實作將會解決這些問題。目前，可以使用 JavaScript media query 的暫時替代方案。

第四、用對 UI Framework。在「八屏一雲時代來臨 教你HTML5六小時打通」課程裡，筆者整理了不只 20 種 UI Framework。以「cross device」做為題目，較廣為流行的是 Less Framework 4，它極為簡單易用。Less Framework 4 能幫助開發者生成支援不同裝置的 CSS Media Query。

但這些 UI Framework 在支援跨裝置方面仍有不足之處。以鴻海的八屏一雲理念來說，仍沒有一個 UI Framework 真正具備「跨八屏」的能力。這裡仍有許多技術工作，若鴻海能在這個部份投入資源，補足這個基礎建設，將會是很有價值的事情。

第五、瀏覽器作業系統化。從 Chrome 到 Firefox OS（前身為 Boot to Gecko），瀏覽器作業系統的發展，從沒有停滯過。Gecko 是 Firefox 的 HTML5/CSS 引擎，因此「Boot to Gecko」就是「一開始就是瀏覽器環境」的概念。

從工程的角度來看，Webkit 是一個很值得投資的瀏覽器引擎，它的發展始於 KDE 計畫，並吸引像是 Apple 這類型的知名企業加入。現在，Webkit 是一個很活躍的 Open source 計畫。許多知名的瀏覽器，例如：Safari，都採用 Webkit 做為其核心。

或許「Boot to Webkit」會是一個很好的創新研發題目，不管如何，具備維護 Webkit 引擎的能力，將可能是八屏一雲計畫的技術核心。

Moko365 與鴻海科技集團，從贊助免費 HTML5 課程開始，希望能逐步推廣 HTML5 技術與八屏一雲觀念。最後，八屏指的是哪八種不同的屏？手機屏、平板電腦、NB、AIO、Portable TV、TV、電子白板、LED顯示屏。
      
   </content>
</entry>
<entry>
   <title>第二個手機時代開始：2013 年觀察重點 </title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/12/smartphone-next-age-2013.html" />
   <id>tag:www.jollen.org,2012:/blog//2.805</id>
   
   <published>2012-12-30T04:07:03Z</published>
   <updated>2012-12-30T10:27:19Z</updated>
   
   <summary>文／Jollen Chen（原文刊載於 CTimes 雜誌 2013 年 1 月號） 幾個月前在這裡提到「手機業黃金五年結束」，意思是智慧手機產業初生的高速成長蜜月期，已經正式結束。這段時間是2008到2012年。手機業的營業利益率將開始下滑。 2012年底是很重要的一個時間點，三星以智慧型手機龍頭的頭銜，完美地在第一個時間的戰場，繳出漂亮的成績單。三星的Galaxy SII成功奪下第一個灘頭堡，宏達電也因此挨了不輕的一拳；延續Galaxy SII的氣勢，SIII更是打下iPhone，贏得智慧型手機的王座。 下一個智慧型手機的時期，筆者認為可能會是在2013~2015年。第二個智慧型手機時代開始了。2013年度到來，未來一年手機業的觀察重點為何，在此提出筆者的看法與大家分享。 第一、差距不至於再擴大。就如同大家所知的，智慧型手機的第一與第二戰線已經抵定，由Apple與Samsung形成的第一戰線，正與第二戰線的手機品牌擴大差距。從市場份額的角度來看，華為、中興、Sony、LG、HTC等第二戰場品牌的總合，還略小於50%。這種大者恆大的現象，應不至於再持續，原因Apple與Samsung的品牌成本效益將更顯著，從贏家的角度來看，爭奪市份份額可能不是第一要務，反倒是思考如何善用品牌成本效益。並且第二戰線的產品，具備多樣化的特性，在品質與性能方面也有顯著提昇，將更能滿足一般消費者的需求。 第二、品牌成本效益決定利潤。筆者認為，第二個智慧型手機的戰場，不能由硬體成本或是出貨量來觀察；在這個新戰場，利潤更有意義，裝置出貨數量只是配菜。台灣的硬體廠應該由品牌的角度來看手機市場，Apple將持續發揮它的品牌成本效益，而Samsung的品牌成本效益明年才正要開始爆發。在品牌效益的加持下，對手賣一支手機的成本是0.2台手機，但自已卻是賣一支手機要一支手機的成本，沒有品牌效益，何來高獲利。 關於品牌成本效益可由幾個消費者數字來觀察。根據近期調查，頂極手機的消費者詢問，Apple大約是33%、RIM大約是3%、Nokia大約是8%，HTC則是7%，至於Samsung，高達45%。以品牌的消費者滿意度來看， 根據近期調查，Apple大約是40%、Samsung大約是50%，而HTC則是大約5%。品牌效益創造獲利的第二個手機時代來臨。 第三、新手機生態系統出現。就如大家所知道的，除了Android與iOS外，微軟的Win8將可能成為第三個生態系統。 第四、人才搶奪戰。簡單說，就是App開發者的資源搶奪大賽。關於這一點，大家都有很深的感受，就不必多提了。但是有一個現象則是值得觀察，就是App開發者或開發商，同時為Android與iOS製作App的比例越來越高，這代表者只為單一作業系統製作App的問題並不存在。但是關鍵會在App開發者的獲利問題上，Google與Apple如何在廣告與下載二個模式外，為開發者創造新的獲利模型，可能成為第二個手機時代的關鍵。 歐洲接下來將可能釋出大量的優秀人才，以及更大量的開發者資源。台灣的產業應把這個議題列入第一要務。合宜的政策與合約架構，才是能吸引這些人才的關鍵。錯過了這次好機會，優秀軟體開發者大量出現的情況可能難以再見。 第五、大量的手機App新創公司。根據筆者的觀察與實地了解，如果你認為現在的手機App新創公司已經夠多了，那麼未來二年的Startups（新創公司）數量與實力可能另你瞠目結舌。這些新創公司的共同特色是走向精實模式，即小團隊、零固定成本、高毛利、更新速度極快、應變能力強、焦點式社群行銷等，另外團隊更年輕化也是一個趨勢。 第六、HTML5與瀏覽器時代。雖然這是在2012年，談了一整年的議題，不過還是有一點值得再次提醒。從開發的角度來看，社交網路（Social Networks）的加據發展，將使HTML5的技術更為重要。而HTML5的運行環境「瀏覽器」，也會有快速的進步與技術創新。 第七、多核App。顯然多核心已經成為手機應用處理器主流，不過，從技術的角度來看，多核心技術的重點在於App本身。雖然多核心技術涉及處理器、作業系統、Android 虛擬機技術、Android 框架等，但是App本身的設計是否能支持並發揮多核心特色，才是讓使用者最有直接感受的環節。簡單說，App開發「多核化」會是一個技術工作的重點。 鑑古知來，筆者整理過去一年的心得，希望能更了解第二個智慧型手機時代的發展格局；此外，還有一點，如同上一期評論提到的「精實消費時代」，一味地Cost Down，消費者可能未蒙其利，先受其害。 軟體團隊的更年輕化，在接下來幾年會更加明顯，以現況來看，大部份的新創軟體團隊，年齡大約在 23~30 歲之間，28 歲後的軟體開發者，更具備經營公司的能力；因此，如同筆者在 [我在 Android World 2012 深圳：與會心得分享] 一文所提，打造一個好的投融資環境，是留住人才的最佳方法。目前台灣的投融資環境來說，和大陸與東南亞相較，實屬不足，這點值得大家省考。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[文／Jollen Chen（原文刊載於 CTimes 雜誌 2013 年 1 月號）

幾個月前在這裡提到「<a href="http://www.jollen.org/blog/2012/07/goodbye-smartphone-gold-years.html">手機業黃金五年結束</a>」，意思是智慧手機產業初生的高速成長蜜月期，已經正式結束。這段時間是2008到2012年。手機業的營業利益率將開始下滑。

2012年底是很重要的一個時間點，三星以智慧型手機龍頭的頭銜，完美地在第一個時間的戰場，繳出漂亮的成績單。三星的Galaxy SII成功奪下第一個灘頭堡，宏達電也因此挨了不輕的一拳；延續Galaxy SII的氣勢，SIII更是打下iPhone，贏得智慧型手機的王座。

下一個智慧型手機的時期，筆者認為可能會是在2013~2015年。第二個智慧型手機時代開始了。2013年度到來，未來一年手機業的觀察重點為何，在此提出筆者的看法與大家分享。

第一、差距不至於再擴大。就如同大家所知的，智慧型手機的第一與第二戰線已經抵定，由Apple與Samsung形成的第一戰線，正與第二戰線的手機品牌擴大差距。從市場份額的角度來看，華為、中興、Sony、LG、HTC等第二戰場品牌的總合，還略小於50%。這種大者恆大的現象，應不至於再持續，原因Apple與Samsung的品牌成本效益將更顯著，從贏家的角度來看，爭奪市份份額可能不是第一要務，反倒是思考如何善用品牌成本效益。並且第二戰線的產品，具備多樣化的特性，在品質與性能方面也有顯著提昇，將更能滿足一般消費者的需求。

第二、品牌成本效益決定利潤。筆者認為，第二個智慧型手機的戰場，不能由硬體成本或是出貨量來觀察；在這個新戰場，利潤更有意義，裝置出貨數量只是配菜。台灣的硬體廠應該由品牌的角度來看手機市場，Apple將持續發揮它的品牌成本效益，而Samsung的品牌成本效益明年才正要開始爆發。在品牌效益的加持下，對手賣一支手機的成本是0.2台手機，但自已卻是賣一支手機要一支手機的成本，沒有品牌效益，何來高獲利。

關於品牌成本效益可由幾個消費者數字來觀察。根據近期調查，頂極手機的消費者詢問，Apple大約是33%、RIM大約是3%、Nokia大約是8%，HTC則是7%，至於Samsung，高達45%。以品牌的消費者滿意度來看， 根據近期調查，Apple大約是40%、Samsung大約是50%，而HTC則是大約5%。品牌效益創造獲利的第二個手機時代來臨。

第三、新手機生態系統出現。就如大家所知道的，除了Android與iOS外，微軟的Win8將可能成為第三個生態系統。

第四、人才搶奪戰。簡單說，就是App開發者的資源搶奪大賽。關於這一點，大家都有很深的感受，就不必多提了。但是有一個現象則是值得觀察，就是App開發者或開發商，同時為Android與iOS製作App的比例越來越高，這代表者只為單一作業系統製作App的問題並不存在。但是關鍵會在App開發者的獲利問題上，Google與Apple如何在廣告與下載二個模式外，為開發者創造新的獲利模型，可能成為第二個手機時代的關鍵。

歐洲接下來將可能釋出大量的優秀人才，以及更大量的開發者資源。台灣的產業應把這個議題列入第一要務。合宜的政策與合約架構，才是能吸引這些人才的關鍵。錯過了這次好機會，優秀軟體開發者大量出現的情況可能難以再見。

第五、大量的手機App新創公司。根據筆者的觀察與實地了解，如果你認為現在的手機App新創公司已經夠多了，那麼未來二年的Startups（新創公司）數量與實力可能另你瞠目結舌。這些新創公司的共同特色是走向精實模式，即小團隊、零固定成本、高毛利、更新速度極快、應變能力強、焦點式社群行銷等，另外團隊更年輕化也是一個趨勢。

第六、HTML5與瀏覽器時代。雖然這是在2012年，談了一整年的議題，不過還是有一點值得再次提醒。從開發的角度來看，社交網路（Social Networks）的加據發展，將使HTML5的技術更為重要。而HTML5的運行環境「瀏覽器」，也會有快速的進步與技術創新。

第七、多核App。顯然多核心已經成為手機應用處理器主流，不過，從技術的角度來看，多核心技術的重點在於App本身。雖然多核心技術涉及處理器、作業系統、Android 虛擬機技術、Android 框架等，但是App本身的設計是否能支持並發揮多核心特色，才是讓使用者最有直接感受的環節。簡單說，App開發「多核化」會是一個技術工作的重點。

鑑古知來，筆者整理過去一年的心得，希望能更了解第二個智慧型手機時代的發展格局；此外，還有一點，如同上一期評論提到的「精實消費時代」，一味地Cost Down，消費者可能未蒙其利，先受其害。

軟體團隊的更年輕化，在接下來幾年會更加明顯，以現況來看，大部份的新創軟體團隊，年齡大約在 23~30 歲之間，28 歲後的軟體開發者，更具備經營公司的能力；因此，如同筆者在 [<a href="http://www.jollen.org/blog/2012/11/android-world-2012-china.html">我在 Android World 2012 深圳：與會心得分享</a>] 一文所提，打造一個好的投融資環境，是留住人才的最佳方法。目前台灣的投融資環境來說，和大陸與東南亞相較，實屬不足，這點值得大家省考。]]>
      
   </content>
</entry>
<entry>
   <title>iPad Mini 或將終結這場瘋狂遊戲：精實化時代來臨</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/12/ipad-mini-leads-lean-consumption.html" />
   <id>tag:www.jollen.org,2012:/blog//2.804</id>
   
   <published>2012-12-29T09:02:29Z</published>
   <updated>2012-12-30T10:06:38Z</updated>
   
   <summary>文／Jollen Chen（原文刊載於 CTimes 雜誌 2012 年 12 月號） 2012 年的一個現象：全球手機廠都陷入了一個瘋狂競賽，更是一個瘋狂遊戲。Apple、Samsung 構成這個遊戲的雙軸心，在這二個軸心外環繞著許多品牌。這些品牌的瘋狂競賽就是瘋狂地製造 Android 手機與平板電腦，然而，Apple 與 Samsung 卻已悄悄改變行銷商品的方法，他們由大量消費的銷售方式，逐漸轉變為「精實」的做法。 我認為，iPad Mini 可能會開啟新的消費史。過去工業生產模式下的大量消費模式，如今可能因為 iPad Mini 的發表，讓人類逐漸進入硬體的精實消費時代。過去精實消費只存在內容、軟體與服務產業，現在可能更擴大到硬體消費上。這意味著硬體產業將發生以下二種情況： 第一、「以低價搶攻市場，進而促進銷售的增長」這個幾乎被認為是鐵律的法則將失效。市場上為數眾多的低價 Android 平板電腦將面臨滯銷。 iPad Mini 的定價出乎市場意料之外，並沒有採取低價策略。可是我們要知道，如果這樣的價格，並不能如 Android 陣營所願地「嚇跑消費者」，對非蘋陣營造成的後果將更加嚴重。非蘋陣營將面臨「產品懸崖」的困境：完全找不出能與 iPad Mini 對抗的策略，因為低價策略也無法提升銷售數字了。 第二、Android 應用程式獨立開發商，以及內容供應商，將被迫做出決擇：壓注 iOS 平臺，或是分散資源同時發展 iOS 與 Android...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      文／Jollen Chen（原文刊載於 CTimes 雜誌 2012 年 12 月號）


2012 年的一個現象：全球手機廠都陷入了一個瘋狂競賽，更是一個瘋狂遊戲。Apple、Samsung 構成這個遊戲的雙軸心，在這二個軸心外環繞著許多品牌。這些品牌的瘋狂競賽就是瘋狂地製造 Android 手機與平板電腦，然而，Apple 與 Samsung 卻已悄悄改變行銷商品的方法，他們由大量消費的銷售方式，逐漸轉變為「精實」的做法。

我認為，iPad Mini 可能會開啟新的消費史。過去工業生產模式下的大量消費模式，如今可能因為 iPad Mini 的發表，讓人類逐漸進入硬體的精實消費時代。過去精實消費只存在內容、軟體與服務產業，現在可能更擴大到硬體消費上。這意味著硬體產業將發生以下二種情況：

第一、「以低價搶攻市場，進而促進銷售的增長」這個幾乎被認為是鐵律的法則將失效。市場上為數眾多的低價 Android 平板電腦將面臨滯銷。

iPad Mini 的定價出乎市場意料之外，並沒有採取低價策略。可是我們要知道，如果這樣的價格，並不能如 Android 陣營所願地「嚇跑消費者」，對非蘋陣營造成的後果將更加嚴重。非蘋陣營將面臨「產品懸崖」的困境：完全找不出能與 iPad Mini 對抗的策略，因為低價策略也無法提升銷售數字了。

第二、Android 應用程式獨立開發商，以及內容供應商，將被迫做出決擇：壓注 iOS 平臺，或是分散資源同時發展 iOS 與 Android 平臺。

第二種現象對非蘋陣營更為不利，App 開發商枇杷別抱將對 Android 平板陣營造成莫大的傷害。不過，倒也不用過於悲觀，因為 Android 陣營在智能手機領域還是能擁有很大的優勢。iPad 開啟平板電腦之戰後，iPad Mini 是否能終結 Android 陣營加入平板戰場後所形成的混沌格局，讓我們繼續看下去。

一般看來，Android 平板電腦，已經有點「PC 化」，這多少和一開始 Android 陣營就以 PC 的觀點來開發平板電腦有關係。從這個角度來看，iPad Mini 更沒有必要直接和低價 Android 平板電腦競爭，只需要繼續走原本 iPad 的道路即可。

手機與平板已經不再是 PC 時代的硬體產品，所以相關產品的設計與開發都必須精緻且實用，售價固然是重要的因子，但只要合理，不需要低價，也能吸引特定的消費者。總結來說，大量消費時代下的銷售模式，低價必定能創造新的需求；這就像「老闆倒店了」的破盤價銷售模式。

筆者認為，這些製造與銷售低價 Android 平板的廠商，都應該清楚區分「需求」與「需要」的差別。 精實消費 (Lean Consumption) 的模式說明了一件事情：為什麼消費者寧可在誠品書店消費 300 元購買實體書，也不願意花費 49 元下載電子書。

蘋果已故執行長賈伯斯說：「消費者往往不知道自已真正的需求」，Android 低價平板陣營誤以為這是消費者的需求，然而，真正滿足他們需求的產品出現後，消費者才會突然了解自已的真正需求。這就是蘋果一向引人入勝的產品策略：告訴消費者這才是你的需求。

對於實體書來說，這是「需求」，因應考試、閱讀或上課等行為而生。電子書則是「需要」，在公車或捷運上為把握時間，有行動閱讀的需要而生。所以，如果只需要便宜、能用、易攜的平板電腦，Android 平板是好的選擇。然而，真正能滿足各方面需求的平板電腦，很可能只有 iPad Mini。

走向精實化的手機與平板電腦，老闆倒店的做法是否能行得通，就看 iPad Mini 幫我們解答了。筆者認為，低價 Android 平板因 iPad Mini 的出現，將正式面臨上述所提及的產品懸崖問題。iPad Mini 就像誠品的實體書，比較貴，但賣得比較多。
      
   </content>
</entry>
<entry>
   <title>我在 Android World 2012 深圳：與會心得分享</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/11/android-world-2012-china.html" />
   <id>tag:www.jollen.org,2012:/blog//2.803</id>
   
   <published>2012-11-30T14:15:48Z</published>
   <updated>2012-12-04T20:27:17Z</updated>
   
   <summary>文／Jollen Chen（原文刊載於 CTimes 雜誌 2012 年 11 月號） 筆者在 10/26 參加了由 IDG 美國國際數據集團主辦的 2012 Android World Global Developers Conference，原本是受邀發表演講，後來很認真聽了多場演講，相當有收獲，特別整理一些心得與觀察和大家分享。 圖：大會現場 IDG 過去在全球主辦的 Linux World 是非常知名的開發者大會，今年開始也啟動了 Android World 系列活動。Android World 第一次開辦就選擇在中國深圳，可見 IDG 對 Android 在中國發展的重視。根據現場工作人員表示，在網站上註冊的參加者有 1800 人。今天的會場是在深圳福田的香格里拉大酒店，主會場能容納 500 人；現場座無虛席，熱情的開發者填滿了整個會場。 一早來報到時，很認真研究了二天的議程表，我發現這次的活動有一個特色：完全沒有人談硬體；還有另外一個特色：現場設有投融資專區！有志創業的軟體高手，在現場就可以洽談投資了。 會場設置的投融資專區，有紅杉資本、同創偉業、IDG...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[文／Jollen Chen（原文刊載於 CTimes 雜誌 2012 年 11 月號）

筆者在 10/26 參加了由 IDG 美國國際數據集團主辦的 2012 Android World Global Developers Conference，原本是受邀發表演講，後來很認真聽了多場演講，相當有收獲，特別整理一些心得與觀察和大家分享。

<img src="http://www.moko365.com/enterprise/wp-content/uploads/misc/2012-10-26-09.52.03.jpg" />
圖：大會現場

IDG 過去在全球主辦的 Linux World 是非常知名的開發者大會，今年開始也啟動了 Android World 系列活動。Android World 第一次開辦就選擇在中國深圳，可見 IDG 對 Android 在中國發展的重視。根據現場工作人員表示，在網站上註冊的參加者有 1800 人。今天的會場是在深圳福田的香格里拉大酒店，主會場能容納 500 人；現場座無虛席，熱情的開發者填滿了整個會場。
 
一早來報到時，很認真研究了二天的議程表，我發現這次的活動有一個特色：完全沒有人談硬體；還有另外一個特色：現場設有投融資專區！有志創業的軟體高手，在現場就可以洽談投資了。

會場設置的投融資專區，有紅杉資本、同創偉業、IDG 資本、勝訊產業共贏基本、鼎暉創投、高原資本、松禾資本、凱鵬華盈等，不管是風險、投資或融資，來了很多專業的投資人。投融資專區設有「密談專區」，有創業需求的軟體開發人，都能直接找這些投融資人洽談。

早上的主題演講還有共同點：多位嘉賓不約而同都談到了開發者與投資這塊議題。最特別的是奇虎 360 的副總裁，他在演講裡提到：「能力越大、責任越大」，他的意思是奇虎創造了今天這樣的公司規模後，他們便開始扶植有能力的軟體開發者。至今他們已投資超過 50 個開發者，總金額在 2 億 (人民幣) 以上。相信這些種子將會成為未來中國軟體產業的重要生力軍。

奇虎 360 的李總裁又說，只要有能力的開發者，都可以找奇虎投資。我認為，「能力越大、責任越大」，是一種企業展現社會責任的表現，個人相當欣賞。台灣成功的企業，也應該學習這種格局，共創後才能共榮。李總裁現場也公開留下他的手機號碼，要有需要的開發者直接找他！果然是年輕創業家的風格，這是一種完全沒有身段的風範啊。

這次的 Android World 談的都是開發者、軟體或投資，完全嗅不到硬體的味道。現場軟體、網路與創業的氛圍濃厚，與台灣的產業味道全然不同。因此個人認為，要提昇台灣軟體產業的競爭力，應該要從投融資環境的角度著手，學習中國模式，由投融資環境，打造一個創業平臺，活化年輕軟體工程師的創業動力，藉由年輕人的創業活動來建立有競爭力的軟體產業。意思是，政府不能光靠蓋蓋軟體園區就能造出「軟體產業」，只有這批有能力的年輕人才能創造一個軟體產業。

下午則是分會場演講，我只能留在自已的演講會場。在我後面的幾位講者，談的正好是我最感興趣的主題：手機遊戲。觀察了今天的所有分會場後，發現主要的議題都環繞在以下三個主題：遊戲、移動廣告與移動閱讀。移動閱讀的部份讓我較感意外，這也是中國火熱發展的一個行業。移動閱讀最基本的形式就是電子書。

大會還規劃了一個專門討論遊戲的分會場。遊戲產業，可以說是今日大會的大亮點。以下是中國遊戲業者的經驗分享，在此列出重要的幾個結論。

第一、關於遊戲收費部份，Freemium 已經成為主流的收費模式。第二、手機遊戲的生命週期大約三個月左右（用戶把遊戲整個玩一遍的時間）。第三、透過任務系統、成就系統與道具系統，可以延長遊戲的生命週期。第四、傳統 RPG 遊戲的付費比例比較高。第五、遊戲運營，大約要投入 20% 的人力來評估用戶行為。第六、遊戲的運營如何運作，要根據收集到的數據來分析得知。第七、遊戲產業非常需要細緻化的運營。第八、便捷的支付管道是關鍵。

感覺中國的手機遊戲業發展非常快速，這些遊戲業者都有 1~2 年的經營經驗。對於有志初入手機遊戲的創業者，這些前輩的經驗是很寶貴的課程。]]>
      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] 讓 Android WebView 支援 WebSocket Client</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/10/android-webview-websocket-howto.html" />
   <id>tag:www.jollen.org,2012:/blog//2.802</id>
   
   <published>2012-10-19T03:48:19Z</published>
   <updated>2012-10-19T08:52:16Z</updated>
   
   <summary>Android 內建瀏覽器不支援 WebSocket Client 端，導致使用 HTML5 開發的 Apps 無法使用 WebSocket 與 Server 建立連線。主要的問題在於 WebView 元件沒有實作 WebSocket 協定。Android SDK + PhoneGap 所製作 HTML5 Apps 是將 WebView 封裝至 APK 裡，所以 WebSocket 無法正常工作是正常的。 不過這個問題也沒有那麼難解決，在等待 WebView 加入 WebSocket 以及更多 HTML5 功能前，我們只能暫時自行實作。還好，現在有很多 Open source 的...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="HTML5 &amp; JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Android 內建瀏覽器不支援 WebSocket Client 端，導致使用 HTML5 開發的 Apps 無法使用 WebSocket 與 Server 建立連線。主要的問題在於 WebView 元件沒有實作 WebSocket 協定。Android SDK + PhoneGap 所製作 HTML5 Apps 是將 WebView 封裝至 APK 裡，所以 WebSocket 無法正常工作是正常的。

不過這個問題也沒有那麼難解決，在等待 WebView 加入 WebSocket 以及更多 HTML5 功能前，我們只能暫時自行實作。還好，現在有很多 Open source 的 WebSocket 程式庫可供使用。在這裡推薦的是 [<a href="http://autobahn.ws" target="_blank">Autobahn WebSocket</a>]。

現在，只需要自行擴充 WebView，並使用 Autobahn WebSocket 來實作 WebSocket Client 即可。Android WebView 不支援 WebSocket 的問題解決了。在此提供一份簡單的程式碼實作：<a href="https://github.com/moko365/android-browser-websocket">android-browser-websocket</a>。


上述範例，亦使用於筆者的訓練課程「<a href="http://www.moko365.com/enterprise/html5-cloud-1-messenger-app">HTML5 與雲端技術教學: 六小時完成手機即時通APP</a>」。]]>
      
   </content>
</entry>
<entry>
   <title>宏碁與阿里雲事件附錄：到底，哪裡出錯了？從根本的 CTS 談起。</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/09/asus-aliyun-cts-issue.html" />
   <id>tag:www.jollen.org,2012:/blog//2.800</id>
   
   <published>2012-09-22T04:12:57Z</published>
   <updated>2012-09-22T10:30:21Z</updated>
   
   <summary>宏碁與阿里雲事件的核心是 Google 要求 Android 的硬體裝置都要通過 CTS 測試要求。CTS (Compatibility Test Suite) 的目的是維護建全的 Android 生態系統。簡單來說，CTS 相容的硬體，理論上能運行所有 Play 商店上的軟體；Play 商店上的應用軟體，當然是由遍佈全球的開發者或開發商所製作。Google 的理念是希望讓所有開發者的軟體，都能在所有 Android 的裝置上運行無礙。 CTS 相容性測試 因此，Google 會對 Android 生態系統裡的製造商做出一些要求。最基本的要求就是上述的 CTS。所有裝載 Android 作業系統的裝置，都必須通過 CTS 測試。CTS 完全是技術問題，這裡面包含了近 17,000 條測試案例 (Test case)。這些案例的目的，是為了確保手機的實作品質、實作完成度、用戶體驗的一致性等等。 通過 CTS 測試後，Google 就會把你的硬體加入到「CTS...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[宏碁與阿里雲事件的核心是 Google 要求 Android 的硬體裝置都要通過 CTS 測試要求。CTS (Compatibility Test Suite) 的目的是維護建全的 Android 生態系統。簡單來說，CTS 相容的硬體，理論上能運行所有 Play 商店上的軟體；Play 商店上的應用軟體，當然是由遍佈全球的開發者或開發商所製作。Google 的理念是希望讓所有開發者的軟體，都能在所有 Android 的裝置上運行無礙。

<strong>CTS 相容性測試</strong>

因此，Google 會對 Android 生態系統裡的製造商做出一些要求。最基本的要求就是上述的 CTS。所有裝載 Android 作業系統的裝置，都必須通過 CTS 測試。CTS 完全是技術問題，這裡面包含了近 17,000 條測試案例 (Test case)。這些案例的目的，是為了確保手機的實作品質、實作完成度、用戶體驗的一致性等等。

通過 CTS 測試後，Google 就會把你的硬體加入到「CTS 相容硬體列表」。理論上，必須成為 CTS 相容硬體，才能讓產品上市銷售。問題是，Android 不是一個號稱人人皆可自由使用的開放系統嗎？市面上不是也銷售許多沒有通過 CTS 測試的 Android 裝置嗎？

這個問題又是另一個層次了 (商標授權)，目前先暫不做討論。CTS 是單純的技術問題，我認為一些媒體報導把 CTS 相容性與 Google 的商業戰略牽扯在一起，略有不妥。CTS 是為了幫助硬體廠，它是對大家都有益的必要過程。

Play 商店眾多軟體，你不知道使用者今天會下載哪個應用軟體，如果 Android 裝置在研發時，出了一丁點差錯，可能有些軟體在這個硬體上，會發生運行失敗的問題。CTS 是為了幫助硬體廠，提升產品質量，避開這些技術問題。

我們必須把 CTS 做到 100% Pass，也就是上述 17,000 個測試案例都能通過，再將報告提交給 cts@android.com。然後，你的硬體就成為 CTS 相容設備了。這是 Google 對 Android 裝置做授權的第一個等級。

<strong>GMS 套件與授權</strong>

成為 CTS 相容設備後，上面是沒有 GMS 套件的。GMS 套件包含許多 Google 官方的應用軟體，例如：Play 商店、Gmail、Google Map、Youtube、Google Calendar、Google Talk 等等。要取得 GMS，我們就要向 Google 申請授權；有難度的地方就是在這裡。

因為一些考量，Google 的授權合約裡，不一定會授權 GMS 裡的所有軟體。Google 會針對申請者的「基本條件」來客製化授權合約。這些條件並沒有很特定的項目，像是品牌知名度、工業設計、產品相互競爭關係、銷售地區等等，都會被列入考慮。但不管如何，GMS 裡一個天字第一號的軟體「Play 商店」通常都會授權給申請者。所以，申請者可能只能拿到 GMS 的部份授權，而且也不能使用 Google 商標；這是 Google 對 Android 裝置做授權的第二個等級。

第三個等級就是取得全套的 GMS 授權。根據我過去所參與過的專案來看，這個等級的難度比想像中更高，目前能取得全套授權的廠商並不多。這個等級的授權，能使用 Google 商標，簡單說，就是手機上能打上 Google 的字樣。所以，要知道有哪些廠商取得這個等級的授權，是很容易的。

<strong>授權等級</strong>

Google 針對 Android 裝置的授權：

1. 通過 CTS，授與 Android 商標使用權，但沒有 GMS 授權。
2. 通過 CTS，授與 Android 商標使用權，取得部份的 GMS 授權，但沒有 Google 商標使用權。
3. 通過 CTS，授與 Android 商標使用權，取得完整的 GMS 授權，有 Google 商標使用權。

<strong>結語</strong>

另外，還有幾點要注意的是：

1. Android 確實是開放平臺，這和上述的說明沒有衝突。將宏碁與阿里雲事件與「Android 邁向封閉」做關聯，是有失專業的報導。

2. Android 的開放有二個層面。第一、開放框架與虛擬機的原始碼，稱為 Android Open Source Project (AOSP)。第二、開放 API，即 Android SDK，人人都可以為 Android 開發應用軟體。

3. Android 的開放性是一個層面，Android 的 Ecosystem 又是另一個層面。Google 以最基本的 CTS 來維持 Android 生態系統的健全。

最後，阿里雲事件來說，不是上述的 (1)，也不是 (2) 或 (3)，這又是另外一個層次的問題。阿里雲，或是其它客製化的 Android ROM，可能都不考慮 CTS，也沒有通過 CTS 測試。如果把這些 ROM 放到宏碁的硬體上，可能真的不行，原因是宏碁或許和 Google 簽訂了 GMS 方面的合約，當中可能包含業界所稱的「反 Android 分裂條款」；不過詳情我們當然無從得知。

不過，會有這種失誤，除了可能這個合作關係太高調外，硬體廠的專業經理人專業度可能也要受到挑戰；當初在規劃時，就應該要做考量與溝通。花轎都到門口了，結果新娘還娶不回家，不免讓人把芧頭指向當初介紹雙方認識的媒婆 (經理人) 身上。

至於，如果把阿里雲放到白牌硬體上，是否就可行？理論上，是。但沒有通過 CTS 測試的話，因為沒有 Android 商標使用權，所以使用上要注意 trademark 的法律問題。此外，也不會有 GMS 授權，如果手機上內置了 GMS 套件的軟體，例如：「Play 商店」，那就可能會被視為盜版。此外，這個情況，也要注意 Apache License 條款裡的 Copyright 與 Patent 等法律問題。

]]>
      
   </content>
</entry>
<entry>
   <title>宏碁與阿里雲事件附錄：除了阿里雲，中國還有哪些 Android ROM？</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/09/most-popular-android-rom-china.html" />
   <id>tag:www.jollen.org,2012:/blog//2.799</id>
   
   <published>2012-09-16T07:06:21Z</published>
   <updated>2012-09-16T12:28:35Z</updated>
   
   <summary>近幾天大家都在新聞媒體上看到了宏碁與阿里雲事件，這反應了定製 Android ROM 在中國已經是一個熱門的研發項目。定製 ROM 的目的無疑是為了搶佔互聯網的商機。在不違反 Apache License 與 Android 商標權的前提下，廠商可以自由地移除 Google 服務，並且加入自已的訂製服務。 這是網路版的圈地活動。這也難怪 Google 要在發表會前，要求宏碁臨時抽腿。 訂製 Android ROM 是 AOSP (Android Open Source Project) 的分支 (Branch)，同時也以刷機方式，提供用戶自由替換硬體上的操作系統。例如，不喜歡官方 Sense UI 的用戶，可以將手上的 HTC 手機刷成 MIUI。 用戶刷機，到底刷上誰的 ROM，這件事情真的很重要。因為這是一種渠道 (通路)。能否掌握刷機渠道，影響網路圈地競爭成敗。例如：我們可以想辦法讓所有 HTC 手機的用戶，都刷上我的 ROM。當然，我的 ROM...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[近幾天大家都在新聞媒體上看到了宏碁與阿里雲事件，這反應了定製 Android ROM 在中國已經是一個熱門的研發項目。定製 ROM 的目的無疑是為了搶佔互聯網的商機。在不違反 Apache License 與 Android 商標權的前提下，廠商可以自由地移除 Google 服務，並且加入自已的訂製服務。

這是網路版的圈地活動。這也難怪 Google 要在發表會前，要求宏碁臨時抽腿。

訂製 Android ROM 是 AOSP (Android Open Source Project) 的分支 (Branch)，同時也以刷機方式，提供用戶自由替換硬體上的操作系統。例如，不喜歡官方 Sense UI 的用戶，可以將手上的 HTC 手機刷成 MIUI。

用戶刷機，到底刷上誰的 ROM，這件事情真的很重要。因為這是一種渠道 (通路)。能否掌握刷機渠道，影響網路圈地競爭成敗。例如：我們可以想辦法讓所有 HTC 手機的用戶，都刷上我的 ROM。當然，我的 ROM 裡面，都可以把別人 (Google) 的服務拿掉，換成自已的服務。

除了新聞上曝光的阿里雲外，在中國還有哪些訂製的 Android ROM 呢？讓我們來總覽一下。

一、CyanogenMod (CM)：這是由 Cyanogen 社群所製作的 Android ROM，普遍受到中國社群與開發者的喜愛。Cyanogen 可以說是 Android ROM 之父。目前筆者所開發的多核心 Android ROM 也是建構在 CM 的基礎之上。所以，CM 是巨人，大家都站在他的肩膀上。

二、阿里雲：由阿里巴巴所推出的版本，主打雲計算，提供像是雲儲存等服務。阿里雲當然也把阿里巴巴的消費服務整合進去了，並且也替換掉通訊錄、日曆、搜尋引擎、郵件服等服務。這也難怪 Google 有話要說。

三、百度雲：最新加入戰局的 Android ROM。百度雲於 2012 年 6 月 4 日推出，不用介紹也知道百度雲整合了自家的搜索服務。Dell 百度雲手機就採用了這款 Android ROM。

四、樂OS (LeOS)：聯想推出的 Android ROM。

五、TITA。這也是最近加入戰局的 Android ROM，發佈於 2012 年 4 月份，開發者是騰訊。

六、樂蛙OS：針對千元以下雙卡雙待智能手機開發的 Android ROM。這樣一說就很明顯了，這是專門針對聯發科平臺所訂製的 Android ROM。

介紹到這裡，大家應該可以知道，為什麼低價手機的 Design house (過去被大家稱為山寨商) 只要專心做好「<a href="http://www.jollen.org/blog/2009/02/android_china_business_opportunities.html" target="_blank">品牌硬體</a>」即可。中國的低價智能手機市場需求，都還沒走到山腰，接下來的需求量會呈現很陡峭的向上趨勢。但是很可惜，過去二年缺乏佈局的台灣供應鍊，將完全沾不到好處，原因是中國供應鍊已經能 100% 自製自足，並且競爭規則也改變了。

七、點心OS：這是在創新工場裡誔生的 Android ROM，可以說是中國訂製 Android ROM 的第一家，出現時間較早。開發商北京風靈創景科技是創新工場投資的第一家公司。點心OS團隊過去也拜訪過台灣的硬體廠，不過台灣的硬體廠對這個項目反應似乎較冷淡。目前合作廠商名單裡也有宏碁。

八、MIUI：把 MIUI 放在最後當壓軸，這就是小米公司所推出的 ROM，目前小米手機就是搭配 MIUI 出貨。MIUI 也是基於 CyanogenMod ROM 所訂製的版本。MIUI 支援的機型較多，你可以把三星、HTC 或 Moto 等眾多手機硬體，刷成 MIUI。

<strong>結語</strong>

小米手機的高知名度真的不必多說了，它的 MIUI 確實得到許多用戶的支持與肯定。刷機文化將讓傳統的手機市佔率計算公式失真。原因很簡單，例如：每賣出的 10 支 HTC 手機裡，就有 3 個用戶把機器刷成 MIUI，這 3 支手機到底要算 HTC 品牌還是算 MIUI 品牌。

所以說，市佔率以後要分為硬體市佔率，以及互聯網裝置市佔率二個數字。以上述的例子來說，被刷掉的 3 支 HTC 手機還是要算在 HTC 的硬體市佔率裡，但是卻要加到 MIUI 的互聯網裝置市佔率上。結論是，Android ROM 以及刷機文化，會「刷」掉傳統品牌的互聯網價值。當然，這些廠商都意識到這個現象了，也正設法擁抱中國的互聯網。]]>
      
   </content>
</entry>
<entry>
   <title>小三大戰簡史</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/09/mi-360-war.html" />
   <id>tag:www.jollen.org,2012:/blog//2.798</id>
   
   <published>2012-09-12T04:57:05Z</published>
   <updated>2012-09-12T10:01:51Z</updated>
   
   <summary>昨天一個朋友問到什麼是「小三大戰」，驚訝之餘，其實也反應出台灣中階主管不太關注網路事件的問題。所以我就簡單介紹了有名的小三大戰，細節，網路上有豐富的資訊。 小三大戰 小米手機創造了新的銷售模式，簡單說就是和社群緊密地走在一起。高配置的硬體規格，加上親民的價格，小米手機一推出果真轟動。小米之後，360也發表特攻手機 (稱為 AK47)，同樣講求高階硬體規格，以及漂亮價格。不想讓小米專美於前，就在360手機開始受到各方觀注的同時，360董事長周鴻禕發表微博，質疑小米機水軍炒作 (網路炒作)。小米手機副總裁很快給了回應，他說360手機雙核1G還賣這種價錢，價格不如同等級的小米機。就當雙方嘴巴還沒說熱時，小米董事長雷軍迅速加入戰團，史稱小三大戰 (小米與360大戰)。 小三大戰到後來幾乎演變為人身攻擊，周鴻禕說雷軍是機霸，別人碰不得他的奶酪。雷軍叫周鴻禕放下AK47，不要沉醉於東方不敗的幻覺中。周鴻禕後來在微博上說「到朝陽公園見面」，疑似要和雷軍定孤支 (決鬥)，讓小三大戰進入高潮。雙方戰火正酣時，QQ董事長馬化騰又加進來幫腔，演變成「小三Q」大戰。 其實二年多前，馬化騰和周鴻禕也打過口水戰，史稱「3Q大戰」。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[昨天一個朋友問到什麼是「小三大戰」，驚訝之餘，其實也反應出台灣中階主管不太關注網路事件的問題。所以我就簡單介紹了有名的小三大戰，細節，網路上有豐富的資訊。

<strong>小三大戰</strong>

小米手機創造了新的銷售模式，簡單說就是和社群緊密地走在一起。高配置的硬體規格，加上親民的價格，小米手機一推出果真轟動。小米之後，360也發表特攻手機 (稱為 AK47)，同樣講求高階硬體規格，以及漂亮價格。不想讓小米專美於前，就在360手機開始受到各方觀注的同時，360董事長周鴻禕發表微博，質疑小米機水軍炒作 (網路炒作)。小米手機副總裁很快給了回應，他說360手機雙核1G還賣這種價錢，價格不如同等級的小米機。就當雙方嘴巴還沒說熱時，小米董事長雷軍迅速加入戰團，史稱小三大戰 (小米與360大戰)。

小三大戰到後來幾乎演變為人身攻擊，周鴻禕說雷軍是機霸，別人碰不得他的奶酪。雷軍叫周鴻禕放下AK47，不要沉醉於東方不敗的幻覺中。周鴻禕後來在微博上說「到朝陽公園見面」，疑似要和雷軍定孤支 (決鬥)，讓小三大戰進入高潮。雙方戰火正酣時，QQ董事長馬化騰又加進來幫腔，演變成「小三Q」大戰。

其實二年多前，馬化騰和周鴻禕也打過口水戰，史稱「3Q大戰」。]]>
      
   </content>
</entry>
<entry>
   <title>即將開始提供的內訓課程：Android 電源管理、硬體加速與 Multi-Core HAL</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/09/android-power-manager-gal-training.html" />
   <id>tag:www.jollen.org,2012:/blog//2.796</id>
   
   <published>2012-09-11T15:28:40Z</published>
   <updated>2012-09-11T20:50:16Z</updated>
   
   <summary>這二個月的時間，有一半都投資在 Multi-Core 的技術工作上，開發之餘，順勢整理了 8 門課程給一些客戶。日前也開始進入教材編輯階段了，本週完成 3 門課程，在此簡單做個紀錄。 Android 電源管理: PowerManagerService, Power Hint 與 Power HAL Jelly Bean 強化了 Power HAL 的功能，並且透過 Power Hint 的方式增強 Power Saving。這個主題會著重在 Power HAL 的實作，以及 Wakelock 的原理。如何將 Control Group、CPU Governors 與 PowerManagerService 放在一起使用 (Put all together)：能達到什麼目標，解決哪些過去的問題？都是這門課程的重點。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[這二個月的時間，有一半都投資在 Multi-Core 的技術工作上，開發之餘，順勢整理了 8 門課程給一些客戶。日前也開始進入教材編輯階段了，本週完成 3 門課程，在此簡單做個紀錄。

<strong>Android 電源管理: PowerManagerService, Power Hint 與 Power HAL</strong>

Jelly Bean 強化了 Power HAL 的功能，並且透過 Power Hint 的方式增強 Power Saving。這個主題會著重在 Power HAL 的實作，以及 Wakelock 的原理。如何將 Control Group、CPU Governors 與 PowerManagerService 放在一起使用 (Put all together)：能達到什麼目標，解決哪些過去的問題？都是這門課程的重點。

<strong>Android Hardware Rendering and Composer</strong>

針對 SurfaceFlinger的Hardware Rendering 架構做介紹，此外也將介紹 hwcompower 的原理以及實作概念。這門課程是 Android Graphics System 的延伸，特別將硬體加速的部份抽離出來，獨立講解。這門課程的重點戲之一，就是 hwcomposer HAL 的實作。

<strong>HAL Stub: Implementation in Multi-core Way</strong>

這是筆者近期比較特別的研究主題，實作成果也陸續整合至 MagicLEGO 平臺，或許未來能提供一個絕佳的效能與多核心 Turnkey solution。本課程跨越 Android Framework、Kernel scheduling、Thread building block 等多個領域，將是未來很重要的多核心技術。本課程利用簡單的實例，說明 HAL 的實作如何針對多核心進行重構，以支援多核心環境。

<strong>後記</strong>

上述課程，都會搭配 Simple code 進行講解，當然也會有實作展示。所有的成果，都會整合至 <a href="http://magiclego.org" target="_blank">MagicLEGO</a> 平臺，課程也以 MagicLEGO 做為講解標地。]]>
      
   </content>
</entry>
<entry>
   <title>如果把 HTC One X 刷上 CM 的 ROM，就會發現其實...</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/08/community-based-android-rom.html" />
   <id>tag:www.jollen.org,2012:/blog//2.795</id>
   
   <published>2012-08-20T04:52:35Z</published>
   <updated>2012-08-20T22:02:57Z</updated>
   
   <summary>從宏觀的角度來看，全球的手機市場「繁華再見了。手機業黃金五年結束。」。另一個要注意是中國的手機市場。從 Android 作業系統的角度來觀察，中國手機市場，正進入第二個發展時期。 在 2009 年初，Android 掀起的波瀾，傳遞到了中國。從 2009 年開始，到 2012 年初，正好滿滿的三年時間裡，是中國智能手機市場的第一個發展時期。在這三個整年裡，山寨機、中國品牌與小米機，是最精采的三個故事。 山寨行業最早也最快吃到甜頭。山寨行業具有高度的商業嗅覺，自然不會放過這個機會。這三年裡，山寨商無不大顯身手，並依賴其特殊的「商業模式」，提供快速且高度客製化的手機，在競爭激烈的手機行業裡，找到一個利基市場。 除了山寨市場的改變與進步外，中國的品牌手機也有很大的進展。例如，中興與華為的崛起正是代表。根據IDC 的研究，中興 (ZTE) 目前是全球第四大手機製造商。HTC 市佔率目前滑落至 2% 左右，位居全球第八。 小米機的故事就不必多說了，其「社群導向」的經營模式，將成為經典。幾天前發表的「小米機二代」，也被外資券商形容為「HTC 在中國的可怕敵人」。小米手機，一家軟體公司的作品，在分析師眼裡，已經和 HTC 平起平坐了。 上述提及的「山寨特殊的商業模式」代表案例之一，就是深度 Android 愛好者的「刷機文化」。這和小米手機有著相當高度的交集。簡單來說，就是經由社群來開發並提供 ROM，讓愛好者刷機，並經營「品牌硬體」。關於這個部份的觀點，可以閱讀「CTimes 矽導論壇：Android元年 vs 山寨機氣象變化元年」一文的說明。 刷機文化，從產品的角度來看，就是一種「客製化手機」的服務。客製化，並不只是訂製硬體，更重要的是訂製軟體。刷機文化正是一種軟體訂製機制，它的運作模式是，由社群開發者扮演 ROM 製造商的角色，整合並提供很多好用的 Android ROM。 小米手機成功的關鍵之一，就是它扮演很好的 ROM 製造商角色。 刷機文化發源自重度使用者與開發者社群，所以這種文化應該是全球性的。事實上正是如此。舉一個例子，CyanogenMod (CM)，是國外相當知名的...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[從宏觀的角度來看，全球的手機市場「<a href="http://www.jollen.org/blog/2012/07/goodbye-smartphone-gold-years.html" target="_blank">繁華再見了。手機業黃金五年結束。</a>」。另一個要注意是中國的手機市場。從 Android 作業系統的角度來觀察，中國手機市場，正進入第二個發展時期。

在 2009 年初，Android 掀起的波瀾，傳遞到了中國。從 2009 年開始，到 2012 年初，正好滿滿的三年時間裡，是中國智能手機市場的第一個發展時期。在這三個整年裡，山寨機、中國品牌與小米機，是最精采的三個故事。

山寨行業最早也最快吃到甜頭。山寨行業具有高度的商業嗅覺，自然不會放過這個機會。這三年裡，山寨商無不大顯身手，並依賴其特殊的「商業模式」，提供快速且高度客製化的手機，在競爭激烈的手機行業裡，找到一個利基市場。

除了山寨市場的改變與進步外，中國的品牌手機也有很大的進展。例如，中興與華為的崛起正是代表。根據IDC 的研究，中興 (ZTE) 目前是全球第四大手機製造商。HTC 市佔率目前滑落至 2% 左右，位居全球第八。

小米機的故事就不必多說了，其「社群導向」的經營模式，將成為經典。幾天前發表的「小米機二代」，也被外資券商形容為「HTC 在中國的可怕敵人」。小米手機，一家軟體公司的作品，在分析師眼裡，已經和 HTC 平起平坐了。

上述提及的「山寨特殊的商業模式」代表案例之一，就是深度 Android 愛好者的「刷機文化」。這和小米手機有著相當高度的交集。簡單來說，就是經由社群來開發並提供 ROM，讓愛好者刷機，並經營「品牌硬體」。關於這個部份的觀點，可以閱讀「<a href="http://www.jollen.org/blog/2009/02/android_china_business_opportunities.html" target="_blank">CTimes 矽導論壇：Android元年 vs 山寨機氣象變化元年</a>」一文的說明。

刷機文化，從產品的角度來看，就是一種「客製化手機」的服務。客製化，並不只是訂製硬體，更重要的是訂製軟體。刷機文化正是一種軟體訂製機制，它的運作模式是，由社群開發者扮演 ROM 製造商的角色，整合並提供很多好用的 Android ROM。

小米手機成功的關鍵之一，就是它扮演很好的 ROM 製造商角色。

刷機文化發源自重度使用者與開發者社群，所以這種文化應該是全球性的。事實上正是如此。舉一個例子，CyanogenMod (CM)，是國外相當知名的 Android ROM 開發者社群。在這裡，你可以找到很多「非官方」的 Android ROM，幫助你讓手機改頭換面。

不要小看這些「非官方」的 ROM，許多 ROM 擁有很高的技術水平，並且經常能提供比「原廠」更快的更新速度。例如，你可以找到針對 HTC One X 所製作的 Jelly Bean ROM。而且，根據該開發者表示，這個 ROM 如果放到 HTC One X 上，其效能表現，遠勝於官方的 ICS 版本。

該開發者又表示，「HTC 實在應該儘速升級至 Jelly Bean」，「Jelly Bean 解決了 HTC 過去的技術問題」。截至目前還止，我們還沒有辦法得到官方版的 Jelly Bean 更新。

「<a href="http://www.youtube.com/watch?v=hL5nTprjOZQ" target="_blank">如果把 HTC One X 刷上 CM 的 ROM，就會發現其實 HTC One X 真的是…很棒的硬體！</a>」

所以，「社群」是一個重要的發展方向。硬體製商如果認為這不能創造成功的企業，那麼應該看看小米手機的故事，再重下定論。山寨機、中國品牌與小米機，都要邁向新的發展格局了。

對於台灣的供應鍊產業，我想在這裡也有一個警訊。邁向另一個發展格局的中國手機市場，已經能 100% 自製了，意思是中國的供應鍊已經能 100% 自足，很多台灣的零件組將被取代。台灣供應鍊優勢，何時完全消失，正持續觀察中。]]>
      
   </content>
</entry>
<entry>
   <title>Phonesmpd 升級了：支援 Jelly Bean</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/08/phonesmpd-jelly-beab.html" />
   <id>tag:www.jollen.org,2012:/blog//2.794</id>
   
   <published>2012-08-04T07:09:39Z</published>
   <updated>2012-08-15T14:39:05Z</updated>
   
   <summary>[Phonesmpd] 目前正和 Jelly Bean 整合當中，並且也開始加入 Linux 3.2 的一些特性。Jelly Bean 新增許多與多核心有關的特色，Phonesmpd 考慮了其中幾個新特色： 1. 整合 Jelly Bean 新的 Thread Group 功能 2. Jelly Bean 修改了 Cgroup 的設定，除了 fg_boost 外，還有一個 app group 3. 針對 Vsync 整合一些多核心功能，目前測試結果顯示能提昇 UI 的使用效能 4. 整合 Cpuset ，並支援 Linux...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Multi-core Software" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="產品開發" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[[<a href="http://www.moko365.com/enterprise/phonesmpd" target="_blank">Phonesmpd</a>] 目前正和 Jelly Bean 整合當中，並且也開始加入 Linux 3.2 的一些特性。Jelly Bean 新增許多與多核心有關的特色，Phonesmpd 考慮了其中幾個新特色：

1. 整合 Jelly Bean 新的 Thread Group 功能
2. Jelly Bean 修改了 Cgroup 的設定，除了 fg_boost 外，還有一個 app group
3. 針對 Vsync 整合一些多核心功能，目前測試結果顯示能提昇 UI 的使用效能
4. 整合 Cpuset ，並支援 Linux 3.2 以及 /proc/&lt;pid&gt;/cpuset 功能
5. 開始測試全面移除 Automatic Cgroup 功能，這是 Phonesmpd 的重要里程碑

由於這次新的功能較多，實作與測試需要比較多時間，希望能在八月底前與 MagicLEGO 整合好。不久後，MagicLEGO 的使用者，都能享受到 Phonesmpd 帶來的多核心威力。]]>
      
   </content>
</entry>
<entry>
   <title>開放平臺為戰略的軟體研發結構？企業管理技術的一環。</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/07/open-platform-software-development-structure.html" />
   <id>tag:www.jollen.org,2012:/blog//2.792</id>
   
   <published>2012-07-23T14:31:00Z</published>
   <updated>2012-08-15T13:47:31Z</updated>
   
   <summary>大約在二零零九年左右，三星在軟體發展方面，有了更重要的戰略，簡單說，就是更開放、更創新的做法；開放與創新的軟體戰略，就是我們所熟知的開放平臺與開放源始碼。 據維基百科上的定義，開放平臺(Open platform)訴求是提供應用程式開發界面，稱為 API (Application Programming Interface)，廠商可以將 API 打包成應用程式開發套件，稱為 SDK (Software Development Kit)；SDK 的目的是提供撰寫應用程式(App)的工具箱(Kit)。最成功的 SDK 就是大家所熟知的 iPhone SDK 與 Android SDK。 意思是說，SDK 本身不一定要公開原始碼(Open source)，只要有整合良好的 SDK 即可。開放源碼是軟體研發結構的一環，這可以從三星積極參與Android與Linux kernel的開放源碼計畫看出。提到Open source，必須要來說明一件事。 李健熙說過：「三星集團必須繼續開放與創新...公司文化變得更為開放、富有彈性並勇於創新...。」他所提到的「開放」，就包含了Open platform。不管是Open platform或Open source，「都改變了企業製造軟體的方法」。 然而，台灣的企業還沒有建立起這種研發結構。台灣的企業並不是沒有能力，而是沒有觀念。沒有Open platform的思想，就沒有重新建構研發文化的可能性。那就享受不到開放平臺帶來的價值。 三星在向大家介紹Bada作業系統時，新聞說：「Samsung presents Bada, open platform for...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      大約在二零零九年左右，三星在軟體發展方面，有了更重要的戰略，簡單說，就是更開放、更創新的做法；開放與創新的軟體戰略，就是我們所熟知的開放平臺與開放源始碼。

據維基百科上的定義，開放平臺(Open platform)訴求是提供應用程式開發界面，稱為 API (Application Programming Interface)，廠商可以將 API 打包成應用程式開發套件，稱為 SDK (Software Development Kit)；SDK 的目的是提供撰寫應用程式(App)的工具箱(Kit)。最成功的 SDK 就是大家所熟知的 iPhone SDK 與 Android SDK。

意思是說，SDK 本身不一定要公開原始碼(Open source)，只要有整合良好的 SDK 即可。開放源碼是軟體研發結構的一環，這可以從三星積極參與Android與Linux kernel的開放源碼計畫看出。提到Open source，必須要來說明一件事。

李健熙說過：「三星集團必須繼續開放與創新...公司文化變得更為開放、富有彈性並勇於創新...。」他所提到的「開放」，就包含了Open platform。不管是Open platform或Open source，「都改變了企業製造軟體的方法」。

然而，台灣的企業還沒有建立起這種研發結構。台灣的企業並不是沒有能力，而是沒有觀念。沒有Open platform的思想，就沒有重新建構研發文化的可能性。那就享受不到開放平臺帶來的價值。

三星在向大家介紹Bada作業系統時，新聞說：「Samsung presents Bada, open platform for app developers.」Bada在2009年時發佈，可見三星很早就開始在思考開放平臺了。

所以，以開放平臺為戰略的軟體研發結構是什麼？例如，有一種結構是 All in-house developers。開放平臺下的研發結構，應該是 in-house developers + free developers(自由開發者)。和具有實力的 3rd party 合作，就是 free developer 的一個例子，這些公司經常是幾個人的小軟體公司。Free developers 在開放源碼上也適用，例如，三星加入了Linaro，以維持它的研發結構裡，有足夠的自由開發者能量。

從結果來看，三星不只是將Android開源計畫或Linux kernel，當做是可免費取得的原始碼（台灣廠商普遍有這樣的誤解），而是把Open platform，乃至於Open source都融入了企業經營技術裡。Google的Android雖然是開放源碼，但商業上則是偏向開放平臺的概念。
      
   </content>
</entry>
<entry>
   <title>繁華再見後，手機業經營者挑戰巨大。至少別再衝浪了。</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/07/smartphone-odms-thinking-the-next-wave.html" />
   <id>tag:www.jollen.org,2012:/blog//2.791</id>
   
   <published>2012-07-22T16:02:09Z</published>
   <updated>2012-07-23T20:11:21Z</updated>
   
   <summary>在黃金五年的尾聲，毫無疑問，三星與蘋果是贏家。以Android作業系統手機來說，三星後來居上，登上王座。 三星在這黃金五年裡，以「開放平臺」為戰略，建立了一個相當有競爭力的技術研發結構。 反觀許多智能手機商，似乎並沒有利用過去這寶貴的黃金五年，建立公司的軟體研發結構。台灣某手機大廠，似乎也是如此。 黃金五年很寶貴，而且機會一去不復返。一般來看，行業的黃金時期都是甜蜜時間，大部份的人都能吃到糖；行業裡的所有人都是享受激情式的成長。 投資大師巴非特說：「當浪潮退去之後，便知道誰在裸泳。」這個比喻很傳神，我們也把它拿來這裡用。 手機黃金五年是一股巨浪，直接把你往前推。有時，公司不需要建立嚴密的研發結構，衝浪就是了。最典型的代表就是山寨機行業。行業內用白話文說：「躺著賺錢。」 總結來說，你可能並不是完全靠自已，而是佔「天時」的便宜。有些手機品牌廠只知衝浪、太過於得意忘形，所以沒有利用寶貴時間，好好建立公司的技術研發結構。當浪潮退去，一切都要回歸本質。 現在是誰在祼泳？ 三星的智能手機，嚴格來說，從2010年才開始。這段時間，三星建立了一個以開放平臺(Open platform)為中心的軟體研發結構。三星不是祼泳者，因為它在開放平臺戰略方面，做得很成功。 以開放平臺為戰略的研發結構，將幫助三星進入另一個境界。開放平臺是一個概念，在這個概念下所產出的軟體並不一定是開放源碼(Open source)，關於這點筆者後續再做說明。比起其它玩「當衝」的手機業者，三星花更多時間做長期佈局的工作。 做為執行者，現在應該去思考如何以開放平臺建立一個精緻的研發結構，為未來做好準備。然而，這是一個需要文化革命的經營運動，是否能落實執行，就是個未知數了。 本文有續集 開放平臺為戰略的軟體研發結構？企業管理技術的一環。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[在黃金五年的尾聲，毫無疑問，三星與蘋果是贏家。以Android作業系統手機來說，三星後來居上，登上王座。

三星在這黃金五年裡，以「開放平臺」為戰略，建立了一個相當有競爭力的技術研發結構。

反觀許多智能手機商，似乎並沒有利用過去這寶貴的黃金五年，建立公司的軟體研發結構。台灣某手機大廠，似乎也是如此。

黃金五年很寶貴，而且機會一去不復返。一般來看，行業的黃金時期都是甜蜜時間，大部份的人都能吃到糖；行業裡的所有人都是享受激情式的成長。

投資大師巴非特說：「當浪潮退去之後，便知道誰在裸泳。」這個比喻很傳神，我們也把它拿來這裡用。

手機黃金五年是一股巨浪，直接把你往前推。有時，公司不需要建立嚴密的研發結構，衝浪就是了。最典型的代表就是山寨機行業。行業內用白話文說：「躺著賺錢。」

總結來說，你可能並不是完全靠自已，而是佔「天時」的便宜。有些手機品牌廠只知衝浪、太過於得意忘形，所以沒有利用寶貴時間，好好建立公司的技術研發結構。當浪潮退去，一切都要回歸本質。 現在是誰在祼泳？ 

三星的智能手機，嚴格來說，從2010年才開始。這段時間，三星建立了一個以開放平臺(Open platform)為中心的軟體研發結構。三星不是祼泳者，因為它在開放平臺戰略方面，做得很成功。

以開放平臺為戰略的研發結構，將幫助三星進入另一個境界。開放平臺是一個概念，在這個概念下所產出的軟體並不一定是開放源碼(Open source)，關於這點筆者後續再做說明。比起其它玩「當衝」的手機業者，三星花更多時間做長期佈局的工作。

做為執行者，現在應該去思考如何以開放平臺建立一個精緻的研發結構，為未來做好準備。然而，這是一個需要文化革命的經營運動，是否能落實執行，就是個未知數了。

<strong>本文有續集</strong>

<ul>
<li><a href="http://www.jollen.org/blog/2012/07/open-platform-software-development-structure.html">開放平臺為戰略的軟體研發結構？企業管理技術的一環。</a></li>
</ul>]]>
      
   </content>
</entry>
<entry>
   <title>繁華再見了。手機業黃金五年結束。</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/07/goodbye-smartphone-gold-years.html" />
   <id>tag:www.jollen.org,2012:/blog//2.790</id>
   
   <published>2012-07-20T14:05:09Z</published>
   <updated>2012-07-22T21:20:06Z</updated>
   
   <summary>手機業黃金五年結束。 存貨反應一個行業的經營體質，而手機行業目前面臨較沈重的庫存問題。當存貨天數過高，營業利益率會有很大的影響。而一些品牌手機商正面臨這個困境。 2008到2012年是智能手機的黃金五年，因為今年可能劃下休止符。我們都全程參與了這個行業，見證到智能手機(觸控手機)的大崛起。2008年9月15日雷曼兄弟宣佈破產，引發金融海嘯。當年智能手機業的營業利益率大約在18%~23%之間，金融海嘯襲捲後還能維持在16%以上。 這個數字在2012年Q1下滑到約9%左右，已經很接近PCB行業了。以銷售硬體為主要商業模式的手機業者，未來將面臨巨大挑戰，Apple早已跳出硬體銷售的模式，因此iPhone提早免役。 市場變化太快，智能手機席捲全球，以功能型手機起家並稱霸手機業多年的Nokia最早落難。繁華過後，高速的成長，反讓智能手機自已面臨成長困境。 張忠謀董事長提到的庫存問題，在手機業情況危急。2008年開始，手機業的存貨天數不超過40天，最高大約是37~38天。但是今年(2012)第一季的存貨數字來到51~52天，創下新高。台灣某品牌的營業利益率則是在今年跌破10%。 這些數字得到一個總結，智能手機不再是新興科技，它是傳統產業。營業利益率方面，賣手機的和作PCB的人差不了多少。高速成長的榮景不復再見，回不去了。 大陸的煤碳行業黃金十年也結束了，在今年六月份，煤碳庫存量來到28天，同樣是繁華老去。所以這樣的故事一直不斷在進行著，也不需要感到可惜。當下重要的事情是去尋找下一個黃金行業。 本文有續集 繁華再見後，手機業經營者挑戰巨大。至少別再衝浪了。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[手機業黃金五年結束。

存貨反應一個行業的經營體質，而手機行業目前面臨較沈重的庫存問題。當存貨天數過高，營業利益率會有很大的影響。而一些品牌手機商正面臨這個困境。

2008到2012年是智能手機的黃金五年，因為今年可能劃下休止符。我們都全程參與了這個行業，見證到智能手機(觸控手機)的大崛起。2008年9月15日雷曼兄弟宣佈破產，引發金融海嘯。當年智能手機業的營業利益率大約在18%~23%之間，金融海嘯襲捲後還能維持在16%以上。

這個數字在2012年Q1下滑到約9%左右，已經很接近PCB行業了。以銷售硬體為主要商業模式的手機業者，未來將面臨巨大挑戰，Apple早已跳出硬體銷售的模式，因此iPhone提早免役。

市場變化太快，智能手機席捲全球，以功能型手機起家並稱霸手機業多年的Nokia最早落難。繁華過後，高速的成長，反讓智能手機自已面臨成長困境。

張忠謀董事長提到的庫存問題，在手機業情況危急。2008年開始，手機業的存貨天數不超過40天，最高大約是37~38天。但是今年(2012)第一季的存貨數字來到51~52天，創下新高。台灣某品牌的營業利益率則是在今年跌破10%。

這些數字得到一個總結，智能手機不再是新興科技，它是傳統產業。營業利益率方面，賣手機的和作PCB的人差不了多少。高速成長的榮景不復再見，回不去了。

大陸的煤碳行業黃金十年也結束了，在今年六月份，煤碳庫存量來到28天，同樣是繁華老去。所以這樣的故事一直不斷在進行著，也不需要感到可惜。當下重要的事情是去尋找下一個黃金行業。

<strong>本文有續集</strong>

<ul>
<li><a href="http://www.jollen.org/blog/2012/07/smartphone-odms-thinking-the-next-wave.html">繁華再見後，手機業經營者挑戰巨大。至少別再衝浪了。</a></li>
</ul>]]>
      
   </content>
</entry>
<entry>
   <title>多核心手機應併用 CPU On-demand 與 CPU Boost 技術</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/07/multi-core-phone-cpu-ondemand-boost.html" />
   <id>tag:www.jollen.org,2012:/blog//2.788</id>
   
   <published>2012-07-11T17:33:45Z</published>
   <updated>2012-07-11T22:46:20Z</updated>
   
   <summary>CPU Ondemand 並非萬能。最重要的例子就是 Android 4.1 的 CPU input boost (Touch Event)，在接收 Touch Event 時，提高 CPU 的運算效能。 延伸 Android 4.1 的 CPU input boost。我們也可以讓應用程式享用 CPU Boost 功能。根據使用者目前的操作，將 CPU Boost，讓使用中的應用程式，衝到最高的效能。Boost 有點像是「猛衝」的感覺，可以在這個時刻讓使用者享受高效能的應用程式。 筆者目前參與開發中的 Phonesmpd 軟體，符合了這樣的設計想法。 CPU On-Demand 到處都適用嗎？ 由於 Android Process Model 與典型的...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[CPU Ondemand 並非萬能。最重要的例子就是 Android 4.1 的 CPU input boost (Touch Event)，在接收 Touch Event 時，提高 CPU 的運算效能。

延伸 Android 4.1 的 CPU input boost。我們也可以讓應用程式享用 CPU Boost 功能。根據使用者目前的操作，將 CPU Boost，讓使用中的應用程式，衝到最高的效能。Boost 有點像是「猛衝」的感覺，可以在這個時刻讓使用者享受高效能的應用程式。

筆者目前參與開發中的 Phonesmpd 軟體，符合了這樣的設計想法。

<strong>CPU On-Demand 到處都適用嗎？</strong>

由於 Android Process Model 與典型的 GNU/Linux 有些不同，CPU Ondemand 的方式並不一定能使用在所有的 Use Case。有鑑於此，筆者過去進行了一些研究，並將成果整合進 Phonesmpd 軟體，讓多核心技術，除了 CPU Ondemand 外，還有另一個更符合手機裝置的選擇。Phonesmpd 現階段的成果，可參考 Moko365 網站：

<a href="http://www.moko365.com/enterprise/phonesmpd" target="_blank">http://www.moko365.com/enterprise/phonesmpd
</a>

至於 CPU Ondemand 的使用時機為何？筆者認為，應該是從應用程式的角度來考慮。當一個應用程式，本身是平行化的設計時，或許它就不太適合 CPU Ondemand 的做法。

通常平行化的設計，是以 Data Partitioning 的方式，將資料分散至不同處理器上計算後，再經由 Shared memory 合併回來。這就是平行處理 (Parallel Computing) 在討論的技術。所以平行處理是多核心軟體的根本。

在進行 Data Partitioning 時，有時也會將任務 (Task) 與 CPU 事先指派好，這時就不太需要 CPU Ondemand 了。多核心手機目前還是一個需要細部研究的領域。]]>
      
   </content>
</entry>
<entry>
   <title>台灣沒有軟體人才的問題！年輕人請奮起 </title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/07/between-taiwan-talent-and-industry.html" />
   <id>tag:www.jollen.org,2012:/blog//2.787</id>
   
   <published>2012-07-05T04:46:59Z</published>
   <updated>2012-07-05T09:54:04Z</updated>
   
   <summary>文/Jollen Chen（Moko365創辦人），原文刊載於 CTimes 雜誌2012年七月號 這一期，我想談談台灣人才外流的問題，也分享在業界的實務心得。今年以來，媒體不斷報導台灣人才外流的現象，根據筆者最近與大陸業界人士的交流經驗，這個問題確實存在。並且，這個人才移動的速度非常驚人。台灣人才的流失正處於「主升段」。筆者在大陸從事教育訓練多年，課程中遇到台灣朋友的比例，確實逐年升高。今年以來，這個比例更高。現在，在大陸進行企業內訓時，遇見台灣同鄉朋友，已經是家常便飯了。 諷刺的是，台廠與政府不約而同大喊「台灣人才不足」。試問既然人才不足，又怎麼外流？讓我們來還原真相：問題核心是台廠與政府人才政策失當。 宏觀來看，台灣不是面臨人才不足的問題，而是人才政策的問題。台灣談的人才問題，指的是本土人才數量的不足，這個不足是反應在「員工招募」的結果之上。但是，台灣本土優秀的人才很多，特別是軟體人才，不但沒有不足的問題，素質之高也超乎老闆們的想像。 所以，廠商反應的人才不足，說白了是吸引不到優秀人才，而不是優秀人才不足。應該要思考為什麼人才或年輕人不願進台廠就業。同時，政府往人才培養方向去做，也解決不了根本問題。台廠與政府的人才政策需要檢討。 筆者所談的人才政策，是指如何網羅頂級人才，借助他們打造企業的新競爭力。這和人力資源普遍在談的員工關係、教育訓練、招募、挖角等，是不同的思想。什麼樣的人才政策，才能吸引優秀人才？讓我們向三星學習正確的軟體人才政策。 三星的人才政策一向做得很好，他是硬體與半導體業，擁抱開放軟體政策的學習典範。中國人講過幾句話：「舜發於畎畝之中，傅說舉於版築之間，膠鬲舉於魚鹽之中，管夷吾舉於士，孫叔敖舉於海，百里奚舉於市。」出自《孟子‧告子下》。這就是三星軟體人才政策的最佳寫照。 開放源碼社群上的高手很多沒有接受過正規的職業訓練，然而，他們是公認的天才。三星深知「生於憂患、死於安樂」的道理，所以經常保持高度的警覺心，對人才也特別重視。三星以海納百川的心胸，去挖掘、去吸納這群天才，因為三星相信，「天才可以拯救一家公司」。這就舜發於畎畝之中的道理。三星從1999年開始，就全面實行這種人才政策，無怪乎，三星的面板、DRAM、手機與軟體等，都有驚人的技術成果。 政府的人才政策不當，也反應在產業換血的問題上。五月初，Moko365 和 CTimes 合作舉辦了 Android Day 大會。大會邀請了多位大陸的專家來分享演講，與其說是專家，用「熱血年輕人」來形容更為貼切。幾位年輕朋友，都是網路和軟體方面的八零後創業家。和他們聊天，可以很明顯地感受到創業的熱情，以及對技術的激情。 Android的出現，大陸產業是大贏家。我並不是從產品的角度下結論，而是從社會現象的角度來觀察。Android，它激起了全大陸年輕人的創業激情。從社會的角度來看，這是一股強撼的力量，這股力量將會不斷促進大陸的軟體與行動網路行業的進步。GDP 反應了這個結果。 去年（2011）中國的 GDP 成長大約是 9.2%，根據麥肯鍚的數據，網路相關的產業，就貢獻了其中約 3% 左右。中國的經濟成長是有新血的。反觀台灣，只能設法提升過去硬體產業的產值，透過出口來提升 GDP。 軟體、社群與行動網路產業，在台灣都是小範圍的成功，例如：單一公司的成功、個人開發者的成功，並沒有大範圍，也就是整體產業的成功。台灣的產業看不到新血換舊血，這是人才的政策問題。 台灣的GDP成長沒有新生力軍，十年後，產業無以為繼。 結論是，台廠與政府需要思考對的人才政策，為什麼孫叔敖都去了三星此類的地方。台灣的軟體人才也請奮起，因為相較於大陸，台灣的年輕人，普遍缺乏衝鋒陷陣精神，也少了創業激情。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[文/Jollen Chen（Moko365創辦人），原文刊載於 CTimes 雜誌2012年七月號

這一期，我想談談台灣人才外流的問題，也分享在業界的實務心得。今年以來，媒體不斷報導台灣人才外流的現象，根據筆者最近與大陸業界人士的交流經驗，這個問題確實存在。<u>並且，這個人才移動的速度非常驚人</u>。台灣人才的流失正處於「主升段」。筆者在大陸從事教育訓練多年，課程中遇到台灣朋友的比例，確實逐年升高。今年以來，這個比例更高。現在，在大陸進行企業內訓時，遇見台灣同鄉朋友，已經是家常便飯了。

諷刺的是，台廠與政府不約而同大喊「台灣人才不足」。試問既然人才不足，又怎麼外流？讓我們來還原真相：問題核心是台廠與政府人才政策失當。

<u>宏觀來看，台灣不是面臨人才不足的問題，而是人才政策的問題</u>。台灣談的人才問題，指的是本土人才數量的不足，這個不足是反應在「員工招募」的結果之上。<u>但是，台灣本土優秀的人才很多，特別是軟體人才</u>，不但沒有不足的問題，素質之高也超乎老闆們的想像。

所以，廠商反應的人才不足，<u>說白了是吸引不到優秀人才，而不是優秀人才不足</u>。應該要思考為什麼人才或年輕人不願進台廠就業。同時，政府往人才培養方向去做，也解決不了根本問題。台廠與政府的人才政策需要檢討。

筆者所談的人才政策，是指如何網羅頂級人才，借助他們打造企業的新競爭力。這和人力資源普遍在談的員工關係、教育訓練、招募、挖角等，是不同的思想。什麼樣的人才政策，才能吸引優秀人才？讓我們向三星學習正確的軟體人才政策。

<u>三星的人才政策一向做得很好，他是硬體與半導體業，擁抱開放軟體政策的學習典範</u>。中國人講過幾句話：「舜發於畎畝之中，傅說舉於版築之間，膠鬲舉於魚鹽之中，管夷吾舉於士，孫叔敖舉於海，百里奚舉於市。」出自《孟子‧告子下》。這就是三星軟體人才政策的最佳寫照。

<u>開放源碼社群上的高手很多沒有接受過正規的職業訓練，然而，他們是公認的天才</u>。三星深知「生於憂患、死於安樂」的道理，所以經常保持高度的警覺心，對人才也特別重視。三星以海納百川的心胸，去挖掘、去吸納這群天才，因為三星相信，「天才可以拯救一家公司」。這就舜發於畎畝之中的道理。三星從1999年開始，就全面實行這種人才政策，無怪乎，三星的面板、DRAM、手機與軟體等，都有驚人的技術成果。

政府的人才政策不當，也反應在產業換血的問題上。五月初，Moko365 和 CTimes 合作舉辦了 Android Day 大會。大會邀請了多位大陸的專家來分享演講，與其說是專家，用「熱血年輕人」來形容更為貼切。<u>幾位年輕朋友，都是網路和軟體方面的八零後創業家</u>。和他們聊天，可以很明顯地感受到創業的熱情，以及對技術的激情。

Android的出現，大陸產業是大贏家。我並不是從產品的角度下結論，而是從社會現象的角度來觀察。<u>Android，它激起了全大陸年輕人的創業激情</u>。從社會的角度來看，這是一股強撼的力量，這股力量將會不斷促進大陸的軟體與行動網路行業的進步。GDP 反應了這個結果。

去年（2011）中國的 GDP 成長大約是 9.2%，<u>根據麥肯鍚的數據，網路相關的產業，就貢獻了其中約 3% 左右</u>。中國的經濟成長是有新血的。反觀台灣，只能設法提升過去硬體產業的產值，透過出口來提升 GDP。

<u>軟體、社群與行動網路產業，在台灣都是小範圍的成功</u>，例如：單一公司的成功、個人開發者的成功，並沒有大範圍，也就是整體產業的成功。台灣的產業看不到新血換舊血，這是人才的政策問題。 台灣的GDP成長沒有新生力軍，十年後，產業無以為繼。

結論是，台廠與政府需要思考對的人才政策，為什麼孫叔敖都去了三星此類的地方。台灣的軟體人才也請奮起，因為相較於大陸，台灣的年輕人，普遍缺乏衝鋒陷陣精神，也少了創業激情。]]>
      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] jQuery 模式的優點：提升 JavaScript 程式碼效率</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/06/javascript-selector-api-performance.html" />
   <id>tag:www.jollen.org,2012:/blog//2.786</id>
   
   <published>2012-06-27T09:28:40Z</published>
   <updated>2012-06-27T14:38:56Z</updated>
   
   <summary><![CDATA[在教育訓練課程「HTML5 軟件開發: Mobile, Web & Cloud 設計模式」裡提到「使用 JavaScript 選擇器」可提升程式碼效能的原則。這個觀念，可延續前一篇日記的內容繼續探討。 在實作Web Socket連線生成時，筆者選擇使用了jQuery pattern的觀念來實作。jQuery pattern 本質上是一種選擇器模式。 為什麼要使用選擇器模式，除了程式碼的組織較好外，另一個原因就是效能：使用選擇器方式可以讓JavaScript程式碼效能更好。 根據不同瀏覽器的實作，選擇器模式可以達到超過十倍以上的效能。典型的選擇器模式，是直接呼叫DOM的API： document.querySelector(“#header”); 使用jQuery的選擇器「$」是目前的主流做法。再回顧上一篇日記的寫去： &lt;div id="message">&lt;/div> &lt;script type="text/javascript"> $("#message").createWebSocket(); &lt;/script> 總計利用了三個模式： 以Closure模式將類別封閉，這與Static class有關係，在這裡先不做討論 使用選擇器模式，範例採用目前最流行的jQuery selector ”$” Read/Write Div Pattern 選擇器模式的效率取決於瀏覽器本身的實作，不過，以選擇器模式來代替直接存取DOM，一般相信是最好的做法。...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="HTML5 &amp; JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[在教育訓練課程「<a href="http://www.moko365.com/enterprise/html5-軟件開發的-10-堂課-mobile-web-cloud-設計模式" target="_blank">HTML5 軟件開發: Mobile, Web & Cloud 設計模式</a>」裡提到「使用 JavaScript 選擇器」可提升程式碼效能的原則。這個觀念，可延續前一篇日記的內容繼續探討。

在實作Web Socket連線生成時，筆者選擇使用了jQuery pattern的觀念來實作。jQuery pattern 本質上是一種選擇器模式。

為什麼要使用選擇器模式，除了程式碼的組織較好外，另一個原因就是效能：使用選擇器方式可以讓JavaScript程式碼效能更好。

根據不同瀏覽器的實作，選擇器模式可以達到超過十倍以上的效能。典型的選擇器模式，是直接呼叫DOM的API：

<pre>document.querySelector(“#header”);</pre>

使用jQuery的選擇器「$」是目前的主流做法。再回顧上一篇日記的寫去：

<pre>&lt;div id="message">&lt;/div>
&lt;script type="text/javascript">  
$("#message").createWebSocket();
&lt;/script>
</pre>

總計利用了三個模式：

<ul><li>以Closure模式將類別封閉，這與Static class有關係，在這裡先不做討論</li>
<li>使用選擇器模式，範例採用目前最流行的jQuery selector ”$”</li>
<li>Read/Write Div Pattern</li></ul>

選擇器模式的效率取決於瀏覽器本身的實作，不過，以選擇器模式來代替直接存取DOM，一般相信是最好的做法。
]]>
      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] HTML5+JavaScript 設計模式：jQuery pattern</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/06/html5-javascript-jquery-pattern.html" />
   <id>tag:www.jollen.org,2012:/blog//2.785</id>
   
   <published>2012-06-18T04:23:20Z</published>
   <updated>2012-06-27T14:37:13Z</updated>
   
   <summary><![CDATA[上週在北京舉辦「課程名稱HTML5 & 雲端整合: 深入MOBILE & CLOUD 設計模式」課程。這門課是從 HTML5 觀念到實作的第一門課（The 1st lesson from concepts to practice），這門課的重點在於「設計模式」(Design pattern)。 當天介紹了「jQuery pattern」。jQuery pattern就是開發jQuery插件(Plugin)的方式，所以技術上倒也沒有什麼學問。不過，jQuery pattern有很高深的哲學道理，意思是說，在軟體工程領域裡，它創造了一個獨特的觀念。這個觀念就是jQuery知名的”$”(Dollar sign)，也就是「Selector」。 以下的例子，就是jQuery pattern： $(“div#news”).html(“&lt;h2>News Today&lt;/h2>”); 從jQuery設計模式的角度思考，如果今天我們想要透過WebSocket與伺服器溝通，並且在一個”div”裡來顯示結果，應該怎麼設計呢？想法如下： 1. 將WebSocket的功能寫成一個function 2. 將JavaScript function封裝成module 3. 在jQuery裡擴充新的函數，簡單說，就是製作一個jQuery插件(Plugin) 以下是一段程式碼樣板： (function($) { $.fn.createWebSocket = function ()...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="HTML5 &amp; JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[上週在北京舉辦「<a href="http://www.moko365.com/enterprise/html5-雲端整合-深入mobile-cloud-設計模式" target="_blank">課程名稱HTML5 & 雲端整合: 深入MOBILE & CLOUD 設計模式</a>」課程。這門課是從 HTML5 觀念到實作的第一門課（The 1st lesson from concepts to practice），這門課的重點在於「設計模式」(Design pattern)。

當天介紹了「jQuery pattern」。jQuery pattern就是開發jQuery插件(Plugin)的方式，所以技術上倒也沒有什麼學問。不過，jQuery pattern有很高深的哲學道理，意思是說，在軟體工程領域裡，它創造了一個獨特的觀念。這個觀念就是jQuery知名的”$”(Dollar sign)，也就是「Selector」。

以下的例子，就是jQuery pattern：

<blockquote><pre>$(“div#news”).html(“&lt;h2>News Today&lt;/h2>”);</pre></blockquote>

從jQuery設計模式的角度思考，如果今天我們想要透過WebSocket與伺服器溝通，並且在一個”div”裡來顯示結果，應該怎麼設計呢？想法如下：

1. 將WebSocket的功能寫成一個function

2. 將JavaScript function封裝成module

3. 在jQuery裡擴充新的函數，簡單說，就是製作一個jQuery插件(Plugin)

以下是一段程式碼樣板：

<blockquote><pre>(function($) {
$.fn.createWebSocket = function () {
  if ("WebSocket" in window)
  {
     alert("WebSocket is supported by your Browser!");
     var ws = new WebSocket("ws://&lt;you-ip-adderess>:8888/start");
     ws.onopen = function()
     {
     };
     ws.onmessage = function (evt) 
     { 
     };
     ws.onclose = function()
     { 
     };
     ws.onerror = function()
     { 
     };
  }
  else
  {
     alert("WebSocket NOT supported by your Browser!");
  }
};

})($);</pre></blockquote>

上述的寫法，採用暱名模組來實作。接者，再將程式碼儲存為jquery.websocket.js。使用方法如下：

<blockquote><pre>&lt;!DOCTYPE html>
&lt;head>
&lt;script type='text/javascript' src="./jquery.min.js"></script>
&lt;script type='text/javascript' src="./jquery.websocket.js"></script>
&lt;/head>
&lt;body>
&lt;div id="message">&lt;/div>
　
&lt;script type="text/javascript">  
$("#message").createWebSocket();
&lt;/script>
&lt;/body>
&lt;/html>
</pre></blockquote>

這種做法也可以良好地組織HTML5與JavaScript程式碼。此外，JavaScript的module具備「Closure」的特性，即封閉性，可以避免一些衍生問題。

由於HTML5+JavaScript的設計思想，和Natvie App的作法有很大的不同，所以了解HTML5+Javascript的應用程式「如何設計」，會是重要的一門課。了解設計模式，除了能有效組織HTML5+JavaScript程式碼外，也能做出正確的設計。]]>
      
   </content>
</entry>
<entry>
   <title>Tizen 奮起、將打敗 Opera 在行動瀏覽器技術稱王</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/05/tizen-is-going-to-beat-opera.html" />
   <id>tag:www.jollen.org,2012:/blog//2.783</id>
   
   <published>2012-05-16T05:04:19Z</published>
   <updated>2012-05-22T10:21:24Z</updated>
   
   <summary>「什麼最重要、Browser 最重要」提到說，瀏覽器方面，Maxthon 與 Opera 目前在桌面與行動裝置，呈現暫時領先的狀態。還有其它爆點嗎？ Tizen 的前身 MeeGo，身世相當坎苛，它是 Moblin 與 Maemo 的合體。Moblin 原本是 Intel 主導的一項開源計畫，Maemo 則是 Nokia 主導的一項開源計畫，這二項計畫的身世又更為坎苛，已經不忍心再提了。 Tizen 即將打敗 Opera 眼尖一點的網友，可以發現，在行動瀏覽器方面，Tizen 居然已經突破 400 分大關。待 Tizen 正式上市後，將擁有最強的行動瀏覽器。Tizen 在行動瀏覽器方面，即將稱王，並且還大幅領先了老字號的 Opera，真是令人佩服。 不得不承認，在行動裝置市場，歷經風風雨雨的 Intel，這回找三星一起做 Tizen，還真是找對人了。正巧，就在一個多星期前，Tizen 1.0 也正式釋出 SDK 以及原始程式碼了。從 Tizen 官方的消息看出，Tizen 1.0 主打的亮點，正是...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="HTML5 &amp; JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[「<a href="http://www.jollen.org/blog/2012/05/browser-html5test.html">什麼最重要、Browser 最重要</a>」提到說，瀏覽器方面，Maxthon 與 Opera 目前在桌面與行動裝置，呈現暫時領先的狀態。還有其它爆點嗎？

Tizen 的前身 MeeGo，身世相當坎苛，它是 Moblin 與 Maemo 的合體。Moblin 原本是 Intel 主導的一項開源計畫，Maemo 則是 Nokia 主導的一項開源計畫，這二項計畫的身世又更為坎苛，已經不忍心再提了。 

<strong>Tizen 即將打敗 Opera</strong>

<img src="http://www.jollen.org/blog/2012/05/16/score-mobile.jpg" />

眼尖一點的網友，可以發現，在行動瀏覽器方面，Tizen 居然已經突破 400 分大關。待 Tizen 正式上市後，將擁有最強的行動瀏覽器。Tizen 在行動瀏覽器方面，即將稱王，並且還大幅領先了老字號的 Opera，真是令人佩服。 

不得不承認，在行動裝置市場，歷經風風雨雨的 Intel，這回找三星一起做 Tizen，還真是找對人了。正巧，就在一個多星期前，Tizen 1.0 也正式釋出 SDK 以及原始程式碼了。從 Tizen 官方的消息看出，Tizen 1.0 主打的亮點，正是 HTML5 標準。

<strong>又是三星</strong>

瀏覽器目前有二匹大黑馬，第一匹是 Maxthon，它在桌面瀏覽器部份，超越 Chrome，成為 HTML5 相容性最佳的瀏覽器。另一個大黑馬，目前還沒浮出檯面，不過威力應該也是爆點的，就是 Tizen。目前幾乎是三星在主導 Tizen，果不其然，全力搶進行動市場。這次或許能成功。

從技術的角度來看，這個新的 HTML5 行動裝置作業系統 (HTML5 & Mobile OS)，有機會以黑馬之姿和 Android 分庭抗禮。所以，筆者稱為，Tizen 與 Android 的關鍵差異，將會在 HTML5 的支援性。

單就 Android 4.0 的 HTML5 支援性來看，Android 4.0 追不上了。因為 Android 4.0 內建的瀏覽器，對 HTML5 的支援性並不佳，Google 改派 Chrome 或許有機會。這或許可以解釋，為什麼 Google 急著讓 Chrome 跳進 Android。

]]>
      
   </content>
</entry>
<entry>
   <title>什麼最重要、Browser 最重要</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/05/browser-html5test.html" />
   <id>tag:www.jollen.org,2012:/blog//2.782</id>
   
   <published>2012-05-16T03:53:29Z</published>
   <updated>2012-05-16T09:17:08Z</updated>
   
   <summary>HTML5 來了。什麼最重要，Browser 最重要。因為所有 HTML5 App 都在 Browser 環境裡執行，所以，HTML5 App 的 Runtime 就是瀏覽器。 正因為這個原因，各家軟體大廠無不加碼研發人才，努力打造一個能完全相容 HTML5 的瀏覽器，連今年10月份要登場的 Windows 8 Mobile Phone 也在 HTML5 做了很大的改進。 可以這樣想，第一代的 App 使用 OS 做為 Runtime。第二代的 App 使用 Java Virtual Machine 做為 Runtime，例如：Android。第三代的 App 將使用 Browser 做為 Runtime。所以，Runtime...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="HTML5 &amp; JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[HTML5 來了。什麼最重要，Browser 最重要。因為所有 HTML5 App 都在 Browser 環境裡執行，所以，HTML5 App 的 Runtime 就是瀏覽器。

正因為這個原因，各家軟體大廠無不加碼研發人才，努力打造一個能完全相容 HTML5 的瀏覽器，連今年10月份要登場的 <a href="http://www.windowsmobile8.com/" target="_blank">Windows 8 Mobile Phone</a> 也在 HTML5 做了很大的改進。

可以這樣想，第一代的 App 使用 OS 做為 Runtime。第二代的 App 使用 Java Virtual Machine 做為 Runtime，例如：Android。第三代的 App 將使用 Browser 做為 Runtime。所以，Runtime 就是個關鍵技術。No Runtime No Running。以前沒有掌握好 OS 沒關係，過去沒掌握好 VM 沒關係，現在還是沒掌握好 Browser 技術，就很有關係了。

所以，各大瀏覽器與 HTML5 的相容性，成為相當重要的指標。因運而生的網站 html5test.com 可以幫助我們了解瀏覽器的 HTML5 相容性。根據最新的 html5test 測試報告，桌面瀏覽器 (Desktop) 平均分數仍然領先行動 (Mobile) 瀏覽器，可見 HTML5 在桌面環境的部份，會優先成熟。

而目前在桌面瀏覽器的部份，來自北京的 Maxthon 瀏覽器以 437 分取得第一，領先第二名的 Chrome 18。Chrome 原本是被寄於厚望的 HTML5 先鋒者，沒想到被大黑馬 Maxthon 超越。由此可見，大陸的軟實力不容小覻；並且，在 HTML5 方面，大陸目前也扮演了非常重要的角色。


<img alt="my-score.jpg" src="http://www.jollen.org/blog/2012/05/16/my-score.jpg" width="717" height="410" />
我目前使用的瀏覽器

<img alt="score-desktop.jpg" src="http://www.jollen.org/blog/2012/05/16/score-desktop.jpg" width="674" height="459" />
桌面瀏覽器：Maxthon 成為領頭羊，Chrome 緊追在後

<img alt="score-mobile.jpg" src="http://www.jollen.org/blog/2012/05/16/score-mobile.jpg" width="655" height="586" />
行動瀏覽器：沒有意外地，Opera 拿到第一

]]>
      
   </content>
</entry>
<entry>
   <title>[Jollen&apos;s AFC] 1.3 C &amp; Object-oriented</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/04/jollens_afc_1-3-c-inherit.html" />
   <id>tag:www.jollen.org,2012:/blog//2.781</id>
   
   <published>2012-04-15T05:18:44Z</published>
   <updated>2012-04-15T10:24:20Z</updated>
   
   <summary>最經常使用的物件導向觀念就是繼承(Inherit)，使用C語言如何實作繼承？最實用的例子就是 Android HAL。以下圖為例，這是一個標準的 HAL Stub 設計。這個例子試圖在原有的 Android 作業系統裡加入一個「LED Stub」，透過 LED Stub 來控制底層的 LED 硬體。 圖1.3是一個標準的繼承設計，也就是說，在設計 HAL Stub 時，需要重用 hw_module_t 設計。從架構設計的角度來看，我們進行設計重用的工作，以擴充出 LED Stub；錯誤做法是，直接修改原有的 hw_module_t 設計，以達到原本的要求。上述觀念，就為設計重用(Design reuse)，這是軟體工程領域相當重要的知識。 ￼ 圖1.3 HAL Stub設計重用 在開發 Android 系統時，會不斷地 reuse 原有的設計，以擴充出想要的功能。 以標準 C 語言實作圖1.3的方式如下： 1. 以資料結構(Data structure)來描述類別(Class)...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[最經常使用的物件導向觀念就是繼承(Inherit)，使用C語言如何實作繼承？最實用的例子就是 Android HAL。以下圖為例，這是一個標準的 HAL Stub 設計。這個例子試圖在原有的 Android 作業系統裡加入一個「LED Stub」，透過 LED Stub 來控制底層的 LED 硬體。

圖1.3是一個標準的繼承設計，也就是說，在設計 HAL Stub 時，需要重用 hw_module_t 設計。從架構設計的角度來看，我們進行設計重用的工作，以擴充出 LED Stub；錯誤做法是，直接修改原有的 hw_module_t 設計，以達到原本的要求。上述觀念，就為設計重用(Design reuse)，這是軟體工程領域相當重要的知識。

￼<img alt="figure-1-3.png" src="http://www.jollen.org/blog/2012/04/15/figure-1-3.png" />
圖1.3 HAL Stub設計重用

在開發 Android 系統時，會不斷地 reuse 原有的設計，以擴充出想要的功能。

以標準 C 語言實作圖1.3的方式如下：

1. 以資料結構(Data structure)來描述類別(Class)
2. 以資料結構的第一個欄位(First field)，來表示繼承

所以圖1.3的意思是 led_module_t 繼承 hw_module_t，用 C 語言來實作，結果如下：

<pre>struct led_module_t {
   struct hw_module_t parent;
};</pre>

C語言沒有明顯的物件導向語法，因此以C語言實作物件導向的繼承，又是另一個Implicit of object-oriented的例子。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen&apos;s AFC 電子書開工了，順便提暢 Single 的概念</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/04/jollen-afc-book-single-publish.html" />
   <id>tag:www.jollen.org,2012:/blog//2.780</id>
   
   <published>2012-04-12T08:39:50Z</published>
   <updated>2012-04-12T15:18:55Z</updated>
   
   <summary>先前在「Jollen 的 Android Framework Complete (框架大全) 課程發表、外加感想」提到了想把 Jollen&apos;s AFC 寫成一本書的構想，現在開始付諸行動了。學生時代寫書，其實也不是為了寫書而寫，大多是平常做技術的零碎紀錄，再匯集而成。在看到自已的成果出版成實體書時，內心可是無比的感動與激動，要特別感謝旗標出版社當時給了我這麼好的機會。 這次，也打算開始整理手邊的資料，慢慢匯整成一本書，並且一邊整理，一邊上線。這就是數位內容的好處，不用一次全寫完再出版。新書的書名也未定，所以暫且叫做「Jollen&apos;s AFC」吧。不過，這次不打算出版實體書，原因有三： 1. 這是冷門書。內容不在迎合業界需求，而是希望寫出真正自已想像中的作品。 2. Light-weight content，頁數鎖定在 200 頁上下。簡單說，出版社考量實體書售價（根據頁數），以及管銷成本等，應該也不願意出版。 3. 不能 Print on demand，也就是不能「隨選列印」。有時讀者可能只想看，並且列印部份內容而已。 近二年，原文書掀起一股輕量級風，越是有深度、越是複雜的技術，內容就更輕量級。這種書的優點是，讀起來全不費工夫，而且一氣呵成，暢快無比。缺點是，底子不深，就很難啃，自已也踼過幾次鐵板。寫出這種書的作者，必定底子深厚，而且把知識融會貫通得很好。我決定多磨練一下功力，挑戰這種輕量級的寫作。 輕量級寫作的重點，在於頁數少，或是字數少。不過，最不重要的就是它的頁數或字數，而是內容的價值。輕量級的書，就是「底子不深不好啃」的概念，看起來小小一本，質量卻很大，讀起有重量。中文電腦書流行的磚頭書概念，也是經常有不錯的作品，但是請避免看起來很大，讀起來卻很輕的現象。例如，連續20頁都是程式碼（Source code listing）。 其實網路上有許多優質的短篇內容，但並不利於做實體出版，就算要出版，出版商也會請作者想辦法補到一定頁數。於是，為了補頁數、趕截稿，作者只好草草做工，所以最後的章節，也就草草了事。非常可惜。 為了不讓短篇內容，被出版商裝上義肢，所以 Amazon 就提出了一個解決方案。線上自助出版平臺。 Amazon 把這類有價值，字數介於一萬至三萬字間的短篇（小品），稱為 Single，並且搭配 Kindle Fire 推出了一個獨立的 Single 線上自助出版產品線。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[先前在「<a href="http://www.jollen.org/blog/2012/03/jollen-android-framework-complete-launch.html">Jollen 的 Android Framework Complete (框架大全) 課程發表、外加感想</a>」提到了想把 Jollen's AFC 寫成一本書的構想，現在開始付諸行動了。學生時代寫書，其實也不是為了寫書而寫，大多是平常做技術的零碎紀錄，再匯集而成。在看到自已的成果出版成實體書時，內心可是無比的感動與激動，要特別感謝旗標出版社當時給了我這麼好的機會。

這次，也打算開始整理手邊的資料，慢慢匯整成一本書，並且一邊整理，一邊上線。這就是數位內容的好處，不用一次全寫完再出版。新書的書名也未定，所以暫且叫做「Jollen's AFC」吧。不過，這次不打算出版實體書，原因有三：

1. 這是冷門書。內容不在迎合業界需求，而是希望寫出真正自已想像中的作品。

2. Light-weight content，頁數鎖定在 200 頁上下。簡單說，出版社考量實體書售價（根據頁數），以及管銷成本等，應該也不願意出版。

3. 不能 Print on demand，也就是不能「隨選列印」。有時讀者可能只想看，並且列印部份內容而已。

近二年，原文書掀起一股輕量級風，越是有深度、越是複雜的技術，內容就更輕量級。這種書的優點是，讀起來全不費工夫，而且一氣呵成，暢快無比。缺點是，底子不深，就很難啃，自已也踼過幾次鐵板。寫出這種書的作者，必定底子深厚，而且把知識融會貫通得很好。我決定多磨練一下功力，挑戰這種輕量級的寫作。

輕量級寫作的重點，在於頁數少，或是字數少。不過，最不重要的就是它的頁數或字數，而是內容的價值。輕量級的書，就是「底子不深不好啃」的概念，看起來小小一本，質量卻很大，讀起有重量。中文電腦書流行的磚頭書概念，也是經常有不錯的作品，但是請避免看起來很大，讀起來卻很輕的現象。例如，連續20頁都是程式碼（Source code listing）。

其實網路上有許多優質的短篇內容，但並不利於做實體出版，就算要出版，出版商也會請作者想辦法補到一定頁數。於是，為了補頁數、趕截稿，作者只好草草做工，所以最後的章節，也就草草了事。非常可惜。

為了不讓短篇內容，被出版商裝上義肢，所以 Amazon 就提出了一個解決方案。線上自助出版平臺。

Amazon 把這類有價值，字數介於一萬至三萬字間的短篇（小品），稱為 Single，並且搭配 Kindle Fire 推出了一個獨立的 Single 線上自助出版產品線。

所以，「Jollen's AFC」將考慮數位內容與數位出版。曾幾何時，實體出版居然變成作者的 Last choice。
]]>
      
   </content>
</entry>
<entry>
   <title>JavaScript 王者再臨</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/04/javascript-the-king-is-back.html" />
   <id>tag:www.jollen.org,2012:/blog//2.779</id>
   
   <published>2012-04-11T11:10:46Z</published>
   <updated>2012-04-12T10:23:28Z</updated>
   
   <summary>JavaScript 是「王者再臨」的最佳代言人，由於 jQuery 被大量應用在網頁設計上的原因，讓 JavaScript 再度被重視了起來；再加上 HTML5 的推波助瀾，JavaScript 儼然成為今年最受矚目的程式語言。 現在，JavaScript 的主要用途，已經由過去的動態網頁（Dynamic Webpages），轉為開發 HTML5 App 角色；也就是 HTML5 的應用。我們不僅僅使用 JavaScript 製作有動態效果的網頁，還藉助它來開發大量的 UI interactive、使用者體驗的設計，以及，最重要的雲端服務的整合。 還有一個很重要的應用，就是「JavaScript in Browser」，也就是利用 JavaScript 來增強瀏覽器的功能，最為大家所熟悉的例子，就是 Google Chrome。Google Chrome 為了增強對 JavaScript 的支援與效能，開發了新的 JavaScript 引擎；在日記「HTML5在手持裝置將開始爆發式成長」就提到了，「JavaScript引擎的成熟度是關鍵」。 所以，測試 JavaScript 的使用案例（Use Cases）在各大瀏覽器的效能，更為一項重要的工程工作。目前被軟體工程師廣為使用的 jsPerf 就是為此而生。更進一步地，由於...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="HTML5 &amp; JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[JavaScript 是「王者再臨」的最佳代言人，由於 jQuery 被大量應用在網頁設計上的原因，讓 JavaScript 再度被重視了起來；再加上 HTML5 的推波助瀾，JavaScript 儼然成為今年最受矚目的程式語言。

現在，JavaScript 的主要用途，已經由過去的動態網頁（Dynamic Webpages），轉為開發 HTML5 App 角色；也就是 HTML5 的應用。我們不僅僅使用 JavaScript 製作有動態效果的網頁，還藉助它來開發大量的 UI interactive、使用者體驗的設計，以及，最重要的雲端服務的整合。

還有一個很重要的應用，就是「JavaScript in Browser」，也就是利用 JavaScript 來增強瀏覽器的功能，最為大家所熟悉的例子，就是 Google Chrome。Google Chrome 為了增強對 JavaScript 的支援與效能，開發了新的 JavaScript 引擎；在日記「<a href="http://www.jollen.org/blog/2012/01/html-5-boost-up-mobile-devices.html">HTML5在手持裝置將開始爆發式成長</a>」就提到了，「JavaScript引擎的成熟度是關鍵」。

所以，測試 JavaScript 的使用案例（Use Cases）在各大瀏覽器的效能，更為一項重要的工程工作。目前被軟體工程師廣為使用的 <a href="http://jsperf.com/" target="_blank">jsPerf</a> 就是為此而生。更進一步地，由於 JavaScript 現在搭配 HTML5 來開發「軟體」，而不只是用來製作動態網頁，所以研究 JavaScript 的軟體設計模式，當然也就變成一門顯學；目前被廣為推薦的就是「<a href="http://addyosmani.com/resources/essentialjsdesignpatterns/book/" target="_blank">Essential JavaScript Design Patterns</a>」一書。

JavaScript 過去曾經在動態網頁製作上紅極一時，後來又迅速沈寂，2003到2007年這段時間，應該是 JavaScript 最谷底的時候。而後在 2007 到 2009 年，因為 Web 2.0 風格網頁，以及 jQuery 的盛行，再度得到開發者的重視。2010 到 2011 年因為 Mobile Native App 的大量流行，使得眾多開發者不再以 JavaScript 做為首選，再度走入低潮。

時間到了 2012 年，在 HTML5 時代正式啟動的今天，JavaScript 成為軟體工程師的必修語言，也是程式設計初學者的最佳選擇。從去年大約 1.5% 的使用率，飆升到這個月的 3.3% 左右的使用率。雖然它不是最受歡迎的程式語言，但是在「Browser & Webpages」的領域，頗有王者再臨的感覺。]]>
      
   </content>
</entry>
<entry>
   <title>[Jollen&apos;s AFC] 1.2 C &amp; Object-oriented</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/04/jollens_afc_1-2-c-object-oriented.html" />
   <id>tag:www.jollen.org,2012:/blog//2.778</id>
   
   <published>2012-04-08T04:11:58Z</published>
   <updated>2012-04-08T09:19:31Z</updated>
   
   <summary>Linux 核心是 implicit of object-oriented 的典型實例。例如，在開發驅動程式的過程中，雖然不需要特別了解驅動程式的物件導向架構，但其架構則是依循嚴謹的物件導向觀念。Linux 核心與驅動程式，都是以 C 語言實作。 另外一個例子，就是筆者在 Android Framework &amp; HAL 課程中所提到的 HAL Stub 觀念。HAL Stub 可採用 C 語言實作，編譯後以 *.so 形式佈署，但它不是程式庫(Library)，而是一個物件(Object)。 圖1.2 HAL Stub 架構 HAL 的模組稱為 Stub，Stub 是一種物件。Stub 在軟體工程領域代表「樁」的角色，也就是整體架構中的一小段基礎程式碼，這段程式碼有著以下二個特色： 1. 符合架構的程式碼（打地基） 2. 一段程式碼範本，最終的實作 (final implementation) 是代理人...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Linux 核心是 implicit of object-oriented 的典型實例。例如，在開發驅動程式的過程中，雖然不需要特別了解驅動程式的物件導向架構，但其架構則是依循嚴謹的物件導向觀念。Linux 核心與驅動程式，都是以 C 語言實作。

另外一個例子，就是筆者在 Android Framework & HAL 課程中所提到的 HAL Stub 觀念。HAL Stub 可採用 C 語言實作，編譯後以 *.so 形式佈署，但它不是程式庫(Library)，而是一個物件(Object)。

<img src="http://www.jollen.org/blog/2009/10/08/android-hal-libhardware.png" />
圖1.2 HAL Stub 架構

HAL 的模組稱為 Stub，Stub 是一種物件。Stub 在軟體工程領域代表「樁」的角色，也就是整體架構中的一小段基礎程式碼，這段程式碼有著以下二個特色：

1. 符合架構的程式碼（打地基）
2. 一段程式碼範本，最終的實作 (final implementation) 是代理人 (proxy) 的角色

但是，Android 將上述的物件導向封裝得非常好，不需要懂這些架構面的觀念，也能依循「步驟」實作出基本的 HAL Stub。

在軟體裡加上自已的實作，最重要的第一門課就是練習寫「樁」，也是打地基的程式碼。所以，我們要知道 Android 的整體架構，並依循其架構，設計並實作自已的 HAL Stub。由此可知，從事 Android 軟體整合開發，重要的背景知識是物件導向、軟體工程與 HAL 架構，而不是硬體的知識。另外，還有很重要的背景知識，就是如何以 C 語言實作物件導向設計。

步驟性的知識可以解決部份的工程(實作)問題，但因為缺乏系統性的觀念，將會影響解決整體性問題的能力。這就是「隱性物件導向」的概念，大部份我們接觸過的軟體，都是嚴謹的物件導向設計，只是因為它被封裝得很好，所以常常會忽略它，或是認為它不存在。

有一種誤解，可以說明這個現象。有些工程師，會誤以為使用 C 語法實作的軟體，並不是物件導向的架構，實則不然。Linux 核心便是一個很好的例子。Axel-Tobias Schreiner 在 1993 年發表了著作「Object-oriented programming with ANSI-C」，解釋了如何使用標準 C 語言 (ANSI C) 撰寫物件導向程式碼；國外有些大學，甚致將這個科目列為必修課。

因此，C 語言是隱性的物件導向程式碼，因為它不像 C++ 或 Java，有著明顯的物件導向語法特徵。這點對於研究工作其實是個麻煩，因為 C 語言沒有鮮明的物件導向語法，所以經常需要花費時間，來探索隱藏其中的物件導向設計。]]>
      
   </content>
</entry>
<entry>
   <title>[Jollen&apos;s AFC] 1.1 切割 View &amp; Control</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/04/jollens_afc_1-1-separate-view-control.html" />
   <id>tag:www.jollen.org,2012:/blog//2.776</id>
   
   <published>2012-04-03T05:23:58Z</published>
   <updated>2012-04-03T11:05:16Z</updated>
   
   <summary>將View與Control切割是軟體設計的根本。這個觀念非常的好懂，也是學習軟體設計的基本功。View被解釋成UI等可見物，Control則是控制功能，例如：關機。一般來說，控制功能由控制者提供，所以經常被稱為View/Controller模式。 這個觀念真的簡單不過，把畫面與控制功能分開。這個觀念的發展始於 1980 年代，當時為了開發圖形介面的電腦，電腦科學家於是想到「 Separated Presentation」，也就是從事視覺(Presenetation)的程式碼就只做視覺(例如：Drawing)，把其餘的切割(separated)出來。後來形成今天家喻戶曉的軟體設計模式 - MVC(Model-View-Controller)。 把View與Controller切割的觀念被一直沿用到今天，所以先想清楚View/Controller為什麼切割，原因何在？才是重點。「Model」是擴充出來的觀念(Concept extending)，所以，可以先將「Model」是什麼放著不談。 將View與Controller切割是為了不讓控制的動作影嚮到畫面(View)，根本原因是希望有更好的使用者體驗。做法很簡單，從現今的分時多工作業系統(Time-sharing &amp; multi-task operating system)角度來看，只要切割成獨立的process即可。如圖1.1。 二個process就使用訊息(message)傳遞的方式溝通，也就是我們所熟悉的IPC(Inter-process communication)。 切割 View &amp; Control Android 系統將 View &amp; Control 切割，因為這樣可以設計出 UI 使用性更好的軟體。同時還有二個好處。第一、讓程式碼更容易維護，第二、軟體架構更清楚。為什麼將 View 與 Control 切割成獨立的 process，可以讓 Android 系統有更好的 UI 使用性呢？...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[將View與Control切割是軟體設計的根本。這個觀念非常的好懂，也是學習軟體設計的基本功。View被解釋成UI等可見物，Control則是控制功能，例如：關機。一般來說，控制功能由控制者提供，所以經常被稱為View/Controller模式。

這個觀念真的簡單不過，把畫面與控制功能分開。這個觀念的發展始於 1980 年代，當時為了開發圖形介面的電腦，電腦科學家於是想到「 Separated Presentation」，也就是從事視覺(Presenetation)的程式碼就只做視覺(例如：Drawing)，把其餘的切割(separated)出來。後來形成今天家喻戶曉的軟體設計模式 - MVC(Model-View-Controller)。

把View與Controller切割的觀念被一直沿用到今天，所以先想清楚View/Controller為什麼切割，原因何在？才是重點。「Model」是擴充出來的觀念(Concept extending)，所以，可以先將「Model」是什麼放著不談。

將View與Controller切割是為了不讓控制的動作影嚮到畫面(View)，根本原因是希望有更好的使用者體驗。做法很簡單，從現今的分時多工作業系統(Time-sharing & multi-task operating system)角度來看，只要切割成獨立的process即可。如圖1.1。


<img alt="view-controller.png" src="http://www.jollen.org/blog/2012/04/03/view-controller.png" width="581" height="413" />

二個process就使用訊息(message)傳遞的方式溝通，也就是我們所熟悉的IPC(Inter-process communication)。

<strong>切割 View & Control</strong>

Android 系統將 View & Control 切割，因為這樣可以設計出 UI 使用性更好的軟體。同時還有二個好處。第一、讓程式碼更容易維護，第二、軟體架構更清楚。為什麼將 View 與 Control 切割成獨立的 process，可以讓 Android 系統有更好的 UI 使用性呢？
]]>
      
   </content>
</entry>
<entry>
   <title>[Jollen&apos;s AFC] 1. Implicit of Object-oriented</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/04/jollens_afc-1-implicit-of-object-oriented.html" />
   <id>tag:www.jollen.org,2012:/blog//2.775</id>
   
   <published>2012-04-03T04:47:32Z</published>
   <updated>2012-04-03T10:14:27Z</updated>
   
   <summary>自從完成「Jollen 的 Android Framework Complete (框架大全) 課程」後，對於軟體設計領域有了更深一層的認識，並且發現許多軟體設計的美麗之處。接下來的工作，除了過去近十年的系統程式領域，也打算在軟體設計領域繼續提升。系統程式(systems software)的技術工作，除了需要大量的經驗累積外，還需要「手感」；這點相信有經驗的系統程式高手，都有同感，所以必須保持不斷的接觸程式碼。系統程式領域廣大，包含：kernel、device drvier等，這些都是筆者過去相當有興趣的主題；所謂的「手感」就像是寫文章，需要偶而一點靈感才行。 系統程式領域，主題與範圍一般都較為明確，例如：kernel。軟體設計領域，範圍更大，所涉及的知識也更多，例如：網路、使用者。無論是系統程式，或是軟體設計，都會有共同的背景知識，例如：物件導向(Object-oriented, OO)。 初學 kernel 或 device driver 的開發者，或許不會知道 kernel 本身就是物件導向的設計；實務上，如果專注在工程面(Engineering)，其實也不太需要深入了解 kernel 與物件導向的關係。所以在 kernel 與 device driver 領域，物件導向是 implicit，隱性的。 在軟體設計方面，例如：Android framework，如果不了解 subsystem 的物件導向設計，以及設計模式(Design pattern)，並不太容易看懂其程式碼(Source code)，並且幾乎影響了後續工程工作的進行。所以在 Android framework 領域，物件導向是 explicit，顯性的。 這就是過去幾年為企業進行相關教育訓練時，有些主題我會特別強調 Object-oriented 與...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[自從完成「<a href="http://www.jollen.org/blog/2012/03/jollen-android-framework-complete-launch.html">Jollen 的 Android Framework Complete (框架大全) 課程</a>」後，對於軟體設計領域有了更深一層的認識，並且發現許多軟體設計的美麗之處。接下來的工作，除了過去近十年的系統程式領域，也打算在軟體設計領域繼續提升。系統程式(systems software)的技術工作，除了需要大量的經驗累積外，還需要「手感」；這點相信有經驗的系統程式高手，都有同感，所以必須保持不斷的接觸程式碼。系統程式領域廣大，包含：kernel、device drvier等，這些都是筆者過去相當有興趣的主題；所謂的「手感」就像是寫文章，需要偶而一點靈感才行。

系統程式領域，主題與範圍一般都較為明確，例如：kernel。軟體設計領域，範圍更大，所涉及的知識也更多，例如：網路、使用者。無論是系統程式，或是軟體設計，都會有共同的背景知識，例如：物件導向(Object-oriented, OO)。

初學 kernel 或 device driver 的開發者，或許不會知道 kernel 本身就是物件導向的設計；實務上，如果專注在工程面(Engineering)，其實也不太需要深入了解 kernel 與物件導向的關係。所以在 kernel 與 device driver 領域，物件導向是 implicit，隱性的。

在軟體設計方面，例如：Android framework，如果不了解 subsystem 的物件導向設計，以及設計模式(Design pattern)，並不太容易看懂其程式碼(Source code)，並且幾乎影響了後續工程工作的進行。所以在 Android framework 領域，物件導向是 explicit，顯性的。

這就是過去幾年為企業進行相關教育訓練時，有些主題我會特別強調 Object-oriented 與 design pattern，有些主題僅介紹機制與作法(practice)的原因。這是老師的責任，評斷並決定主題的切入點以及重心。例如，最近在介紹 Android 的 graphics system 時，我就會特別說明 Surface 與 SurfaceHolder.Callback 的 MVC 模式。

<strong>Implicit of Object-oriented</strong>

所以，並不是作業系統不需要用到物件導向觀念，也不是物件導向觀念是用在大型軟體開發上(有些教科書的說法)。而是，在某些時候，它是相當 implicit 的。原創者(Creator)將物件導向的觀念封裝到非常好，好到使用者(Users/coders)只需要照圖施工，就可以保證成功。最好的例子，就是 Linux kernel。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android Framework Complete (框架大全) 課程發表、外加感想</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/03/jollen-android-framework-complete-launch.html" />
   <id>tag:www.jollen.org,2012:/blog//2.774</id>
   
   <published>2012-03-16T16:36:50Z</published>
   <updated>2012-03-16T22:26:27Z</updated>
   
   <summary>就用 Jollen 的 AFC 當做 Android 研究工作的段落吧。在 2007 年底接觸 Android 時，還沒有很用心去投入研究工作，記得當時還在 Openmoko 公司，負責教育市場的推展。到了 2008 年底，Openmoko 社群將 Android 移植到 Neo FreeRunner 後，便開始對 Android 的框架研究產生了興趣。當時，花費比較多時間其實還是在移植(Porting)的層面，除了改改一些小東西，寫點移植手冊外(為了學校推廣、後來沒有發表)，還是很零星地在 Android Framework 研究工作上。 離開 Openmoko 公司後，便創辦 Moko365 公司，給新公司的定位是 Research Company。當時心想，台灣未來勢必走向軟體開發之路。了解軟體的人，一定知道技術研究工作的重要性。畢竟，技術研究工作，是技術開發之母。再加上 Android 龐大又複雜的架構，如果可以有一家公司，專職做「技術研究」，為產業提供研究成果，勢必能對產業有所貢獻。就是這個想法，所以自已做下去了。 術業有專攻。我來做研究與發展(Research and Development)，硬體公司做工程(Engineering)，大家分工把最後的工作，也就是「產品」做好。 在成立 Moko365...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[就用 Jollen 的 AFC 當做 Android 研究工作的段落吧。在 2007 年底接觸 Android 時，還沒有很用心去投入研究工作，記得當時還在 Openmoko 公司，負責教育市場的推展。到了 2008 年底，Openmoko 社群將 Android 移植到 Neo FreeRunner 後，便開始對 Android 的框架研究產生了興趣。當時，花費比較多時間其實還是在移植(Porting)的層面，除了改改一些小東西，寫點移植手冊外(為了學校推廣、後來沒有發表)，還是很零星地在 Android Framework 研究工作上。

離開 Openmoko 公司後，便創辦 Moko365 公司，給新公司的定位是 Research Company。當時心想，台灣未來勢必走向軟體開發之路。了解軟體的人，一定知道技術研究工作的重要性。畢竟，技術研究工作，是技術開發之母。再加上 Android 龐大又複雜的架構，如果可以有一家公司，專職做「技術研究」，為產業提供研究成果，勢必能對產業有所貢獻。就是這個想法，所以自已做下去了。

術業有專攻。我來做研究與發展(Research and Development)，硬體公司做工程(Engineering)，大家分工把最後的工作，也就是「產品」做好。

在成立 Moko365 後，我就是全職的研究員了。一轉眼，過了三年。要細數 Android 的複雜與龐大，當了三年全職的 Android Researcher，可說是有心酸滿腹。這項工作，對我來說，其實是相當有趣的。在這1000個日子裡，對 Android Framework 所做的研究，不敢講是最完整的，但至少產出相當驚人。

這些成果，終於在上週，以「Jollen 的 Android Framework Complete（AFC、框架大全）」正式推出系列課程。說這是課程，倒不如說是服務，因為總計30門課程，如果一週一門課，也要二年半才能開得完。所以，現在只能用「客戶點餐」的方式，提供「研究成果報告」的服務形式。

這正是 Moko365 公司當初成立的核心精神，一家研究公司。我一直想著，就像「供應鍊」一樣，研究公司必定是軟體產業鍊裡，重要的一個環節。它提供迅速、確實又即時的「研究報告」，讓產品公司，大家不用做重覆的工，而且能節省成本。

一個內部的 Android 研究團隊，假設是 3 個人，這應該是最小的編組了。每個人的年管銷費用（薪水加上辦公室等固定成本），以150萬計（年薪75萬x2），這個研究小組的成本每年就是 450 萬。但是跟研究公司買報告或服務，只要這個費用的五折、或三折，或更低。而且得到的是內容維護更精緻的報告。更重要的是，這種模式風險非常低，也節省很多時間。風險與時間，是更重要的成本。

基於這個理念，三年前成立 Moko365 後投入研究工作，到今天超過了 1000 個研究日，所以在此向大家正式介紹 [<a href="http://www.moko365.com/enterprise/android-framework-complete">Jollen 的 Android Framework Complete</a>]。今年初，我已經將研究與開發工作，從 Android 轉入到另外一個領域，所以 AFC 也算是繳出了一張成績單。

下一個目標？除了新的研究領域外，也想再來寫寫書。

大學時代，當個學生，時間總是感覺特別多，四年時間發表了超過10本的著作。還有一本，當年曾登上天瓏排行榜第一名。算一算離最近一次出書，也快十年了，希望可以逐步整理 AFC 內容，終結可能會有十年沒出書的紀錄 ;-)]]>
      
   </content>
</entry>
<entry>
   <title>HTC硬體規格優勢已不在、應思考產品差異化的價值</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/03/htc-in-mwc-2013.html" />
   <id>tag:www.jollen.org,2012:/blog//2.773</id>
   
   <published>2012-03-01T09:09:40Z</published>
   <updated>2012-03-01T15:47:47Z</updated>
   
   <summary><![CDATA[這幾天看了MWC 2012的消息，華為與中興在手機領域的大躍進令人配服，還有三星的Galaxy SII可說是壓倒性的勝利，不但是銷售之王，幫助三星拿到2011年的智慧型手機龍頭外，也贏得今年的最佳智能手機獎。對此，心裡特別有感，所以很簡單的寫了一篇分享文；希望大家一起為HTC加油。 宏達電(HTC)在2010年MWC推出HTC Desire時，獲得相當不錯的迴響，網路上紛紛以「最強的Android手機」來評價它。當時的三星，在Android手機領域，完全沒有任何建樹。即使是今年震撼MWC的華為(Huawei)，或是令人刮目相看的中興(ZTE)，當年推出的Android手機完全無法與HTC Desire抗衡。在硬體規格上落後HTC一大截。 HTC一向都是領先的硬體技術者，在2011 MWC推出Incredible S時，硬體技術仍舊領先業界；今年的MWC，繼續以HTC One X保持領先的硬體技術。HTC One系列更再加碼，以自有的ImageSense軟硬體技術，把手機照像功能再推上一層樓。仕橙部落特別將HTC過去三年來的MWC主打機，做了一個整理。 &nbsp; 2010 MWCHTC Desire 2011 MWCHTC Incredible S 2012 MWCHTC One X 作業系統 Android 2.1 (Eclair) Android 2.2 (Froyo) Android 4.0 (ICS) 機身厚度 11.9mm 11.7mm 9.29mm 重量 150g...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p style="text-align: left;">這幾天看了MWC 2012的消息，華為與中興在手機領域的大躍進令人配服，還有三星的Galaxy SII可說是壓倒性的勝利，不但是銷售之王，幫助三星拿到2011年的智慧型手機龍頭外，也贏得今年的最佳智能手機獎。對此，心裡特別有感，所以很簡單的寫了一篇分享文；希望大家一起為HTC加油。</p>

<p style="text-align: left;">宏達電(HTC)在2010年MWC推出HTC Desire時，獲得相當不錯的迴響，網路上紛紛以「最強的Android手機」來評價它。當時的三星，在Android手機領域，完全沒有任何建樹。即使是今年震撼MWC的華為(Huawei)，或是令人刮目相看的中興(ZTE)，當年推出的Android手機完全無法與HTC Desire抗衡。在硬體規格上落後HTC一大截。</p>
<p style="text-align: left;">HTC一向都是領先的硬體技術者，在2011 MWC推出Incredible S時，硬體技術仍舊領先業界；今年的MWC，繼續以HTC One X保持領先的硬體技術。HTC One系列更再加碼，以自有的ImageSense軟硬體技術，把手機照像功能再推上一層樓。仕橙部落特別將HTC過去三年來的MWC主打機，做了一個整理。</p>

<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="75">&nbsp;</td>
<td valign="top" width="150">2010 MWC<br /><strong>HTC Desire</strong></td>
<td valign="top" width="150">2011 MWC<br /><strong>HTC Incredible S</strong></td>
<td valign="top" width="150">2012 MWC<br /><strong>HTC One X</strong></td>
</tr>
<tr>
<td valign="top" width="75">作業系統</td>
<td valign="top" width="150">Android 2.1
(Eclair)</td>
<td valign="top" width="150">Android 2.2
(Froyo)</td>
<td valign="top" width="150">Android 4.0
(ICS)</td>
</tr>
<tr>
<td valign="top" width="75">機身厚度</td>
<td valign="top" width="150">11.9mm</td>
<td valign="top" width="150">11.7mm</td>
<td valign="top" width="150">9.29mm</td>
</tr>
<tr>
<td valign="top" width="75">重量</td>
<td valign="top" width="150">150g</td>
<td valign="top" width="150">136g</td>
<td valign="top" width="150">153g</td>
</tr>
<tr>
<td valign="top" width="75">記憶體(RAM)</td>
<td valign="top" width="150">576MB</td>
<td valign="top" width="150">768MB</td>
<td valign="top" width="150">1GB</td>
</tr>
<tr>
<td valign="top" width="75">螢幕規格</td>
<td valign="top" width="150">3.7” / 480x800
AMOLED</td>
<td valign="top" width="150">4” /  480x800
SuperLCD</td>
<td valign="top" width="150">4.7” / 720x1280
SuperLCD</td>
</tr>
<tr>
<td valign="top" width="75">應用處理器</td>
<td valign="top" width="150">單核 1GHz
(Qualcomm)</td>
<td valign="top" width="150">單核 1GHz</td>
<td valign="top" width="150">四核 1.5GHz
(nVidia Tegra 3)</td>
</tr>
<tr>
<td valign="top" width="75">像機</td>
<td valign="top" width="150">5MP
720P 錄影</td>
<td valign="top" width="150">8MP
720P 錄影</td>
<td valign="top" width="150">8MP
1080P 錄影</td>
</tr>
</tbody>
</table>
<p style="text-align: left;">製表：<a href="http://www.moko365.com/" target="_blank">仕橙部落</a></p>
<p style="text-align: left;">從這張表可以發現，HTC在2010年時，硬體技術可說是大幅領先同業，以華為來說，當年所推出的機種，應用處理器也只有528MHz，螢幕規格更差了一大截。到了2011年，HTC Incredible S仍舊領先競爭對手，不過差距已經縮小許多。</p>
<p style="text-align: left;">到了今年，大家從媒體的報導就可以看得出來，HTC One X已經沒有硬體技術的優勢了；除了ImageSense外，華為與中興都已經和HTC並駕齊驅。</p>

<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="180">&nbsp;</td>
<td valign="top" width="180"><strong>HTC One X</strong></td>
<td valign="top" width="180"><strong>Huawei Ascend D quad</strong></td>
</tr>
<tr>
<td valign="top" width="180">預計上市時間</td>
<td valign="top" width="180">2Q’12</td>
<td valign="top" width="180">2Q’12</td>
</tr>
<tr>
<td valign="top" width="180">作業系統</td>
<td valign="top" width="180">Android 4.0 (ICS)</td>
<td valign="top" width="180">Android 4.0 (ICS)</td>
</tr>
<tr>
<td valign="top" width="180">機身厚度</td>
<td valign="top" width="180">9.29mm</td>
<td valign="top" width="180">8.9mm</td>
</tr>
<tr>
<td valign="top" width="180">重量</td>
<td valign="top" width="180">153g</td>
<td valign="top" width="180">130g</td>
</tr>
<tr>
<td valign="top" width="180">記憶體(RAM)</td>
<td valign="top" width="180">1GB</td>
<td valign="top" width="180">1GB</td>
</tr>
<tr>
<td valign="top" width="180">後鏡頭(rear)</td>
<td valign="top" width="180">8MP</td>
<td valign="top" width="180">8MP BSI</td>
</tr>
<tr>
<td valign="top" width="180">前鏡頭(front)</td>
<td valign="top" width="180">1.3MP</td>
<td valign="top" width="180">1.3MP</td>
</tr>
<tr>
<td valign="top" width="180">通訊規格</td>
<td valign="top" width="180">HSPA+ / LTE</td>
<td valign="top" width="180">HSPA+ / LTE</td>
</tr>
<tr>
<td valign="top" width="180">螢幕規格</td>
<td valign="top" width="180">4.7” / 720x1280<br />SuperLCD (312ppi)</td>
<td valign="top" width="180">4.5” / 720x1280<br />LCD (330ppi)</td>
</tr>
<tr>
<td valign="top" width="180">應用處理器</td>
<td valign="top" width="180">nVidia Tegra 3<br />Quad-core (1.5GHz)</td>
<td valign="top" width="180">K3V2 (ARM)<br />Quad-core 1.5GHz</td>
</tr>
</tbody>
</table>
<p style="text-align: left;">製表：<a href="http://www.moko365.com/" target="_blank">仕橙部落</a></p>

<p style="text-align: left;">這倒是給了我們一個警示。2010年到2012年，實質上只有二個整年；華為與中興從大幅落後，到現在迎頭趕上，只花了730天的時間。這說明了，如果2013 MWC還是主打硬體規格，競爭對手之間，已經沒有任何差異性了；就像 [<a href="http://www.moko365.com/enterprise/news-20120229-mwc-2012-htc-new-arrivals" target="_blank">HTC新機功能強大　仍缺”獨賣”價值</a>] 提到的：</p>
<p style="text-align: left;"><em>分析師指出，雖然HTC在這次大會中證實自己仍是手機硬體技術的領導品牌廠，但這並不足以成為強大的競爭優勢，因為這些門檻別人很快就會跨越追上。</em></p>
<p style="text-align: left;">筆者的看法很簡單，HTC已經不需要向誰證明它的硬體技術，或是製造能力了，專注思考「差異化的價值」，一定能做得非常不錯。如果不認真去思考什麼是差異化的價值，那可能完全想不透，為什麼Samsung Galaxy SII能獲得如此迅速又巨大的成功；這可不是因為AMOLED面板被斷貨，這麼簡單的原因。而且，用什麼作業系統，對HTC來說也不是很重要的事情，也不必去再乎Bada作業系統的潛在影響力。</p>]]>
      
   </content>
</entry>
<entry>
   <title>該來的終於來了：HTML5大戰拉開序幕</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/02/html5-evolution.html" />
   <id>tag:www.jollen.org,2012:/blog//2.772</id>
   
   <published>2012-02-13T13:56:16Z</published>
   <updated>2012-02-13T20:00:05Z</updated>
   
   <summary>Android版的Chrome瀏覽器出現了，Chrome是HTML5發展史的一個重要指標。預計今年HTML5(Chrome)將全面走入各式產品，這宣告純硬體時代正式結束了。未來的產品，少了軟體與雲端的加持，將顯得平傭而無奇。純硬體能走進市場的機會，只會越來越少。手機肯定首當其衝。特別是Android版的Chrome瀏覽器現身了，它將引發新軟體革命嗎？ 我們知道，雲端應用目前有二大龍頭：Google與Facebook。Google老大哥的Gmail、相簿、位置服務等，儼然成為一項民生必須品。Facebook則是在社交網路(Social Networking)領域獨佔鰲頭。他們都是網路巨擎，也都是以平臺(Platform)的概念經營。平臺的概念是什麼？簡單說，就是提供開發者API服務。 平臺是一個很容易理解的概念，就像大家手上的手機，裡頭安裝了許多使用到Google以及Facebook API的App；這些App都會透過「雲端」，存取其服務。iPhone與Android手機裡的這些「雲端App」，所使用到的核心技術，就是HTML5。這代表著，只要HTML5的規格能開始推出草案(Draft)，並且手機上的HTML5瀏覽器技術更加成熟，手機行業將會展開一場HTML5大戰。HTML5大戰就是雲端運算的戰爭，這肯定是新一波的軟體革命。以HTML5技術，結合網路服務、開發App，並整合至手機，將成為顯學。 所以，筆者認為，Android版Chrome的到來，從產業的角度來看，肯定是一個重要指標，具有特別的意義。它將帶領HTML5往前衝刺。其實，Chrome很早就是HTML5的領頭羊了，例如：早在2010年，Google就宣佈以HTML5取代Google Gear技術，從這裡可見一斑。 我們可以這樣假設：有了Chrome，雲(Cloud Computing)就更容易放進裝置裡。正因為如此，所以Chrome的出現，有了HTML5大戰的煙焇味。Chrome將加速雲端應用走進手機App，所以手機不能只有硬體功能，硬體廠將面臨新的一波挑戰。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p style="text-align: left;">Android版的Chrome瀏覽器出現了，Chrome是HTML5發展史的一個重要指標。預計今年HTML5(Chrome)將全面走入各式產品，這宣告純硬體時代正式結束了。未來的產品，少了軟體與雲端的加持，將顯得平傭而無奇。純硬體能走進市場的機會，只會越來越少。手機肯定首當其衝。特別是Android版的Chrome瀏覽器現身了，它將引發新軟體革命嗎？</p>
<img src="http://www.moko365.com/enterprise/wp-content/uploads/misc/html5.jpg" alt="" width="525" height="300" />
<p style="text-align: left;">我們知道，雲端應用目前有二大龍頭：Google與Facebook。Google老大哥的Gmail、相簿、位置服務等，儼然成為一項民生必須品。Facebook則是在社交網路(Social Networking)領域獨佔鰲頭。他們都是網路巨擎，也都是以平臺(Platform)的概念經營。平臺的概念是什麼？簡單說，就是提供開發者API服務。</p>
<p style="text-align: left;">平臺是一個很容易理解的概念，就像大家手上的手機，裡頭安裝了許多使用到Google以及Facebook API的App；這些App都會透過「雲端」，存取其服務。iPhone與Android手機裡的這些「雲端App」，所使用到的核心技術，就是HTML5。這代表著，只要HTML5的規格能開始推出草案(Draft)，並且手機上的HTML5瀏覽器技術更加成熟，手機行業將會展開一場HTML5大戰。HTML5大戰就是雲端運算的戰爭，這肯定是新一波的軟體革命。以HTML5技術，結合網路服務、開發App，並整合至手機，將成為顯學。</p>
<p style="text-align: left;">所以，筆者認為，Android版Chrome的到來，從產業的角度來看，肯定是一個重要指標，具有特別的意義。它將帶領HTML5往前衝刺。其實，Chrome很早就是HTML5的領頭羊了，例如：早在2010年，Google就宣佈以HTML5取代Google Gear技術，從這裡可見一斑。</p>
<p style="text-align: left;">我們可以這樣假設：有了Chrome，雲(Cloud Computing)就更容易放進裝置裡。正因為如此，所以Chrome的出現，有了HTML5大戰的煙焇味。Chrome將加速雲端應用走進手機App，所以手機不能只有硬體功能，硬體廠將面臨新的一波挑戰。</p>]]>
      
   </content>
</entry>
<entry>
   <title>台灣ICT產業的出路：雲端與App？（中天新聞2012經濟危機特報）</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/02/taiwan-2012-ict.html" />
   <id>tag:www.jollen.org,2012:/blog//2.771</id>
   
   <published>2012-02-08T14:16:36Z</published>
   <updated>2012-02-08T21:19:19Z</updated>
   
   <summary>中天新聞今天播出陳文茜小姐主持的特別節目「2012經濟危機特報-內閣改組篇」，討論到台灣ICT產業的發展，有一段討論讓我很有共鳴，所以在這裡簡單做的紀錄。這篇文章的內容，完全沒有任何政治立場，純綷就是關心一個與自己切身相關的話題，並分享給大家。 這幾天有二則新聞。第一則是台北市政府App鑑賞期事件的後續，第二則是張委員提到，「政府主導教育雲、醫療雲 ‎」。台灣科技業是否能重返榮耀，或是繼續失落，需要一個強力政策，更需要有眼光的政府團隊。目前看來，「雲端產業」，是重振台灣科技業的主導政策。 今天陳文茜小姐的節目，有二位來賓談到了這個App事件，以及雲端產業的願景。這是和我們非常密切的主題。關於台北市政府的App事件，新科政務委員張善政提到二個重點。第一個重點，我們需要一個合乎時宜的法規，也就是，並不是不去規範App收費，但是不能用一個落伍的法律，去限制一個產業的發展。 其實，在這個事件發生後，網路上有相當多「法律落伍」的聲音。政府去年也表示，可以發佈一個特別法來解決這個問題。但很不幸地，前幾天經濟部的裁決結果，仍支持台北市政府的看法。App事件，或許能定調是法規落後。個人看法是，大陸與韓國有關App商店的法規內容，應能做為修正的藍本。 第二個重點是，張委員認為，法規會的葉慶元先生法律出身，不懂科技，是逐字在執行法律，這是「法匠」；張委員認為，應該協助葉慶元先生了解科技。所以，他有意找葉慶元先生溝通。張善政出身科技業，在科技圏相當有份量，這次辭去Google的工作，到政府單位服務，來自專業領域，果然有一種耳目一新的感覺。 另外，有一段對話頗為有趣。張委員說，可以為新內閣上課，第一堂課就是了解科技，了解雲端產業；宅神朱學恆接腔說，張委員沒空的話，他可以代勞這個手腳工，幫新內閣上課。講到這段時，現場來賓還拍手，...。我想說，有機會的話，我也可以貢獻自已的淺薄能力（此想法純屬虛構，不敢造次）。 關於雲端產業的發展，陳文茜提到韓國的做法，張委員認為，雲端園區，也可以是虛擬園區，只要提供一個「公共雲」，也就是為年輕人打造一個發展的舞台，這樣甚至可以「到宜蘭上午衝浪、下午在房間做App」。張委員認為，除了雲端產業，App產業也是可以納入的一環。 以上紀錄出自「2012經濟危機特報-內閣改組篇」，未來應該可以在 Youtube 上找到影片。上述內容若有誤，也請大家指正。台灣在2012年會臨經濟危機？我想不至於這麼嚴重啦。台灣的App軟體人才，水準很高，一起加油吧。 後記。張善政回應主持人說他不敢想到李國鼎的層次，但是台灣需要你是第二個李國鼎。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      中天新聞今天播出陳文茜小姐主持的特別節目「2012經濟危機特報-內閣改組篇」，討論到台灣ICT產業的發展，有一段討論讓我很有共鳴，所以在這裡簡單做的紀錄。這篇文章的內容，完全沒有任何政治立場，純綷就是關心一個與自己切身相關的話題，並分享給大家。

這幾天有二則新聞。第一則是台北市政府App鑑賞期事件的後續，第二則是張委員提到，「政府主導教育雲、醫療雲 ‎」。台灣科技業是否能重返榮耀，或是繼續失落，需要一個強力政策，更需要有眼光的政府團隊。目前看來，「雲端產業」，是重振台灣科技業的主導政策。

今天陳文茜小姐的節目，有二位來賓談到了這個App事件，以及雲端產業的願景。這是和我們非常密切的主題。關於台北市政府的App事件，新科政務委員張善政提到二個重點。第一個重點，我們需要一個合乎時宜的法規，也就是，並不是不去規範App收費，但是不能用一個落伍的法律，去限制一個產業的發展。

其實，在這個事件發生後，網路上有相當多「法律落伍」的聲音。政府去年也表示，可以發佈一個特別法來解決這個問題。但很不幸地，前幾天經濟部的裁決結果，仍支持台北市政府的看法。App事件，或許能定調是法規落後。個人看法是，大陸與韓國有關App商店的法規內容，應能做為修正的藍本。

第二個重點是，張委員認為，法規會的葉慶元先生法律出身，不懂科技，是逐字在執行法律，這是「法匠」；張委員認為，應該協助葉慶元先生了解科技。所以，他有意找葉慶元先生溝通。張善政出身科技業，在科技圏相當有份量，這次辭去Google的工作，到政府單位服務，來自專業領域，果然有一種耳目一新的感覺。

另外，有一段對話頗為有趣。張委員說，可以為新內閣上課，第一堂課就是了解科技，了解雲端產業；宅神朱學恆接腔說，張委員沒空的話，他可以代勞這個手腳工，幫新內閣上課。講到這段時，現場來賓還拍手，...。我想說，有機會的話，我也可以貢獻自已的淺薄能力（此想法純屬虛構，不敢造次）。

關於雲端產業的發展，陳文茜提到韓國的做法，張委員認為，雲端園區，也可以是虛擬園區，只要提供一個「公共雲」，也就是為年輕人打造一個發展的舞台，這樣甚至可以「到宜蘭上午衝浪、下午在房間做App」。張委員認為，除了雲端產業，App產業也是可以納入的一環。

以上紀錄出自「2012經濟危機特報-內閣改組篇」，未來應該可以在 Youtube 上找到影片。上述內容若有誤，也請大家指正。台灣在2012年會臨經濟危機？我想不至於這麼嚴重啦。台灣的App軟體人才，水準很高，一起加油吧。

後記。張善政回應主持人說他不敢想到李國鼎的層次，但是台灣需要你是第二個李國鼎。
      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] 如何成功 Android 4.0 移植, #2: Early suspend 設定</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/02/android-4-0-porting-2.html" />
   <id>tag:www.jollen.org,2012:/blog//2.770</id>
   
   <published>2012-02-02T05:55:24Z</published>
   <updated>2012-02-02T13:15:17Z</updated>
   
   <summary>本文使用的Linux內核版本是2.6.35.7，若使用其它版本，設定選項的位置可能會有所不同。根據先前的說明，我們將分別設定Early suspend、Quota v2與Framebuffer功能。 關於 Early suspend 的設定，請打開以下功能： ● Power management options -&gt; Wake lock (圖1) ● Power management options -&gt; Wake lock -&gt; Early suspend （圖1) 圖1: Wake lock 與 Early suspend 設定 接著，底下有一個項目： ● User-space screen access (圖2) 圖2:...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本文使用的Linux內核版本是2.6.35.7，若使用其它版本，設定選項的位置可能會有所不同。根據先前的說明，我們將分別設定Early suspend、Quota v2與Framebuffer功能。

關於 Early suspend 的設定，請打開以下功能：

● Power management options -> Wake lock (圖1)
● Power management options -> Wake lock -> Early suspend （圖1)

<img alt="ics-kernel-configs-1.png" src="http://www.jollen.org/blog/2012/02/02/ics-kernel-configs-1.png" width="777" height="511" />
圖1: Wake lock 與 Early suspend 設定

接著，底下有一個項目：

● User-space screen access (圖2)

<img alt="ics-kernel-configs-2.png" src="http://www.jollen.org/blog/2012/02/02/ics-kernel-configs-2.png" width="776" height="510" />
圖2: User-space screen access 設定

將這個功能設定為「Sysfs interface」，意思是在 /sys 目錄裡產生 Framebuffer 驅動程式的 suspend/resume sysfs 檔案。Android 4.0 的 Surfaceflinger 現在會使用到這個功能，沒有開啟的話，Android 開機時會因為無法正常啟動 Surfaceflinger，而導致開機失敗。

<strong>延伸閱讀</strong>

● <a href="http://www.jollen.org/blog/2012/01/android-4-0-porting-1.html">[教育訓練紀錄] 如何成功 Android 4.0 移植, #1: 三個常見的kernel configs問題</a>
]]>
      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] 如何成功 Android 4.0 移植, #1: 三個常見的kernel configs問題</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/01/android-4-0-porting-1.html" />
   <id>tag:www.jollen.org,2012:/blog//2.769</id>
   
   <published>2012-01-31T03:39:18Z</published>
   <updated>2012-02-02T11:56:41Z</updated>
   
   <summary>延續「Ice Cream Sandwich (Android 4.0) 移植與框架」課後紀錄，與大家分享一些Android 4.0的移植經驗。移植Android 4.0的第一個階段稱為Bring-up，簡單說，就是要想辦法將Android放到硬體上，並且要能成功開機。 影響是否能Bring-up的關鍵之一，就是kernel的設定。因為驅動程式的關係， 一般認為，使用Linux 3.0系列是比較好的做法。不過，2.6.3x或3.x的版本，都能支援Android 4.0。在這次的課程裡，筆者使用了三個平臺。第一個是MagicLEGO計畫所開發的MagicLEGO開發板，MagicLEGO使用三星的Exynos 4210雙核心處理器。第二個是長高科技開發的DMA-210L開發板，最後一個是devkit8000，這是一個BeagleBoard的複製品。 以上三個平臺，就kernel configs層面來說，需要打開的項目，大約有80%左右的共通性。以下，整理針對執行Android 4.0必要的kernel configs，相信對仍在進行移植工作的朋友，會有一些幫助。 首先，先介紹三個Android 4.0的特性： ● Android 4.0使用Early Suspend ● Android 4.0不支援Virtual Framebuffer ● Android 4.0使用Quota v2 Android 4.0的Surfaceflinger使用到early suspend功能，因此必須將kernel的Early suspend能打開。接著，在Bring-up階段，我們採取穩健做法，先使用Software rendering的方式，讓Android能成功開機，後續再考慮硬體加速的部份。 在Kernel支援Virtual framebuffer的環境下，Software rendering並不能完全正常運作，因此，必須將kernel的Virtual framebuffer功能關閉。另外，Software...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[延續「<a href="http://www.moko365.com/enterprise/ice-cream-sandwich-porting-training" target="_blank">Ice Cream Sandwich (Android 4.0) 移植與框架</a>」課後紀錄，與大家分享一些Android 4.0的移植經驗。移植Android 4.0的第一個階段稱為Bring-up，簡單說，就是要想辦法將Android放到硬體上，並且要能成功開機。

影響是否能Bring-up的關鍵之一，就是kernel的設定。因為驅動程式的關係， 一般認為，使用Linux 3.0系列是比較好的做法。不過，2.6.3x或3.x的版本，都能支援Android 4.0。在這次的課程裡，筆者使用了三個平臺。第一個是MagicLEGO計畫所開發的MagicLEGO開發板，MagicLEGO使用三星的Exynos 4210雙核心處理器。第二個是長高科技開發的DMA-210L開發板，最後一個是devkit8000，這是一個BeagleBoard的複製品。

以上三個平臺，就kernel configs層面來說，需要打開的項目，大約有80%左右的共通性。以下，整理針對執行Android 4.0必要的kernel configs，相信對仍在進行移植工作的朋友，會有一些幫助。

首先，先介紹三個Android 4.0的特性：

● Android 4.0使用Early Suspend

● Android 4.0不支援Virtual Framebuffer

● Android 4.0使用Quota v2

Android 4.0的Surfaceflinger使用到early suspend功能，因此必須將kernel的Early suspend能打開。接著，在Bring-up階段，我們採取穩健做法，先使用Software rendering的方式，讓Android能成功開機，後續再考慮硬體加速的部份。

在Kernel支援Virtual framebuffer的環境下，Software rendering並不能完全正常運作，因此，必須將kernel的Virtual framebuffer功能關閉。另外，Software rendering的方式，將會透過Kernel的framebuffer驅動程式進行繪圖，這部份後續再做說明。

Quota v2是kernel的「netlink」功能，Android的netd會使用到netlink，在設定kernel時，也要將這個功能開啟。以上整理的三個重點，特別是netlink的設定，很頻繁地出現在網路上的論壇，可見這是移植Android 4.0初期經常遇到的問題。

<strong>延伸閱讀</strong>

● <a href="http://www.jollen.org/blog/2011/12/porting-android-4-0-devkit8000.html">移植 Android 4.0 到 Devkit8000 開發板 (OMAP3)，只能開機、沒有硬體加速</a>
● <a href="http://www.jollen.org/blog/2012/01/android-4-0-porting-keys.html">[教育訓練紀錄] Android 4.0 移植與框架課程：會後小記與學習建議</a>]]>
      
   </content>
</entry>
<entry>
   <title>HTML5在手持裝置將開始爆發式成長</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/01/html-5-boost-up-mobile-devices.html" />
   <id>tag:www.jollen.org,2012:/blog//2.767</id>
   
   <published>2012-01-19T12:33:15Z</published>
   <updated>2012-01-19T18:36:39Z</updated>
   
   <summary>文／Jollen Chen（原文刊載於 CTimes零組件雜誌2012年2月號） HTML5標準將開始大舉進入行動裝置市場，這是今年的手機技術重頭戲。撰寫手機App現在有二種選擇了。第一種做法是典型的做法，也就是Native App的開發方式，採用Java或C程式語言撰寫App，在編譯後安裝至手機運行。這種做法的主要缺點是，不跨平臺，也就是，針對Android手機、iPhone機等，都必須各自發展一份程式碼。 第二種做法就是HTML5的做法，採用HTML5標準開發App，有點像是在設計網頁，或是撰寫Web應用程式。可以想像，以後只要把網頁或Web應用程式封裝成App後，就能直接安裝至手機運行。這種做法解決了Native App不能跨平臺的缺點。 我們可以這樣解釋，不管使用什麼作業系統或瀏覽器，都可以瀏覽網頁，所以網頁與Web應用程式本身，都是跨平臺的。同樣地，不管你是使用什麼手機，也不管手機使用的是什麼作業系統，都可以運行同一份HTML5的手機App。 HTML5將要在手持裝置域，呈現大爆發式的成長；因此，有三項關鍵技術，不可不知。 第一、使用HTML5+CSS+JavaScript撰寫Web應用。HTML5是網頁標籤語言的標準，當然，單單使用HTML5並不能開發應用程式，必須搭配CSS與JavaScript來使用。因此，HTML5+CSS+JavaScript就是「HTML5 App」的基礎建設。有些網頁上面有很棒的特效，例如：轉場效果，這些都可以透過JavaScript來完成。 另外，jQuery也是不可或缺的技術。jQuery已經相當的有名，就不必再多說了。直接撰寫JavaScript可能有時很麻煩，這時可以使用jQuery以及眾多的jQuery plugins來完成。 第二、JavaScript引擎的成熟度是關鍵。要在手機上運行HTML5的App，因為將會使用到許多JavaScript程式碼，所以JavaScript的引擎成熟度，以及它的效能是主要關鍵。安裝在手持裝置上的JavaScript 引擎，將成為手持裝置的重要技術。 Android系統早期使用的 JavaScript 引擎稱為 JavaScriptCore (JSC)，JSC 包含在 webkit 中。因為一些原因，Google 也決定開發自已的 JavaScript 引擎，稱之為 V8。技術上，新一代的 V8 引擎效能比 JSC 引擎更好。最新的 Ice Cream Sandwich 已經全面採用 V8 引擎了。V8 引擎的編譯基礎技術稱為 Crankshaft，這項技術可以很有效地改善JavaScript應用程式的效能。 第三、PhoneGap潛力驚人。目前，已經有非常多的App開發者，使用知名的開放源碼專案...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      文／Jollen Chen（原文刊載於 CTimes零組件雜誌2012年2月號）

HTML5標準將開始大舉進入行動裝置市場，這是今年的手機技術重頭戲。撰寫手機App現在有二種選擇了。第一種做法是典型的做法，也就是Native App的開發方式，採用Java或C程式語言撰寫App，在編譯後安裝至手機運行。這種做法的主要缺點是，不跨平臺，也就是，針對Android手機、iPhone機等，都必須各自發展一份程式碼。

第二種做法就是HTML5的做法，採用HTML5標準開發App，有點像是在設計網頁，或是撰寫Web應用程式。可以想像，以後只要把網頁或Web應用程式封裝成App後，就能直接安裝至手機運行。這種做法解決了Native App不能跨平臺的缺點。

我們可以這樣解釋，不管使用什麼作業系統或瀏覽器，都可以瀏覽網頁，所以網頁與Web應用程式本身，都是跨平臺的。同樣地，不管你是使用什麼手機，也不管手機使用的是什麼作業系統，都可以運行同一份HTML5的手機App。

HTML5將要在手持裝置域，呈現大爆發式的成長；因此，有三項關鍵技術，不可不知。

第一、使用HTML5+CSS+JavaScript撰寫Web應用。HTML5是網頁標籤語言的標準，當然，單單使用HTML5並不能開發應用程式，必須搭配CSS與JavaScript來使用。因此，HTML5+CSS+JavaScript就是「HTML5 App」的基礎建設。有些網頁上面有很棒的特效，例如：轉場效果，這些都可以透過JavaScript來完成。

另外，jQuery也是不可或缺的技術。jQuery已經相當的有名，就不必再多說了。直接撰寫JavaScript可能有時很麻煩，這時可以使用jQuery以及眾多的jQuery plugins來完成。

第二、JavaScript引擎的成熟度是關鍵。要在手機上運行HTML5的App，因為將會使用到許多JavaScript程式碼，所以JavaScript的引擎成熟度，以及它的效能是主要關鍵。安裝在手持裝置上的JavaScript 引擎，將成為手持裝置的重要技術。

Android系統早期使用的 JavaScript 引擎稱為 JavaScriptCore (JSC)，JSC 包含在 webkit 中。因為一些原因，Google 也決定開發自已的 JavaScript 引擎，稱之為 V8。技術上，新一代的 V8 引擎效能比 JSC 引擎更好。最新的 Ice Cream Sandwich 已經全面採用 V8 引擎了。V8 引擎的編譯基礎技術稱為 Crankshaft，這項技術可以很有效地改善JavaScript應用程式的效能。

第三、PhoneGap潛力驚人。目前，已經有非常多的App開發者，使用知名的開放源碼專案 PhoneGap，來開發者HTML5的手機App。大家都知道，Adobe已經宣佈放棄行動版的Flash，但是，有一個重要的事情是DreamWaver 5.5。DreamWaver 5.5 的特色之一就是加入 PhoneGap 的支援。

DreamWaver 5.5可以做到令人興奮的一個功能。設計師可以使用DreamWaver 5.5把設計好的「Web」直接封裝成手機Android App，並安裝至手機。不但如此，封裝出來的App還可以上架到Android Market上。

從種種跡象顯示，HTML5+CSS+JavaScript確實已經成為應用軟體開發商的另外一個選擇了。各大作業系統JavaScript引擎的成熟，以及DreamWaver宣佈支援 PhoneGap，還有PhoneGap專案的快速發展，這些現象告訴我們，HTML5標準在手持裝置領域，將開始有爆發式的成長。
      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] Android 4.0 移植與框架課程：會後小記與學習建議</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/01/android-4-0-porting-keys.html" />
   <id>tag:www.jollen.org,2012:/blog//2.766</id>
   
   <published>2012-01-17T06:03:07Z</published>
   <updated>2012-01-17T12:12:46Z</updated>
   
   <summary>上週三 (1/11) 舉辦的「Ice Cream Sandwich (Android 4.0) 移植與框架」課程，參與情況相當踴躍，覺得非常的感動。所以當然也要使出渾身解數，回報大家的支持。這次的課程有一個比較特別的地方，就是在一些移植工作上，筆者特別將 Android 4.0 的移植工作與 Android 2.3 做比較。 由於 Android 4.0 移植，可以基於 Android 2.3 甚致 Android 3.0 來進行，所以並不需要「從零開始」。基於過去的 Android 移植經驗，可以完成大約 80% 左右的 Android 4.0 移植工作。從學習的角度來看，因為 2.3 與 4.0 的移植技術很許多相同的地方，例如：Product tree 的製作完全相同，因此實際了解 2.3 與 4.0...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[上週三 (1/11) 舉辦的「Ice Cream Sandwich (Android 4.0) 移植與框架」課程，參與情況相當踴躍，覺得非常的感動。所以當然也要使出渾身解數，回報大家的支持。這次的課程有一個比較特別的地方，就是在一些移植工作上，筆者特別將 Android 4.0 的移植工作與 Android 2.3 做比較。

由於 Android 4.0 移植，可以基於 Android 2.3 甚致 Android 3.0 來進行，所以並不需要「從零開始」。基於過去的 Android 移植經驗，可以完成大約 80% 左右的 Android 4.0 移植工作。從學習的角度來看，因為 2.3 與 4.0 的移植技術很許多相同的地方，例如：Product tree 的製作完全相同，因此實際了解 2.3 與 4.0 的「差異」是比較有效率的作法。

另外，同樣是從學習的角度來看。如果是 Android 移植的入門新手，一開始不太需要區分版本，由 Android 2.3 移植開始，也是一個很好的入門點，這會讓學習更單純，例如：不需要考慮 InputReader 的修改；這個專門針對 Android 4.0 的移植工作，未來再補上即可。

<strong>Android 4.0 的 20%</strong>

Android 移植工作，可以區分為二個部份：

• Bring-up
• 周邊移植

Bring-up 指的是「想辦法做到可以開機」，這是移植的第一個重要 Milestone。在開機完成後，再接著處理周邊，例如：Wi-Fi、感測器等。

這次的課程，總共有三位講師。筆者主要負責「Bring-up」的部份，也就是整理如何將 Android 4.0 做到可以開機，課程內容的規劃，鎖定在這「20%」的不同。「可開機」的定義是可以看到 Android 的桌面環境。課堂上，筆者提到了幾個「可開機」的關鍵：

• Kernel configs
• Software rendering
• InputReader (Android) 與 Input device driver (kernel)

接下來的課程紀錄，將會針對每一個關鍵做一個整理。雖然面對不同硬體，Android 4.0 移植工作仍會有些小差異，不過只要處理好這三大關鍵，幾乎都可以成功開機。]]>
      
   </content>
</entry>
<entry>
   <title>現今軟體開發的一個重要議題：開源授權與私有授權的混用</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2012/01/software-license-issues-floss-and-proprietary.html" />
   <id>tag:www.jollen.org,2012:/blog//2.765</id>
   
   <published>2012-01-01T01:45:50Z</published>
   <updated>2012-01-01T10:01:48Z</updated>
   
   <summary>文／Jollen Chen（原文刊載於零組件雜誌2012年1月號） 軟體取代硬體成為主流價值 觸控手機與平板電腦的成功，正式宣告軟體與網路時代的來臨，這表示硬體獲利模式時代的結束，以硬體為主的商業模式，成為上一個世代的故事了。軟體是產品開發的主角，這已經是大家所公認的主流價值。 因此，可以看到一個事實，台灣有許多硬體公司，已經將軟體列為重點項目，除了利用軟體提升硬體的價值外，也提供軟體服務的新商業模式。 軟體取代硬體，成為主流價值的時代，有更多非技術面議題需要探討。除了專利問題外，在軟體開發的過程中，還有一個幾乎被遺忘的重要議題，在這裡與大家分享。 一個非技術面議題 現今市場上流通的產品，有很高的比例都是採取開放平臺與開源軟體。我們都知道，軟體太重要了，所以企業開始大量投入軟體研發。但與其說是「軟體研發」，不如說是「軟體工程」；因為，這些軟體有相當高的比例都是開放平臺或開放源碼，意思是，絕大多數，甚致是全部的軟體，都是取之於他人（透過網路），而非自行「研究」與「開發」，所以事實是，我們都是在他人的基礎之上做工（工程）。 也就是說，現今企業「從零開始」開發真正私有程式碼的比例變得相當低。從產品的角度來看，可能有99%的程式碼都是外來，例如，使用Google提供的Android程式碼；又如，網路上數以萬計的開放原始碼計畫 (Open source software)。可能只有1%或更低的比率，是私有的程式碼。 因此，我們將產品上的程式碼分為「公眾財」與「私有財」二大類。開放源碼採用的 GPL 或 Apache 是屬於一種公眾財概念的授權 (License)，無論是取得、散佈、重製或修改等，都要遵守授權規劃。例如：Linux 核心的修改必須遵守 GPL (Version 2) 的授權聲明，確實公開原始程式碼。過去一些企業經常採用「Delay Open」，即產品發佈後，儘量托延公開程式碼的時間，但 [這個做法可能仍有一些疑慮]。 透過一些「軟體架構設計」的方式，可以讓企業在公眾財的程式碼裡，加入「私有財」的程式碼。私有財的程式碼，完全由開發商自行撰寫授權條款，即授權方式是自行決定，而不是採用公眾財授權。例如，Android 的 HAL 架構，便具備這樣的空間。架構設計，有時並不只在解決技術問題，有些也在解決一些關鍵的非技術問題。 從以上的說明可以發現，開源軟體的公眾財授權，以及企業為了保護智慧財產權必須採取的私有財授權，以及二者的混合，必須有一定的架構設計，才不致於面臨法律問題，這是台灣業者過去這一年來，普遍忽視的議題。從現況來看，筆者為大陸企業提供這方面建議與咨詢服務已經有一段時間了，台灣業者在這個議題上，仍需加緊腳步。 Happy New Year 2012 !...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[文／Jollen Chen（原文刊載於零組件雜誌2012年1月號）

<strong>軟體取代硬體成為主流價值</strong>

觸控手機與平板電腦的成功，正式宣告軟體與網路時代的來臨，這表示硬體獲利模式時代的結束，以硬體為主的商業模式，成為上一個世代的故事了。軟體是產品開發的主角，這已經是大家所公認的主流價值。

因此，可以看到一個事實，台灣有許多硬體公司，已經將軟體列為重點項目，除了利用軟體提升硬體的價值外，也提供軟體服務的新商業模式。

軟體取代硬體，成為主流價值的時代，有更多非技術面議題需要探討。除了專利問題外，在軟體開發的過程中，還有一個幾乎被遺忘的重要議題，在這裡與大家分享。
 

<strong>一個非技術面議題</strong>

現今市場上流通的產品，有很高的比例都是採取開放平臺與開源軟體。我們都知道，軟體太重要了，所以企業開始大量投入軟體研發。但與其說是「軟體研發」，不如說是「軟體工程」；因為，這些軟體有相當高的比例都是開放平臺或開放源碼，意思是，絕大多數，甚致是全部的軟體，都是取之於他人（透過網路），而非自行「研究」與「開發」，所以事實是，我們都是在他人的基礎之上做工（工程）。

也就是說，現今企業「從零開始」開發真正私有程式碼的比例變得相當低。從產品的角度來看，可能有99%的程式碼都是外來，例如，使用Google提供的Android程式碼；又如，網路上數以萬計的開放原始碼計畫 (Open source software)。可能只有1%或更低的比率，是私有的程式碼。

因此，我們將產品上的程式碼分為「公眾財」與「私有財」二大類。開放源碼採用的 GPL 或 Apache 是屬於一種公眾財概念的授權 (License)，無論是取得、散佈、重製或修改等，都要遵守授權規劃。例如：Linux 核心的修改必須遵守 GPL (Version 2) 的授權聲明，確實公開原始程式碼。過去一些企業經常採用「Delay Open」，即產品發佈後，儘量托延公開程式碼的時間，但 [<a href="http://laforge.gnumonks.org/weblog/2011/12/24/#20111224-htc-delays-gpl" target="_blank">這個做法可能仍有一些疑慮</a>]。

透過一些「軟體架構設計」的方式，可以讓企業在公眾財的程式碼裡，加入「私有財」的程式碼。私有財的程式碼，完全由開發商自行撰寫授權條款，即授權方式是自行決定，而不是採用公眾財授權。例如，Android 的 HAL 架構，便具備這樣的空間。<u>架構設計，有時並不只在解決技術問題，有些也在解決一些關鍵的非技術問題。</u>

從以上的說明可以發現，開源軟體的公眾財授權，以及企業為了保護智慧財產權必須採取的私有財授權，以及二者的混合，必須有一定的架構設計，才不致於面臨法律問題，這是台灣業者過去這一年來，普遍忽視的議題。從現況來看，筆者為大陸企業提供這方面建議與咨詢服務已經有一段時間了，台灣業者在這個議題上，仍需加緊腳步。

Happy New Year 2012 !]]>
      
   </content>
</entry>
<entry>
   <title>硬體廠的軟體經營策略：建立軟體伙伴關係</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/12/create-partnership-with-software-house.html" />
   <id>tag:www.jollen.org,2012:/blog//2.764</id>
   
   <published>2011-12-31T03:39:29Z</published>
   <updated>2012-01-01T09:40:59Z</updated>
   
   <summary>文／Jollen Chen（原文刊載於零組件雜誌2011年12月號） 現在已經是軟體的時代了，有一個很有趣的現象在發生，部份軟體公司，「想連硬體設計都一起做」；許多硬體公司，積極想在軟體層面有所突破。從技術上的做法來看，軟體整合是硬體廠尋求突破很好的方向，但技術性太高。因此，若以軟硬結合取代軟硬整合，也就是硬體廠結合軟體公司，成為伙伴關係，或許是另一個不錯方向。 軟硬整合的難度有多高？Steve Jobs打從創立蘋果之初，就決心走軟硬整合的路，今天許多偉大的產品，雖然並不光靠「軟硬整合」技術取勝，但單就技術面來看，這肯定是一條「非常漫長的道路」。因此，硬體廠與軟體公司結合，成為策略合作伙伴，將是比較聰明又有效率的選擇。另外一個原因是，軟硬整合做得好，長期來看，應該要往消費性產品公司的願景邁進。 這半年來，為許多企業進行訓練工作時，可以感受到「決心改變」的氣氛；最特別的是，過去一些被認為是純硬體廠的企業，正努力地尋找好的「軟體策略」；因此，在這裡提出一些個人觀察與想法。 第一、軟硬結合。技術研發上，硬體廠透過軟體公司的協助，可以為硬體建立更多價值，並且也能在新商業模式的建立上有所突破。因此，與軟體公司或是軟體團隊，建立伙伴關係，並且學習新的軟體研發管理模式，是重要的功課。建立與軟體公司的伙伴關係，並且成功打造突破性產品的成功例子，當屬三星的手機產品。伙伴關係是一種共生系統架構（Ecosystem），對硬體廠來說才是最有利的做法，因為可以建立軟體伙伴對自已的認同感。 第二、研發管理。過去的軟體研發，特別在台灣，都是屬於門內做法（In-door），意思是招募自有的軟體工程師，並在內部完成研發專案。現在，有許多專案在初始階段（Initial Development Pase）都是採用戶外做法（Out-door）；簡單說，就是我們談論很久的社群模式，透過外部力量來完成工作。 軟體的研發方法不一樣了，關於這點，或許可以從我個人經營的軟體服務業務來說明；目前與客戶進行的部份軟體專案，客戶也接受了新的做法，讓社群上的個人開發者參與專案。因此，若採用戶外模式，專案的成功關鍵因素，在於是否能建立正確的研發管理方法。 第三、軟體是知識。軟體並不是程式碼，而是「知識」。知識包含想法、創意與專業學科等等。過去在本論壇，也和大家分享過「寫程式並不等於做軟體」的觀點。由於軟體是無疆界的「知識」，因此，策略與專案內容的擬定上，「不應該以硬體平臺做為出發點」；這是過去一直不斷發生的問題，許多計畫都是以硬體角度出發，容易因小失大。簡單說，專案的出發點，以及結果，「都只是在為硬體寫程式」，這是過去近二年觀察到的問題。 一直以來，硬體廠把軟體視為附屬品，或是將軟體公司做為外包廠的現象，在這半年來有了相當大幅度的轉變。這是一個以軟體為主的新時代，台灣硬體廠雖然一開始應變速度慢，起步也較晚，但是觀念的轉換速度卻很快，希望大家以期待的心情來看待。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      文／Jollen Chen（原文刊載於零組件雜誌2011年12月號）

現在已經是軟體的時代了，有一個很有趣的現象在發生，部份軟體公司，「想連硬體設計都一起做」；許多硬體公司，積極想在軟體層面有所突破。從技術上的做法來看，軟體整合是硬體廠尋求突破很好的方向，但技術性太高。因此，若以軟硬結合取代軟硬整合，也就是硬體廠結合軟體公司，成為伙伴關係，或許是另一個不錯方向。

軟硬整合的難度有多高？Steve Jobs打從創立蘋果之初，就決心走軟硬整合的路，今天許多偉大的產品，雖然並不光靠「軟硬整合」技術取勝，但單就技術面來看，這肯定是一條「非常漫長的道路」。因此，硬體廠與軟體公司結合，成為策略合作伙伴，將是比較聰明又有效率的選擇。另外一個原因是，軟硬整合做得好，長期來看，應該要往消費性產品公司的願景邁進。

這半年來，為許多企業進行訓練工作時，可以感受到「決心改變」的氣氛；最特別的是，過去一些被認為是純硬體廠的企業，正努力地尋找好的「軟體策略」；因此，在這裡提出一些個人觀察與想法。

第一、軟硬結合。技術研發上，硬體廠透過軟體公司的協助，可以為硬體建立更多價值，並且也能在新商業模式的建立上有所突破。因此，與軟體公司或是軟體團隊，建立伙伴關係，並且學習新的軟體研發管理模式，是重要的功課。建立與軟體公司的伙伴關係，並且成功打造突破性產品的成功例子，當屬三星的手機產品。伙伴關係是一種共生系統架構（Ecosystem），對硬體廠來說才是最有利的做法，因為可以建立軟體伙伴對自已的認同感。

第二、研發管理。過去的軟體研發，特別在台灣，都是屬於門內做法（In-door），意思是招募自有的軟體工程師，並在內部完成研發專案。現在，有許多專案在初始階段（Initial Development Pase）都是採用戶外做法（Out-door）；簡單說，就是我們談論很久的社群模式，透過外部力量來完成工作。 軟體的研發方法不一樣了，關於這點，或許可以從我個人經營的軟體服務業務來說明；目前與客戶進行的部份軟體專案，客戶也接受了新的做法，讓社群上的個人開發者參與專案。因此，若採用戶外模式，專案的成功關鍵因素，在於是否能建立正確的研發管理方法。

第三、軟體是知識。軟體並不是程式碼，而是「知識」。知識包含想法、創意與專業學科等等。過去在本論壇，也和大家分享過「寫程式並不等於做軟體」的觀點。由於軟體是無疆界的「知識」，因此，策略與專案內容的擬定上，「不應該以硬體平臺做為出發點」；這是過去一直不斷發生的問題，許多計畫都是以硬體角度出發，容易因小失大。簡單說，專案的出發點，以及結果，「都只是在為硬體寫程式」，這是過去近二年觀察到的問題。


一直以來，硬體廠把軟體視為附屬品，或是將軟體公司做為外包廠的現象，在這半年來有了相當大幅度的轉變。這是一個以軟體為主的新時代，台灣硬體廠雖然一開始應變速度慢，起步也較晚，但是觀念的轉換速度卻很快，希望大家以期待的心情來看待。
      
   </content>
</entry>
<entry>
   <title>Android 瀏覽器與 Webkit 專案心得：AOSP 心酸說不完</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/12/android-aosp-browser-webkit-struggling.html" />
   <id>tag:www.jollen.org,2011:/blog//2.763</id>
   
   <published>2011-12-23T07:44:38Z</published>
   <updated>2011-12-23T21:03:21Z</updated>
   
   <summary>2011歲末時刻，要好好為自已上一堂「Lessons Learned」課程。 今年度有幾個 Android 專案，特別令人印象深刻，其中一個是有關於 Android 瀏覽器與 webkit 的計畫。因為開發專案的需要，修改了 Android 瀏覽器 (Browser) 的程式碼，也對 Webkit 做了些研究，沒想到這整個過程，倒是有點出乎我的意料之外；原本以為這是一個簡單，且能輕易結案的計畫，沒想到踩到 AOSP 的地雷。在這個瀏覽器開發專案接近尾聲時，在這裡分享一點甘苦談。 Google 採用 Webkit 做為 Android 內建瀏覽器的 HTML 引擎，Webkit 是相當知名的 HTML 引擎，由 Apple 公司做了早期的開發，現在則是成為了一個開源計畫，由社群開發者，以及部份公司，共同貢獻程式碼。 這個開發專案需要基於現有的 Android 2.2/2.3 瀏覽器，加入一些功能，並能整合伺服器端的服務，其中一個功能，需要使用到瀏覽器的 Copy/Selection 功能。就如同大家所知道的，Android 2.2 的 WebView 並沒有...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      2011歲末時刻，要好好為自已上一堂「Lessons Learned」課程。

今年度有幾個 Android 專案，特別令人印象深刻，其中一個是有關於 Android 瀏覽器與 webkit 的計畫。因為開發專案的需要，修改了 Android 瀏覽器 (Browser) 的程式碼，也對 Webkit 做了些研究，沒想到這整個過程，倒是有點出乎我的意料之外；原本以為這是一個簡單，且能輕易結案的計畫，沒想到踩到 AOSP 的地雷。在這個瀏覽器開發專案接近尾聲時，在這裡分享一點甘苦談。

Google 採用 Webkit 做為 Android 內建瀏覽器的 HTML 引擎，Webkit 是相當知名的 HTML 引擎，由 Apple 公司做了早期的開發，現在則是成為了一個開源計畫，由社群開發者，以及部份公司，共同貢獻程式碼。

這個開發專案需要基於現有的 Android 2.2/2.3 瀏覽器，加入一些功能，並能整合伺服器端的服務，其中一個功能，需要使用到瀏覽器的 Copy/Selection 功能。就如同大家所知道的，Android 2.2 的 WebView 並沒有 Selection API，Android 2.3 在 WebView 加入了 Selection API，「但是卻沒有完整且良好的實作」。

原本天真的以為，「把沒有實作完成的 API 做完」，就可以交卷了，沒想到後續發展，根本沒有辦法寫劇本，到後期則是在兵恾馬亂的情況下，「補洞」加「救火隊」的方式搞定專案。這一切都要從 Android 的設計與實作講起。

部份的 API 設計過於鬆散，有些程式碼的實作也還是 prototype 階段；這就是開發 AOSP 的惡夢，工程師要面對鬆散的設計，以及不完整的實作，到最後只能拋開一切理想化的做法，開始進行捕洞與救火工程，然後希望下一個洞不要出現，眼不見為淨，希望專案早早收尾。

由於廠商需要同時推出 Android 2.2 與 2.3 的平板電腦，所以需要同時開發 2.2 與 2.3 的瀏覽器。但是，二個版本的瀏覽器程式碼有一些差距，為了簡化開發工作，並且讓程式碼更一致性，首先我做了一個工作，就是將 Android 2.3 的瀏覽器 Backport 至 Android 2.2。

這期間遇到一些小問題，例如：Android 2.2 並沒有 EdgeGlow 的功能。為了讓 Android 2.3 的瀏覽器可以在 2.2 上正常執行，也修改了 WebView 以及一小部份的 native webkit。Android 2.3 雖然支援了 selection API，但是並沒有實作「彈出視窗」的功能，在這個部份花了一點時間實作，因為希望儘量不去破壞 WebView 的 behavior，所以對 WebView 做了一次完整的研究。專案開始的初期，花費許多時間在了解 WebView 的設計。

      
   </content>
</entry>
<entry>
   <title>移植 Android 4.0 到 Devkit8000 開發板 (OMAP3)，只能開機、沒有硬體加速</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/12/porting-android-4-0-devkit8000.html" />
   <id>tag:www.jollen.org,2011:/blog//2.761</id>
   
   <published>2011-12-05T08:18:52Z</published>
   <updated>2011-12-07T20:21:31Z</updated>
   
   <summary>Google 將 Android 4.0 釋出後，製造了一波移植運動。Linaor 或是 xda-developer 上，都已經發佈 Ice Cream Sandwich 的移植成果。一些大家手邊常見的開發板，像是 PandaBoard 等，也都能運行最新的 Android 4.0 系統了。 在 Android 4.0 AOSP 上線後，手邊也開始了一個移植專案；經過一個多禮拜的努力，就在大有斬獲時，開發板就被 Porting 到壞掉了。不過，Ice Cream Sandwich 移植是一個令人熱血沸驣的工作，怎麼能這樣就休息呢。於是把在上課使用的 devkit8000 開發板拿出來「試試看」，這是我手邊現有的唯一開發板。 雖然 devkit8000 的硬體配置不算頂級（Cortex A8 600MHz 處理器、256M 記憶體），但因為 Linaro 發佈的 Release 11.11...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Google 將 Android 4.0 釋出後，製造了一波移植運動。Linaor 或是 xda-developer 上，都已經發佈 Ice Cream Sandwich 的移植成果。一些大家手邊常見的開發板，像是 PandaBoard 等，也都能運行最新的 Android 4.0 系統了。

在 Android 4.0 AOSP 上線後，手邊也開始了一個移植專案；經過一個多禮拜的努力，就在大有斬獲時，開發板就被 Porting 到壞掉了。不過，Ice Cream Sandwich 移植是一個令人熱血沸驣的工作，怎麼能這樣就休息呢。於是把在上課使用的 devkit8000 開發板拿出來「試試看」，這是我手邊現有的唯一開發板。

雖然 devkit8000 的硬體配置不算頂級（Cortex A8 600MHz 處理器、256M 記憶體），但因為 Linaro 發佈的 Release 11.11 與 11.12 都把 ICS 移植到  PandaBoard 與 BeagleBoard 了，所以我想 devkit8000 「應該」也不成問題。

上週在進行「Android Porting」的教育訓練時，也跟同學提到，「要把 Android 移植到可以開機」，並不是很難的工作，所以，這個任務的目標，就定為「只到可以開機就好」。於是，利用了週末以及今天下午的時間，進行了這項任務。

為了實驗：從 AOSP（Android Open Source Project）到能開機，並不是難事，所以我就從 AOSP 上取得原生的 Android 程式碼，開始了移植作業。Android 4.0 Porting 很有趣，而且也有一點挑戰性。

由於 Android 4.0 使用到 Wakelock 的 Early-suspend 功能，所以必須重新編譯 kernel，把 Power sysfs 打開。原本打算取用 Linaor 的 kernel，不過後來還是決定使用 rowboat 的版本，再加上 devkit8000 的 4.3 吋 LCD Panel 需要打一些補丁，最後是下載了 0xdroid 的 kernel tree，除了有包含 rowboat 的分支外，也維護了 devkit8000 的相關 patch。

工程師初老症第一條：能找到別人維護好、現成可用的 source tree，就不會有自已維護、打補丁的念頭。

不過最後還是對 kernel 做了一點小修改，包含 Touch Screen 的邊緣沒反應等小問題。這個版本目前維護在 moko365 的 github 上。

移植 Android 時，也修改了一些小細節。不過，大致上「編譯後放到板子上」就可以開機了。由於 dexopt 的 verify-and-optimize 所製造出來的 cache 資料量比較大，以及為了方便測試，所以我就把 kernel、ramdisk 與整個 system 都放到 SD Card 上開機。

最後做出一個只能開機的 Android 4.0 + Devkit8000。Graphics 的部份，使用的是 libEGL_android.so，也就是 Software OpenGL，並沒有硬體加速的功能。最後就是影片中看到的：Launcher2 起來後就掛了。所以，要到真正能用，還要再加點工。

<iframe width="560" height="315" src="http://www.youtube.com/embed/lfT2anmjJ5Y" frameborder="0" allowfullscreen></iframe>

在 Po 壞的板子維修完成前，Devkit8000 大概還要再陪我過幾天乾癮。

<strong>12.07 更新：Launcher 順利啟動</strong>

<iframe width="560" height="315" src="http://www.youtube.com/embed/ptGl_p7b6bg" frameborder="0" allowfullscreen></iframe>]]>
      
   </content>
</entry>
<entry>
   <title>Android 4.0 源碼即將登場：產業將再起什麼變化？</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/12/android-4-0-ice-cream-sandwich.html" />
   <id>tag:www.jollen.org,2011:/blog//2.760</id>
   
   <published>2011-12-05T08:05:19Z</published>
   <updated>2011-12-05T14:11:12Z</updated>
   
   <summary>文／Jollen Chen（原文刊載於 CTimes 零組件雜誌，2011年11月號） 經過10個月的等待，最新的Android源碼，千呼萬喚始出來。Android開始源碼專案，稱之為Android Open Source Project（即AOSP)，目前的最新版本是2.3，下一個AOSP將會是4.0。Google跳過Android 3.0的原因，據信是因為「Android 3.0程式碼不適合開源」，從技術面的角度來看，可能是碼源的組織結構尚未建全，以及架構設計並未經過全面驗證。 從目前已公開的Android 4.0 SDK來看，確實是一個「跨裝置」的作業系統。代號為Ice Cream Sandwich的Android 4.0強調「手機與平板」通用，在新特色列表裡，我們也能發現，應用程式面的特色增加不少。事實上，這次Android 4.0的發佈，Google並沒有說明框架或底層技術細節的變動，而是強調應用軟體面的新功能。 Android 4.0可以說是Android發展史的「第三個重要時代」。熱呼呼的Android 4.0源碼即將到手，廠商應該如何調整接下來的研發策略？在此提供一些想法，請不吝指教。 第一、產品公司的利基已經顯現。第三個Android發展時期，即Android 4.0的時代，訴求已經很明顯，那就是「應用軟體」。重視應用軟體，並不等於組織一個應用軟體研發團隊。實際上，Android Market近20萬個軟體，都是最好的「創意庫」。因此，Android 4.0對於產品公司特別有利基點，因為有了自有產品，才有機會專注在應用軟體與網路服務的整合，發展創新特色。 第二、系統廠應消除研發累贅。所謂的研發累贅，廣義上來說，可以是符合以下二個條件的工作：1. 重覆性工作、2. 研發成本過高的活動。重覆性工作視廠商性質不同而定，例如：感測器研發系統廠，「Android 移植」就是一個重覆性工作，因為接下來，廠商將能直接由「社群」或是「處理器原廠」取得完整度很高的參考設計，只需將重心放在感測器本身的整合，以及應用層面的創新等工作即可。研發成本過高的活動，說明在第三點。 第三、研發成本很低或無限大。研發成本過高的活動，內容千羅萬象，在這裡舉一個例子：「技術研究」。技術研究的目的在於「精確掌握接下來的軟體與技術趨勢」，例如：多核心（Multi-core）接下來的主流會是「異質性」或「同質性」模型。這樣的能力通常只有專家型公司辦得到，例如：知名的技術服務公司Infosys就是一個例子。Infosys曾經提過，「當企業無法跟上技術變化，創新過程將變得緩慢」，因為一但走錯研發方向，修正錯誤的代價將極為昂貴。因此，技術研究是自組團隊，或尋求專家公司的協助，需要經營者的智慧。 以上三個想法，主要是推測Android 4.0降臨後，產業現況可能會發生的化學效應，並取其重，當然還會有更多的變化，不只於這三個想法。面臨變化，新策略的制定，過去的經驗是否有幫助，這可能需要省思。企業經理人，可以從彼得杜拉克「巨變時代的管理」一書中找到一些想法，包含「徹底改造」也是巨變時代的一個藥方。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      文／Jollen Chen（原文刊載於 CTimes 零組件雜誌，2011年11月號）

經過10個月的等待，最新的Android源碼，千呼萬喚始出來。Android開始源碼專案，稱之為Android Open Source Project（即AOSP)，目前的最新版本是2.3，下一個AOSP將會是4.0。Google跳過Android 3.0的原因，據信是因為「Android 3.0程式碼不適合開源」，從技術面的角度來看，可能是碼源的組織結構尚未建全，以及架構設計並未經過全面驗證。

從目前已公開的Android 4.0 SDK來看，確實是一個「跨裝置」的作業系統。代號為Ice Cream Sandwich的Android 4.0強調「手機與平板」通用，在新特色列表裡，我們也能發現，應用程式面的特色增加不少。事實上，這次Android 4.0的發佈，Google並沒有說明框架或底層技術細節的變動，而是強調應用軟體面的新功能。

Android 4.0可以說是Android發展史的「第三個重要時代」。熱呼呼的Android 4.0源碼即將到手，廠商應該如何調整接下來的研發策略？在此提供一些想法，請不吝指教。

第一、產品公司的利基已經顯現。第三個Android發展時期，即Android 4.0的時代，訴求已經很明顯，那就是「應用軟體」。重視應用軟體，並不等於組織一個應用軟體研發團隊。實際上，Android Market近20萬個軟體，都是最好的「創意庫」。因此，Android 4.0對於產品公司特別有利基點，因為有了自有產品，才有機會專注在應用軟體與網路服務的整合，發展創新特色。

第二、系統廠應消除研發累贅。所謂的研發累贅，廣義上來說，可以是符合以下二個條件的工作：1. 重覆性工作、2. 研發成本過高的活動。重覆性工作視廠商性質不同而定，例如：感測器研發系統廠，「Android 移植」就是一個重覆性工作，因為接下來，廠商將能直接由「社群」或是「處理器原廠」取得完整度很高的參考設計，只需將重心放在感測器本身的整合，以及應用層面的創新等工作即可。研發成本過高的活動，說明在第三點。

第三、研發成本很低或無限大。研發成本過高的活動，內容千羅萬象，在這裡舉一個例子：「技術研究」。技術研究的目的在於「精確掌握接下來的軟體與技術趨勢」，例如：多核心（Multi-core）接下來的主流會是「異質性」或「同質性」模型。這樣的能力通常只有專家型公司辦得到，例如：知名的技術服務公司Infosys就是一個例子。Infosys曾經提過，「當企業無法跟上技術變化，創新過程將變得緩慢」，因為一但走錯研發方向，修正錯誤的代價將極為昂貴。因此，技術研究是自組團隊，或尋求專家公司的協助，需要經營者的智慧。

以上三個想法，主要是推測Android 4.0降臨後，產業現況可能會發生的化學效應，並取其重，當然還會有更多的變化，不只於這三個想法。面臨變化，新策略的制定，過去的經驗是否有幫助，這可能需要省思。企業經理人，可以從彼得杜拉克「巨變時代的管理」一書中找到一些想法，包含「徹底改造」也是巨變時代的一個藥方。

      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] Android HAL &amp; Framework 課程範例移植至 Android 4.0</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/11/android-hal-framework-porting-android-4-0.html" />
   <id>tag:www.jollen.org,2011:/blog//2.759</id>
   
   <published>2011-11-18T07:18:02Z</published>
   <updated>2011-11-18T13:39:31Z</updated>
   
   <summary>本課程範例目前已順利移植至 Android 4.0.1 版本。「Android HAL &amp; Framework: 軟硬整合實作訓練」課程，從2009年開辦至今，已經將有二年半的時間了，在這二年多的時間裡，歷經了 Android 1.6/2.1/2.2/2.3 共四個版本，今天也正式踏入了 Android 4.0 版本。 還記得「Android HAL &amp; Framework: 軟硬整合實作訓練」第一次開課是在2009年7月份，在北京紫竹橋附近的訓練教室，大約有50位同學參加。當時，大家是在「不太了解」什麼是 HAL 與 Framework 的情況下來上課，所以似乎是 Android 的超高人氣幫了最大的忙。 這次將課程範例移植至 Android 4.0，其實是一個「無痛」的過程，程式碼實作本身並沒有什麼修改，只須對 Android.mk 做微幅調整，再重新編譯即可。學員若有意將課堂範例移植到 Android 4.0，可參考仕橙3G教室發佈的修改方法，再重新編譯即可。 課程範例的主要訴求是「依循標準架構」來設計，設計如果能符合標準架構，並依循物件導向的觀念，便能得到相當容易維護並移植的程式碼實作。當然這就是這門課程的主軸，「了解 HAL 與 Framework 的架構、設計與原理」。Android 的開發有許多觀念必須事先建立，例如：範例儘可能不去更動 Android 框架的原始碼。由於沒有對...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本課程範例目前已順利移植至 Android 4.0.1 版本。「<a href="http://www.moko365.com/training/android-hal-framework-practice" target="_blank">Android HAL & Framework: 軟硬整合實作訓練</a>」課程，從2009年開辦至今，已經將有二年半的時間了，在這二年多的時間裡，歷經了 Android 1.6/2.1/2.2/2.3 共四個版本，今天也正式踏入了 Android 4.0 版本。

還記得「<a href="http://www.moko365.com/training/android-hal-framework-practice" target="_blank">Android HAL & Framework: 軟硬整合實作訓練</a>」第一次開課是在2009年7月份，在北京紫竹橋附近的訓練教室，大約有50位同學參加。當時，大家是在「不太了解」什麼是 HAL 與 Framework 的情況下來上課，所以似乎是 Android 的超高人氣幫了最大的忙。

這次將課程範例移植至 Android 4.0，其實是一個「無痛」的過程，程式碼實作本身並沒有什麼修改，只須對 Android.mk 做微幅調整，再重新編譯即可。學員若有意將課堂範例移植到 Android 4.0，可參考仕橙3G教室發佈的修改方法，再重新編譯即可。

課程範例的主要訴求是「依循標準架構」來設計，設計如果能符合標準架構，並依循物件導向的觀念，便能得到相當容易維護並移植的程式碼實作。當然這就是這門課程的主軸，「了解 HAL 與 Framework 的架構、設計與原理」。Android 的開發有許多觀念必須事先建立，例如：範例儘可能不去更動 Android 框架的原始碼。由於沒有對 Android 框架程式碼做修改，因此將新功能移植至新版本時，可以節省相當多的時間。]]>
      
   </content>
</entry>
<entry>
   <title>[多核心課程紀錄] 多核心軟體開發的關鍵：Thread Object Model</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/11/multi-core-software-thread-object-model.html" />
   <id>tag:www.jollen.org,2011:/blog//2.758</id>
   
   <published>2011-11-11T08:11:48Z</published>
   <updated>2011-11-11T14:13:05Z</updated>
   
   <summary>關於Java virtual machine的Thread object model，理論上的做法是「一個Thread object連繫(Binding)到一個native thread」。從multi-core的角度來看，這是一個很理想的做法，實務上是否有採用這種Thread object model的Java virtual machine呢？答案是，有的；這取決於virtual machine與作業系統的設計。 JDK6搭配Ubuntu 8.04的環境，以及Android 2.3搭配MagicLego的kernel來看，都是上述的thread model。當然，這裡只是以我自已目前使用中的開發環境當例子，不僅只於這二個環境。 為什麼一個Thread object連繫一個Native thread是比較好的做法，適合應用在multi-core的場合，這涉及到多核心的kernel scheduling技術，在後續的文章裡再做討論。基本上，只要您的系統是屬於上述的Thread object model，未來都能提供一個良好的多核心軟體開發環境。 應用程式到框架，框架透過JNI來到C/C++底層，Thread object與Native thread是一對一關係時，作業系統再將指定的Native thread指派到另外一個處理器，接下來就可以得到這樣的效果：Thread object被指派到另外一個處理器了。這就是為什麼應用程式的設計，以及底層的軟體系統，決定了系統是否能實現「多核心運算」的原因。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      關於Java virtual machine的Thread object model，理論上的做法是「一個Thread object連繫(Binding)到一個native thread」。從multi-core的角度來看，這是一個很理想的做法，實務上是否有採用這種Thread object model的Java virtual machine呢？答案是，有的；這取決於virtual machine與作業系統的設計。

JDK6搭配Ubuntu 8.04的環境，以及Android 2.3搭配MagicLego的kernel來看，都是上述的thread model。當然，這裡只是以我自已目前使用中的開發環境當例子，不僅只於這二個環境。

為什麼一個Thread object連繫一個Native thread是比較好的做法，適合應用在multi-core的場合，這涉及到多核心的kernel scheduling技術，在後續的文章裡再做討論。基本上，只要您的系統是屬於上述的Thread object model，未來都能提供一個良好的多核心軟體開發環境。

應用程式到框架，框架透過JNI來到C/C++底層，Thread object與Native thread是一對一關係時，作業系統再將指定的Native thread指派到另外一個處理器，接下來就可以得到這樣的效果：Thread object被指派到另外一個處理器了。這就是為什麼應用程式的設計，以及底層的軟體系統，決定了系統是否能實現「多核心運算」的原因。
      
   </content>
</entry>
<entry>
   <title>佔領硬體街：軟體人，今天是你們要團結的日子，你們沒有什麼包袱</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/11/calling-all-hackers-occupy-hardware-street.html" />
   <id>tag:www.jollen.org,2011:/blog//2.757</id>
   
   <published>2011-11-10T02:15:41Z</published>
   <updated>2011-11-10T09:34:37Z</updated>
   
   <summary>「佔領硬體街」，原文出處：Calling all hackers: Occupy Hardware Street。很有趣，因為寫得很有戰帖的味道，但其實是很發人省思的一篇文章。 它的開場白： This ought to be the era of the software developer. 「這應該是軟體人的時代」 在佔領華爾街後，為什麼要招集軟體高手佔領硬體街？從下一句話，就可以知道，軟體的價值，以及軟體時代真的到來了。原文的 Hacker 是「軟體高手」的意思： Every week sees a new event courting the lowly hacker. Here are a few recent examples from my day...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[「佔領硬體街」，原文出處：<a href="http://www.eetimes.com/electronics-news/4230394/Calling-all-hackers--Occupy-Hardware-Street" target="_blank">Calling all hackers: Occupy Hardware Street</a>。很有趣，因為寫得很有戰帖的味道，但其實是很發人省思的一篇文章。

它的開場白：

<blockquote>This ought to be the era of the software developer.</blockquote>

<blockquote>「這應該是軟體人的時代」</blockquote>

在佔領華爾街後，為什麼要招集軟體高手佔領硬體街？從下一句話，就可以知道，軟體的價值，以及軟體時代真的到來了。原文的 Hacker 是「軟體高手」的意思：

<blockquote>Every week sees a new event courting the lowly hacker. Here are a few recent examples from my day timer: The Android Dev Con, ARM Tech Con, Blackberry Dev Con, Ubuntu Dev Con…and the list goes on.</blockquote>

<blockquote>「每週，都有很多活動，想要拉攏軟體高手，像是 Android Dev Con、ARM Tech Con、Blackberry Dev Con、UBuntu Dev Con。」</blockquote>

所以，不意外的，或許接下來會有 Baba Dev Con、Tizen Dev Conf 吧。拉攏開發者的活動，或是換個角度，「與開發者合作」的能力，是很重要的競爭力。這應該列入現代公司經營管理的一環，公司要建立與開發者的合作能力，而不是去雇用為員工，這個新改變很巨大，因為企業要學習如何與「Hackers」合作。

例如，軟體高手，他（她）可能想要發展自已的 App，並且在 Android Market 上銷售自已的軟體，甚至這些軟體高手，已經有多個熱銷的 App 了。「收編旗下」實在是個不好的主意，要招募他們為員工的可能機會不高，但可以和他們結為伙伴關係。這就是為什麼有些廠商，認為「好的軟體人才難尋」的原因之一。雖然旁邊的釘子很多，但這塊磁鐵吸不到半支。

看到這點，讓我想到，政府部門這陣子很用心在執行「App 軟體人才」的計畫，值得肯定；但方向可能有錯，或許是對「App 軟體人才」的認知不夠。正確的做法，應該是去協助並扶植 App 人才或團隊，形成一個新的產業，就像當初政府發展「竹科」一樣。從政府的角度，只做就業媒合，格局太小，需要全套的政策。

原文提到「Software Bay」的看法，很值得政府來做。在十月份的零組件雜誌專題報導中，我認為「台灣沒有軟體人才的問題」，但「管理軟體人才的方式出問題」是近二年教育訓練的心得。實際上，台灣軟體高手不少，很多軟體高手在國際上都有「好利害」的表現。像是最近在 AppStore 排行榜前十名的熱門軟體，有一個就是台灣的軟體團隊作品。

過去二年，為許多企業做 Android & Linux 教育訓練，觀察「軟體人才」問題也有很長一段時間了。我的心得是「其實軟體人才就在裡面」，這段期間，也遇到不少利害的軟體高手，我這個「老師」和他們的領域相比，相形見絀。例如，過去幾年，代工廠內部產出一批可以客製化 Linux kernel 的工程師，但就像原文提及：

<blockquote>Even Taiwan's notebook makers are hungry for all the low level software architects they can find—especially those who can help them customize Android kernels for their future smartphones and tablets.</blockquote>

代工廠，你們有 Developer 等級的 Linux 高手，為什麼還缺人才，確實值得思考。所以，台灣有軟體高手，產出人才不是重點，怎麼去凝聚這些人，才是重點，怎麼做？這個部份，其實像是創新工場，或是台灣的 Mr. Jamie 都有很不錯的做法。或許學習 Mr. Jamie 的模式，才是政府該做的事情。

原文最後，是我覺得最好玩的一句話：

<blockquote>So, software developers, today is your day to unite. You have nothing to lose but your shackles.</blockquote>

<blockquote>「所以，軟體人，今天是你們要團結的日子，你們沒有什麼包袱，只要解開你的桎梏」</blockquote>

這個「shackle」是什麼？作者的意思應該是「不要怕、要勇敢」，意思是軟體人要站出來做點自已的事情了。因為「Software is becoming the key differentiator in electronics everywhere you turn.」，你的產業或許不把軟體當一回事，就這是不要怕，要拿開 shackles 的意思。如果您是在科技業的軟體人，也參與過一些硬體研發專案，這不需要再多講了，我想我們都有默契。]]>
      
   </content>
</entry>
<entry>
   <title>[多核心課程紀錄] 多核心軟體開發的關鍵：Pthread</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/11/multi-core-software-multi-threading.html" />
   <id>tag:www.jollen.org,2011:/blog//2.756</id>
   
   <published>2011-11-08T11:09:04Z</published>
   <updated>2011-11-08T17:09:53Z</updated>
   
   <summary>任務切割的目的，在於將應用程式裡的計算工作，切割後指派至另一個處理器核心；讓應用程式，能真正使用多核心的計算能力。這就是為什麼多核心軟體的設計，決定了多核心系統效能。上述的觀念，就是「平行處理」。 從應用程式的層面，就要考慮多核心的設計。如何將一個計算工作切割出來，並指派至另一個處理器核心？方式就是使用multi-thread。以Linux作業系統為例，multi-thread程式設計使用一個稱為pthread的程式庫；因此，學習pthread程式設計，就是打好多核心軟體開發的第一個功課。 Android作業系統同樣是使用pthread程式庫，雖然Android的pthread程式庫，與Linux的pthread程式庫「是二個2不同的實作版本」，但同樣是依循POSIX的標準（pthread是POSIX thread的縮寫），因此，有志進入多核心軟體開發的工程師，可以先在Linux系統底下，學習Linux pthread程式設計。 此外，Android應用程式與框架層，採用Java程式語言撰寫，並且採用物件導向的基礎理論。目前所談論的pthread程式設計，則是用C或C++撰寫，我們將透過pthread所產生的thread稱之為native thread。應用程式使用Java語言撰寫，所產生的thread稱為Java thread。Java thread本質上是一個物件，因此也稱為Thread object。 應用程式與框架層的Thread object與更底層的Native thread關係為何？答案是決取於Java Virtual Machine的設計；JVM的Thread model設計，將會影響Java thread的行為，在多核心系統上，Thread model也會影響Java thread的效能。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Multi-core Software" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      任務切割的目的，在於將應用程式裡的計算工作，切割後指派至另一個處理器核心；讓應用程式，能真正使用多核心的計算能力。這就是為什麼多核心軟體的設計，決定了多核心系統效能。上述的觀念，就是「平行處理」。

從應用程式的層面，就要考慮多核心的設計。如何將一個計算工作切割出來，並指派至另一個處理器核心？方式就是使用multi-thread。以Linux作業系統為例，multi-thread程式設計使用一個稱為pthread的程式庫；因此，學習pthread程式設計，就是打好多核心軟體開發的第一個功課。

Android作業系統同樣是使用pthread程式庫，雖然Android的pthread程式庫，與Linux的pthread程式庫「是二個2不同的實作版本」，但同樣是依循POSIX的標準（pthread是POSIX thread的縮寫），因此，有志進入多核心軟體開發的工程師，可以先在Linux系統底下，學習Linux pthread程式設計。

此外，Android應用程式與框架層，採用Java程式語言撰寫，並且採用物件導向的基礎理論。目前所談論的pthread程式設計，則是用C或C++撰寫，我們將透過pthread所產生的thread稱之為native thread。應用程式使用Java語言撰寫，所產生的thread稱為Java thread。Java thread本質上是一個物件，因此也稱為Thread object。

應用程式與框架層的Thread object與更底層的Native thread關係為何？答案是決取於Java Virtual Machine的設計；JVM的Thread model設計，將會影響Java thread的行為，在多核心系統上，Thread model也會影響Java thread的效能。
      
   </content>
</entry>
<entry>
   <title>[多核心課程紀錄] 多核心軟體開發的關鍵：任務切割</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/11/multi-core-software-task-conquer.html" />
   <id>tag:www.jollen.org,2011:/blog//2.755</id>
   
   <published>2011-11-07T10:15:17Z</published>
   <updated>2011-11-07T16:24:05Z</updated>
   
   <summary>距離上次為自已的部落格裡新增文章分類，已經有一年的時間了，這次加入了一個 Multi-core Software 的分類，也代表自已接下來的技術研究重心，將會在多核心軟體開發上投入時間。 就在上週四(11/3)，Moko365與MagicLego團隊共同舉辦了一場「Multi-Core 嵌入式開發」研討課程。這次的課程，可以說是多核心軟硬體開發的「電腦概論」課程，不但是多核心開發的第一門課，更是了解「沒有軟體、沒有多核心效能」的基礎課程。針對自已的講題部份，在此做一些簡單的紀錄。 沒有良好的軟體設計，無法發揮多核心處理器的效能。既然如此，多核心軟體的涉及範圍為何？只需要作業系統支援多核心即可嗎？ 答案是，多核心處理器需要軟體全面的支援，範圍從應用程式開始，一直往底層，直到作業系統，甚致驅動程式，都有很大的關聯。軟體如何支援多核心處理器，最大的關鍵在於「任務切割與指派」。研討課程當天，另一位講師Frank也利用一個影像處理的例子，說明影像處理如何分割任務，並將不同的任務，分派給不同的處理器。 另一個多核心軟體的關鍵為資料合併(Combine)，Frank同樣也以影像處理做為例子，說明每個處理器在完成計算後，將分別得到的結果(Data)合併成最終計算結果。這個部份，梁老師也利用了一個矩陣運算的例子做了很清楚的說明。 由以上的說明可以了解，資料合併的關鍵，最終在於「如何取用另一個處理器核心的結果(Data)」。在ARM Cortex A8/A9架構裡，這個問題，是透過共用記憶體方式解決。也就是Cortex A8/A9多核心架構，處理器核心間是共用記憶體。共用的記憶體包含二種，第一種是成本較高，但速度較快的 L2 Cache；另一個共用記憶體則是DRAM，它的成本較低、容量較大，但速度較慢。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Multi-core Software" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[距離上次為自已的部落格裡新增文章分類，已經有一年的時間了，這次加入了一個 Multi-core Software 的分類，也代表自已接下來的技術研究重心，將會在多核心軟體開發上投入時間。

就在上週四(11/3)，Moko365與MagicLego團隊共同舉辦了一場「<a href="http://www.moko365.com/enterprise/multi-core-training-basics" target="_blank">Multi-Core 嵌入式開發</a>」研討課程。這次的課程，可以說是多核心軟硬體開發的「電腦概論」課程，不但是多核心開發的第一門課，更是了解「沒有軟體、沒有多核心效能」的基礎課程。針對自已的講題部份，在此做一些簡單的紀錄。

沒有良好的軟體設計，無法發揮多核心處理器的效能。既然如此，多核心軟體的涉及範圍為何？只需要作業系統支援多核心即可嗎？

答案是，多核心處理器需要軟體全面的支援，範圍從應用程式開始，一直往底層，直到作業系統，甚致驅動程式，都有很大的關聯。軟體如何支援多核心處理器，最大的關鍵在於「任務切割與指派」。研討課程當天，另一位講師Frank也利用一個影像處理的例子，說明影像處理如何分割任務，並將不同的任務，分派給不同的處理器。

另一個多核心軟體的關鍵為資料合併(Combine)，Frank同樣也以影像處理做為例子，說明每個處理器在完成計算後，將分別得到的結果(Data)合併成最終計算結果。這個部份，梁老師也利用了一個矩陣運算的例子做了很清楚的說明。

由以上的說明可以了解，資料合併的關鍵，最終在於「如何取用另一個處理器核心的結果(Data)」。在ARM Cortex A8/A9架構裡，這個問題，是透過共用記憶體方式解決。也就是Cortex A8/A9多核心架構，處理器核心間是共用記憶體。共用的記憶體包含二種，第一種是成本較高，但速度較快的 L2 Cache；另一個共用記憶體則是DRAM，它的成本較低、容量較大，但速度較慢。]]>
      
   </content>
</entry>
<entry>
   <title>Android 4.0 源碼即將登場：產業將再起什麼變化？ </title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/11/android-4-0-wave-taiwan.html" />
   <id>tag:www.jollen.org,2011:/blog//2.754</id>
   
   <published>2011-11-05T10:25:40Z</published>
   <updated>2011-11-05T15:29:42Z</updated>
   
   <summary>文／Jollen Chen（原文刊載於「零組件雜誌」2011年11月號） 經過10個月的等待，最新的Android源碼，千呼萬喚始出來。Android開始源碼專案，稱之為Android Open Source Project（即AOSP)，目前的最新版本是2.3，下一個AOSP將會是4.0。Google跳過Android 3.0的原因，據信是因為「Android 3.0程式碼不適合開源」，從技術面的角度來看，可能是碼源的組織結構尚未建全，以及架構設計並未經過全面驗證。 Android 4.0 跨裝置作業系統 從目前已公開的Android 4.0 SDK來看，確實是一個「跨裝置」的作業系統。代號為Ice Cream Sandwich的Android 4.0強調「手機與平板」通用，在新特色列表裡，我們也能發現，應用程式面的特色增加不少。事實上，這次Android 4.0的發佈，Google並沒有說明框架或底層技術細節的變動，而是強調應用軟體面的新功能。 Android 4.0可以說是Android發展史的「第三個重要時代」。熱呼呼的Android 4.0源碼即將到手，廠商應該如何調整接下來的研發策略？在此提供一些想法，請不吝指教。 軟體與產品公司興起、ODM 模式走入尾聲？ 第一、產品公司的利基已經顯現。第三個Android發展時期，即Android 4.0的時代，訴求已經很明顯，那就是「應用軟體」。重視應用軟體，並不等於組織一個應用軟體研發團隊。實際上，Android Market近20萬個軟體，都是最好的「創意庫」。因此，Android 4.0對於產品公司特別有利基點，因為有了自有產品，才有機會專注在應用軟體與網路服務的整合，發展創新特色。 第二、系統廠應消除研發累贅。所謂的研發累贅，廣義上來說，可以是符合以下二個條件的工作：1. 重覆性工作、2. 研發成本過高的活動。重覆性工作視廠商性質不同而定，例如：感測器研發系統廠，「Android 移植」就是一個重覆性工作，因為接下來，廠商將能直接由「社群」或是「處理器原廠」取得完整度很高的參考設計，只需將重心放在感測器本身的整合，以及應用層面的創新等工作即可。研發成本過高的活動，說明在第三點。 走錯研發方向、修正成本相當昂貴 第三、研發成本很低或無限大。研發成本過高的活動，內容千羅萬象，在這裡舉一個例子：「技術研究」。技術研究的目的在於「精確掌握接下來的軟體與技術趨勢」，例如：多核心（Multi-core）接下來的主流會是「異質性」或「同質性」模型。這樣的能力通常只有專家型公司辦得到，例如：知名的技術服務公司Infosys就是一個例子。Infosys曾經提過，「當企業無法跟上技術變化，創新過程將變得緩慢」，因為一但走錯研發方向，修正錯誤的代價將極為昂貴。因此，技術研究是自組團隊，或尋求專家公司的協助，需要經營者的智慧。 彼得杜拉克：「巨變時代、徹底改造」 以上三個想法，主要是推測Android 4.0降臨後，產業現況可能會發生的化學效應，並取其重，當然還會有更多的變化，不只於這三個想法。面臨變化，新策略的制定，過去的經驗是否有幫助，這可能需要省思。企業經理人，可以從彼得杜拉克「巨變時代的管理」一書中找到一些想法，包含「徹底改造」也是巨變時代的一個藥方。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[文／Jollen Chen（原文刊載於「零組件雜誌」2011年11月號）

經過10個月的等待，最新的Android源碼，千呼萬喚始出來。Android開始源碼專案，稱之為Android Open Source Project（即AOSP)，目前的最新版本是2.3，下一個AOSP將會是4.0。Google跳過Android 3.0的原因，據信是因為「Android 3.0程式碼不適合開源」，從技術面的角度來看，可能是碼源的組織結構尚未建全，以及架構設計並未經過全面驗證。

<strong>Android 4.0 跨裝置作業系統</strong>

從目前已公開的Android 4.0 SDK來看，確實是一個「跨裝置」的作業系統。代號為Ice Cream Sandwich的Android 4.0強調「手機與平板」通用，在新特色列表裡，我們也能發現，應用程式面的特色增加不少。事實上，這次Android 4.0的發佈，Google並沒有說明框架或底層技術細節的變動，而是強調應用軟體面的新功能。

Android 4.0可以說是Android發展史的「第三個重要時代」。熱呼呼的Android 4.0源碼即將到手，廠商應該如何調整接下來的研發策略？在此提供一些想法，請不吝指教。

<strong>軟體與產品公司興起、ODM 模式走入尾聲？</strong>

第一、產品公司的利基已經顯現。第三個Android發展時期，即Android 4.0的時代，訴求已經很明顯，那就是「應用軟體」。重視應用軟體，並不等於組織一個應用軟體研發團隊。實際上，Android Market近20萬個軟體，都是最好的「創意庫」。因此，Android 4.0對於產品公司特別有利基點，因為有了自有產品，才有機會專注在應用軟體與網路服務的整合，發展創新特色。

第二、系統廠應消除研發累贅。所謂的研發累贅，廣義上來說，可以是符合以下二個條件的工作：1. 重覆性工作、2. 研發成本過高的活動。重覆性工作視廠商性質不同而定，例如：感測器研發系統廠，「Android 移植」就是一個重覆性工作，因為接下來，廠商將能直接由「社群」或是「處理器原廠」取得完整度很高的參考設計，只需將重心放在感測器本身的整合，以及應用層面的創新等工作即可。研發成本過高的活動，說明在第三點。

<strong>走錯研發方向、修正成本相當昂貴</strong>

第三、研發成本很低或無限大。研發成本過高的活動，內容千羅萬象，在這裡舉一個例子：「技術研究」。技術研究的目的在於「精確掌握接下來的軟體與技術趨勢」，例如：多核心（Multi-core）接下來的主流會是「異質性」或「同質性」模型。這樣的能力通常只有專家型公司辦得到，例如：知名的技術服務公司Infosys就是一個例子。Infosys曾經提過，「當企業無法跟上技術變化，創新過程將變得緩慢」，因為一但走錯研發方向，修正錯誤的代價將極為昂貴。因此，技術研究是自組團隊，或尋求專家公司的協助，需要經營者的智慧。

<strong>彼得杜拉克：「巨變時代、徹底改造」</strong>

以上三個想法，主要是推測Android 4.0降臨後，產業現況可能會發生的化學效應，並取其重，當然還會有更多的變化，不只於這三個想法。面臨變化，新策略的制定，過去的經驗是否有幫助，這可能需要省思。企業經理人，可以從彼得杜拉克「巨變時代的管理」一書中找到一些想法，包含「徹底改造」也是巨變時代的一個藥方。]]>
      
   </content>
</entry>
<entry>
   <title>AOSP 回來了、Ice Cream Sandwich 將會開源</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/10/aosp-is-back-ice-cream-sandwich.html" />
   <id>tag:www.jollen.org,2011:/blog//2.752</id>
   
   <published>2011-10-21T04:30:33Z</published>
   <updated>2011-10-21T09:53:43Z</updated>
   
   <summary>經過漫長的等待，AOSP (Android Open Source Project) 終於回來了。這次 kernel.org 被駭事件，導致 AOSP 伺服器中斷服務近三個月，Google 終於帶來好消息。 正好 Android 4.0 (Ice Cream Sandwich) 產品發佈。根據 Google 官方說明，Ice Cream Sandwich 的源碼將在三星 Android 4.0 手機 (Nexus Prime) 上市後公開。由於社群不斷在郵件列表裡發問，這次 Google 官方為大家釋疑，讓社群開發者總算放下一塊大石；Android 4.0 確定會發佈到 AOSP，時間大約在 11 月底前。正確時間還是要看 Nexus Prime 的出貨時間而定。 AOSP...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      經過漫長的等待，AOSP (Android Open Source Project) 終於回來了。這次 kernel.org 被駭事件，導致 AOSP 伺服器中斷服務近三個月，Google 終於帶來好消息。

正好 Android 4.0 (Ice Cream Sandwich) 產品發佈。根據 Google 官方說明，Ice Cream Sandwich 的源碼將在三星 Android 4.0 手機 (Nexus Prime) 上市後公開。由於社群不斷在郵件列表裡發問，這次 Google 官方為大家釋疑，讓社群開發者總算放下一塊大石；Android 4.0 確定會發佈到 AOSP，時間大約在 11 月底前。正確時間還是要看 Nexus Prime 的出貨時間而定。

AOSP 這次也加入了新的權限管理方案，不再使用 kernel.org 提供的伺服器，而是搬回 Google 自已的伺服器，由 Google Git 接手 AOSP 的服務。

現在已經看不到 android.git.kernel.org 的小綿羊了。android.git.kernel.org 被導向到 android.googlesource.com，AOSP 也能正常下載；但目前提供的是舊版 AOSP 源碼 (2.3.7_r1)。由於 Android 3.x 可能無法正常支援手機，因此 Google 並未提供 AOSP；相信 Android 4.0 將會再帶來新的樂趣。
      
   </content>
</entry>
<entry>
   <title>Dennis M. Ritchie (1941-2011)</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/10/dennis-ritchie-1941-2011.html" />
   <id>tag:www.jollen.org,2011:/blog//2.751</id>
   
   <published>2011-10-14T15:48:18Z</published>
   <updated>2011-10-14T20:56:17Z</updated>
   
   <summary></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p align="center" style="margin-top:50px;margin-bottom:100px;"><a href="http://cm.bell-labs.com/who/dmr/">
<img alt="Dennis-Ritchie.gif" src="http://www.jollen.org/blog/2011/10/14/Dennis-Ritchie.gif" width="310" height="261" border="0" />
</a></p>]]>
      
   </content>
</entry>
<entry>
   <title>趨動台灣的硬體產業創新：10個觀念建立開放硬體專案</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/10/10-principles-to-open-source-hardware-for-taiwan-vendors.html" />
   <id>tag:www.jollen.org,2011:/blog//2.749</id>
   
   <published>2011-10-03T06:53:03Z</published>
   <updated>2011-10-03T12:12:34Z</updated>
   
   <summary>趨動台灣的硬體產業創新：10個觀念建立開放硬體專案 (文/Jollen Chen，刊載於零組件雜誌2011年10月號) 硬體產業需要融入「軟體」、「應用」與「社群」的元素，才有創新的力量。台灣的硬體產業如何創新並尋找新的機會，開放硬體是一個很好的做法。台灣硬體業者，在開放硬體運動上，也能扮演重要的角色。以下以簡單的10個觀念，協助台灣硬體廠建立開放硬體專案。 第一：提供硬體元素 (Hardware Components) 以Arduino社群為例，它提供一個可供硬體愛好者「DIY」的元素，愛家利用Arduino提供的硬體來連接週邊裝置，例如：電器用品，發揮天馬行空的創意。由開放硬體計畫由銷售的硬體，以簡單易用為原則。 第二：整合式開發工具 (Integrated Development Environment) 除了有簡單好用的特性外，軟體也是一大關鍵；最重要的軟體莫過於開放工具。目前開放源碼的軟體開發工具眾多，如果可以讓硬體的開發工具更容易上手，使用並整合至現有的開發工具，肯定是最佳的想法。 第三：決定程式碼授權與內容授權條款 (FLOSS &amp; CC License) 開放源碼(FLOSS)的眾多授權條款中，GPL(v2/v3)、BSD系列、Apache 2.0與MIT條款都是主流條款，也廣為使用。內容的授權條款則是以創用CC(Creative Commons)系列為主。不管是開放源碼、開放硬體、開放設計或開放內容，都要以這些授權條款為主。 第四：創造獨有精神象徵 (Symbols) 象徵可以是口號、符號、圖形等，或是建立完整的CIS系統。但是，若是借開放名義，行商業之實，很容易產生反效果。因此，並不建議基於企業現有的 CIS 系統，來進行這項活動。 第五：扮演適當的身份 (Sponsor is good) 如上述所提，勿假借開放名義行商業之實；但是，並不是要企業扮演慈善家，只有付出或貢獻，企業透過開放硬體社群，目前是為了創造新的商業機會。開放硬體運動是雙向的，硬體廠有貢獻，當然也可以有收獲，以「贊助商」的角色協助營運，並扮演初期創辦者的角色，都是很好的做法。 第六：社群經理人 (Manage Results not People) 從企業是開放硬體計畫的「成立者」來看，急於將社群的產出，連接到企業商業利益， 將很容易出現「控制」社群的行為。硬體廠需要了解的是，在開放硬體的計畫裡，沒有經理人：沒有任何計畫需要被管理，沒有任何社群的自發活動需要被管理。 社群與商業利益的良好結合，會是社群能長久經營的關鍵；這項工作也需要專業經理人，但經理人不是駐守在社群裡，而是在企業內部。因此，這裡指的社群經理人，並不是管理社群的人，而是善於收劍社群的產出，將之轉化為商業模式的專家。 簡而言之，企業內部的社群經理人，在於管理產出物，而不是社群本身。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[趨動台灣的硬體產業創新：10個觀念建立開放硬體專案
(文/Jollen Chen，刊載於零組件雜誌2011年10月號)

硬體產業需要融入「軟體」、「應用」與「社群」的元素，才有創新的力量。台灣的硬體產業如何創新並尋找新的機會，開放硬體是一個很好的做法。台灣硬體業者，在開放硬體運動上，也能扮演重要的角色。以下以簡單的10個觀念，協助台灣硬體廠建立開放硬體專案。

<strong>第一：提供硬體元素 (Hardware Components)</strong>

以Arduino社群為例，它提供一個可供硬體愛好者「DIY」的元素，愛家利用Arduino提供的硬體來連接週邊裝置，例如：電器用品，發揮天馬行空的創意。由開放硬體計畫由銷售的硬體，以簡單易用為原則。

<strong>第二：整合式開發工具 (Integrated Development Environment)</strong>

除了有簡單好用的特性外，軟體也是一大關鍵；最重要的軟體莫過於開放工具。目前開放源碼的軟體開發工具眾多，如果可以讓硬體的開發工具更容易上手，使用並整合至現有的開發工具，肯定是最佳的想法。

<strong>第三：決定程式碼授權與內容授權條款 (FLOSS & CC License)</strong>

開放源碼(FLOSS)的眾多授權條款中，GPL(v2/v3)、BSD系列、Apache 2.0與MIT條款都是主流條款，也廣為使用。內容的授權條款則是以創用CC(Creative Commons)系列為主。不管是開放源碼、開放硬體、開放設計或開放內容，都要以這些授權條款為主。

<strong>第四：創造獨有精神象徵 (Symbols)</strong>

象徵可以是口號、符號、圖形等，或是建立完整的CIS系統。但是，若是借開放名義，行商業之實，很容易產生反效果。因此，並不建議基於企業現有的 CIS 系統，來進行這項活動。

<strong>第五：扮演適當的身份 (Sponsor is good)</strong>

如上述所提，勿假借開放名義行商業之實；但是，並不是要企業扮演慈善家，只有付出或貢獻，企業透過開放硬體社群，目前是為了創造新的商業機會。開放硬體運動是雙向的，硬體廠有貢獻，當然也可以有收獲，以「贊助商」的角色協助營運，並扮演初期創辦者的角色，都是很好的做法。

<strong>第六：社群經理人 (Manage Results not People)</strong>

從企業是開放硬體計畫的「成立者」來看，急於將社群的產出，連接到企業商業利益， 將很容易出現「控制」社群的行為。硬體廠需要了解的是，在開放硬體的計畫裡，沒有經理人：沒有任何計畫需要被管理，沒有任何社群的自發活動需要被管理。

社群與商業利益的良好結合，會是社群能長久經營的關鍵；這項工作也需要專業經理人，但經理人不是駐守在社群裡，而是在企業內部。因此，這裡指的社群經理人，並不是管理社群的人，而是善於收劍社群的產出，將之轉化為商業模式的專家。

簡而言之，企業內部的社群經理人，在於管理產出物，而不是社群本身。

<strong>第七：建立銷售管理 (Create Disty & Resller Program)</strong>

硬體要容易取得，這是開放硬體計畫很重要的事情。硬體不像是軟體，軟體可以很容易透過下載取得。因此，為你的實體硬體建立銷售管道，將是很重要的工作。

開放硬體社群會願意付費購買硬體，供應商當然也可以從中得到合理利潤；只要一切合理，以商業方式銷售硬體，是應該要鼓勵的作法。這是一種正面的循環，硬體廠可以創造合理利潤，玩家又能以合理價格取得硬體。

以 Disty & Reseller Program 來說，建議可以連絡區域性的代理商或代銷商，目前網路上有許多社群導向的線上銷售公司，這些都是第一優先的建議名單。

<strong>第八：獨立網址 (Create .org/.com)</strong>

為開放硬體計畫創造獨立的網站，當然也要為它申請獨立的網址。這點很重要，因為關係到未來行銷或是PR工作。獨立網址，也更容易讓人留下最佳的第一印象。

<strong>第九：了解OSHW文化 (Read OSHW)</strong>

閱讀OSHW(Open Source Hardware)的官方網站，了解OSHW的定義、歷史活動以及成功案例，都是了解開放硬體文化的作法，但都比不上實地參與更有效。要建立開放硬體社群，就不能只是紙上談兵，就算沒有經驗，也要起身而行，求教有經驗的社群，做學做邊又何妨。

<strong>第十：確實開放 (Completely Open)</strong>

相信這是台灣硬體廠內心最掙扎的一點，確實開放，代表要以「創辦者」與「贊助者」的心態，充份開放足夠的技術資訊，例如：Schematics、BOM、Gerber 等，儘量不要讓開發者面臨技術資訊不足的困境。

如果有商業機密的考量，當然可以選擇不公開技術資訊，因為這也是一種正向循環，可以讓硬體廠在商業上得到保障，又能尋找新機會。因此，確實開放的定義是：選擇能「充份公開」的「部份」。

<strong>仕橙部落「開放硬體」專欄</strong>

過去一個月，仕橙部落針對開放硬體也做了一些報導「<a href="http://www.moko365.com/enterprise/sp001-20110929-open-hardware" target="_blank">OSHW 專欄</a>」。]]>
      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] Android 的 JNI 開發，排名第一名的誤用是？</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/09/android-jni-passing-array-use-getintarrayregion.html" />
   <id>tag:www.jollen.org,2011:/blog//2.748</id>
   
   <published>2011-09-26T16:21:34Z</published>
   <updated>2011-09-26T22:24:36Z</updated>
   
   <summary>Java 與 native code 的溝通介面稱為 JNI，這是 Android 底層開發的基本技術。不過，有許多 C 語言遺留下來的壤習慣，讓很多系統程式的開發者，一不小心就把 JNI 的程式碼寫錯。本週將會在一場論壇上說明幾個「誤用 C 語言」的例子，希望對 Android 底層開發的初學者有幫助。 近期在協助一家企業進行 Android 內訓，也遇到工程師問起「Java 如何與 C 傳遞資料」的問題，以傳遞陣列來說，其程式碼的寫法，跟傳統的 C 語言寫法有點不同。 從過去的教育訓練經驗裡也能歸納發現，排行榜第一名的誤用莫過於「陣列傳遞」，當 Java 透過 JNI 傳遞 Array 給 native code 時，native code 必須使用 JNI 的 GetIntArrayRegion() method...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Java 與 native code 的溝通介面稱為 JNI，這是 Android 底層開發的基本技術。不過，有許多 C 語言遺留下來的壤習慣，讓很多系統程式的開發者，一不小心就把 JNI 的程式碼寫錯。本週將會在一場論壇上說明幾個「誤用 C 語言」的例子，希望對 Android 底層開發的初學者有幫助。

近期在協助一家企業進行 Android 內訓，也遇到工程師問起「Java 如何與 C 傳遞資料」的問題，以傳遞陣列來說，其程式碼的寫法，跟傳統的 C 語言寫法有點不同。

從過去的教育訓練經驗裡也能歸納發現，排行榜第一名的誤用莫過於「陣列傳遞」，當 Java 透過 JNI 傳遞 Array 給 native code 時，native code 必須使用 JNI 的 GetIntArrayRegion() method 來讀取，而不是使用 C Pointer 的做法。

例如：

<pre>
int intArrayAdd(int *num)
{
   int i, sum = 0;
  　
   for (i = 0; i < 10; i++) {
      sum += num[i];
   }
}
</pre>

換成 JNI 的話，應該改寫成：

<pre>
intArraryAdd(JNIEnv *env, jobject obj, jintArray arr)
 {
     jint buf[10];
     jint i, sum = 0;
　
     (*env)->GetIntArrayRegion(env, arr, 0, 10, buf);
　
     for (i = 0; i < 10; i++) {
         sum += buf[i];
     }
     return sum;
 }
</pre>

這裡的概念是，將陣列 copy 到 native code 裡後再使用。相關的完整說明，可參考「The Java Native Interface. Programmer's Guide and Specification」第 3.3 節。
]]>
      
   </content>
</entry>
<entry>
   <title>Android 軟體品質管理： 台灣硬體廠如何提升軟體能力</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/09/android-code-review-with-training-is-a-must-for-taiwan-industry.html" />
   <id>tag:www.jollen.org,2011:/blog//2.746</id>
   
   <published>2011-09-05T15:57:43Z</published>
   <updated>2011-09-05T21:02:26Z</updated>
   
   <summary>文／Jollen Chen (原文刊載於零組件雜誌 2011 年 9 月號) 建立 Android 專用的 Code Review 流程是關鍵 照顧程式碼品質就像照顧身體，要常常檢查，隨時注意異狀。Android 的開發工作如果要確保可用（Usable）與穩定（Stability），就要做好 Code Review 的工作。根據過去與許多廠商的合作經驗發現，許多關鍵的軟體開發觀念經常被忽略。主要的原因為，大部份的技術開發思惟，都比較偏向硬體與驅動程式方面，或是功能性的實作。 軟體的開發本身就是一項大工程，由 Android 所創造出來的手機作業系統，可能有近 90% 的比例是透過軟體工程的技術與觀念所開發，其它 10% 才是考量硬體層面，或是驅動程式層面。換個角度來看，以台灣硬體廠商的技術水準，如果把軟體工程的技術養成，一定能具備產品開發的實力。以下提供個人的一點建議：台灣硬體廠該如何提升軟體開發能力。 第一、先做再說、確實可行。單獨以 Android 的框架與軟硬整合的角度來看，先設計後實作（Design &amp; Implementation）的方法論可能不適用於台灣的產業環境，因此導入傳統的軟體工程方法論，或許也沒有絕對的必要性；原因是，Android 已經把這些基礎建設都做到一定程度了。在理論與實際間取捨的話，「先實作、後檢視」可能是一種方式。 目前在業界所見的程式碼實作，大多偏重硬體與功能面，在理論面著墨不深，不過這卻是個很好的契機。過去自已的經驗發現，先實作，得到初步可用的程式碼實作後，再考量理論面，進行程式碼調整，其實是可行、有效率的做法。因此，自已也希望能將這個觀念與方法論，提供給客戶參考，甚或協助導入「先實作、後檢視」的作業流程。 什麼是 Code Review 第二、實施 Code Review 就對了。軟體的開發工作，都會有 Code...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[文／Jollen Chen (原文刊載於零組件雜誌 2011 年 9 月號)

<strong>建立 Android 專用的 Code Review 流程是關鍵</strong>

照顧程式碼品質就像照顧身體，要常常檢查，隨時注意異狀。Android 的開發工作如果要確保可用（Usable）與穩定（Stability），就要做好 Code Review 的工作。根據過去與許多廠商的合作經驗發現，許多關鍵的軟體開發觀念經常被忽略。主要的原因為，大部份的技術開發思惟，都比較偏向硬體與驅動程式方面，或是功能性的實作。

軟體的開發本身就是一項大工程，由 Android 所創造出來的手機作業系統，可能有近 90% 的比例是透過軟體工程的技術與觀念所開發，其它 10% 才是考量硬體層面，或是驅動程式層面。換個角度來看，以台灣硬體廠商的技術水準，如果把軟體工程的技術養成，一定能具備產品開發的實力。以下提供個人的一點建議：台灣硬體廠該如何提升軟體開發能力。

第一、先做再說、確實可行。單獨以 Android 的框架與軟硬整合的角度來看，先設計後實作（Design & Implementation）的方法論可能不適用於台灣的產業環境，因此導入傳統的軟體工程方法論，或許也沒有絕對的必要性；原因是，Android 已經把這些基礎建設都做到一定程度了。在理論與實際間取捨的話，「先實作、後檢視」可能是一種方式。

目前在業界所見的程式碼實作，大多偏重硬體與功能面，在理論面著墨不深，不過這卻是個很好的契機。過去自已的經驗發現，先實作，得到初步可用的程式碼實作後，再考量理論面，進行程式碼調整，其實是可行、有效率的做法。因此，自已也希望能將這個觀念與方法論，提供給客戶參考，甚或協助導入「先實作、後檢視」的作業流程。

<strong>什麼是 Code Review</strong>

第二、實施 Code Review 就對了。軟體的開發工作，都會有 Code Review 的流程。這裡所提的「檢視」即 Code Review。Code Review 是一個很久的觀念了，它在軟體管理（Software Management）的領域裡被詳細討論。

Code Review 是一個系統化的檢查過程，目的是確定程式碼的品質；檢查的過程，是為了找出錯誤、並且修正錯誤，這些錯誤在初階的開發階段（Initial Development Phase）可能不會被發現。這裡的「錯誤」也包含「觀念上的錯誤」、「理論的誤用」等等，因此，能動作（Workable）的程式碼，不見得是正確的程式碼。

<strong>Code Review 是教育訓練的一環</strong>

第三、搭配教育訓練。Code Review 還有另外一個很重要的目的，卻不常被提及，就是「提升開發人員的技能」。Code Review 等於 Improve Software Quality + Improve Developer's Skills。軟體的品質，影響軟體的穩定性；人員的素質，影響軟體的品質。在初階開發階段，可以不必發現理論上的問題，而是下一階段，由資深開發人員協助 Code Review，再進行程式碼調整，以提升軟體品質。這就是「先實作、後檢視」的精神。

最後、其實是一個例子。以 Android Framework 與 Linux 驅動程式為例，主要影響系統穩定性的關鍵在於「Android 框架與 Linux 驅動程式的資料傳遞方式」，即「儲存資料」並「傳遞記憶體」的方式。「記憶體的使用」是影響 Android 與 Linux 整合穩定性的主要因素。Android 底層可能需要以 Memory Heap 來儲存並傳遞大量資料，而非以 C 語言指標（Pointer）的方式進行。

從事硬體發展的研發人員，可以在初階開發階段以 malloc 搭配 C 語言指標，來傳遞硬體資料給 Android 作業系統。但是，必須有 Code Review 人員，協助將初階的實作，修改為 Memory Heap 方式，並以物件觀念傳遞。 重構後的程式碼，可以協助該硬體開發人員，提升他（她）的軟體技能。這種「先開發、後檢視」的作法，就是 Code Review 的精神，也是台灣硬體業提升 Android 程式碼穩定性，以及提升開發人員技能的一個方法。]]>
      
   </content>
</entry>
<entry>
   <title>Motorola 嫁進 Google 大門，台灣硬體廠如何因應，與 Android 的未來</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/08/google-to-acquire-motorola-mobility-impact-of-taiwan-hardware-industry.html" />
   <id>tag:www.jollen.org,2011:/blog//2.744</id>
   
   <published>2011-08-18T14:39:23Z</published>
   <updated>2011-08-25T21:06:48Z</updated>
   
   <summary>Google 過去四年來對 Android 應用程式框架的貢獻巨大，可視為「資訊科技整合」的一個代表作，購併 Motorola Mobility Inc 後，除了媒體所討論的專利議題外，Google 更能從 Motorola Mobility 身上，學習到寶貴的軟硬整合經驗，這是更重要的進步。一般認為收購之舉是衝著專利而來。大家比較沒有注意到的是 IBM 也擁有許多作業系統專利，不久前，Google 也「一籃子」收購 IBM 專利，因此，Motorola 嫁進 Google 大門，專利議題應是主因。以下從「非專利」面分享一些個人看法，請不吝指教。 自有能力 vs 重度依賴 台灣硬體廠學習軟體的速度緩慢，對 Google 有很高程度的依賴。在 Google 購併 Motorola Mobility Inc 後，紛紛對 Android 的開放性提出質疑，並且認為 Motorola 將取得更多的 Android 資源，其它廠商或將淪為「二等公民」。 台灣硬廠對軟體的高度依賴性並不是現在才開始。從 Wintel...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Google 過去四年來對 Android 應用程式框架的貢獻巨大，可視為「資訊科技整合」的一個代表作，購併 Motorola Mobility Inc 後，除了媒體所討論的專利議題外，Google 更能從 Motorola Mobility 身上，學習到寶貴的軟硬整合經驗，這是更重要的進步。一般認為收購之舉是衝著專利而來。大家比較沒有注意到的是 IBM 也擁有許多作業系統專利，不久前，Google 也「一籃子」收購 IBM 專利，因此，Motorola 嫁進 Google 大門，專利議題應是主因。以下從「非專利」面分享一些個人看法，請不吝指教。

<strong>自有能力 vs 重度依賴</strong>

台灣硬體廠學習軟體的速度緩慢，對 Google 有很高程度的依賴。在 Google 購併 Motorola Mobility Inc 後，紛紛對 Android 的開放性提出質疑，並且認為 Motorola 將取得更多的 Android 資源，其它廠商或將淪為「二等公民」。

台灣硬廠對軟體的高度依賴性並不是現在才開始。從 Wintel 時代開始，就非常依賴微軟視窗作業系統，不過，由於當初時空背景的關係，微軟作業系統是整個 PC 標準重要環節，大家是一個 Ecosystem，因此沒有建立自有作業系統的必要性。

這個從小到大的習慣，開始帶來壞處。就像一個被寵壞的小孩子一般，硬體廠普遍認為 Google 提供完善的 Android 程式碼是順理成章的事情，有了完整的程式碼，以及適當程度的「保護」後，「大家才願意跟著玩」，這或許不是一個很健康的想法。如何建立自已的軟體技術能力，似乎少有人思考。

<strong>回歸自由軟體的精神</strong>

Google 對 Android 的投入與貢獻，不該被忽略。Android 的定位很清楚，有一份 AOSP 版本，Google 也不斷在內部開發更棒的新版本。AOSP 是 Google 在開放平臺與自由軟體的重要貢獻之一，這就是 Android Open Source Project 的目的，貢獻源碼，提供自由軟體，「但這並不表示 Google 有責任為硬體廠付出任何責任」，韓國三星電子近期強力要求旗下部門強化軟體競爭力，這才是台灣產業要認真思考的方向。

事實上，AOSP 僅只是 Google 對自由軟體的貢獻之一，而不是唯一。Google 也提供 AJAX 程式庫，也有免費的 CSS 字型，也支持 jQuery 等重要的自由軟體專案，「聽說 Google 將封閉 Android 程式碼」，並不是健康的想法。如果了解 Google 在自由軟體工程領域的貢獻，就會了解，「只是先關起門來把事情做好」，而不是對外關起大門。

<strong>朝向開放 API 搭配部份開放源碼</strong>

事實上，要取得目前最新版本的 Android 程式碼不是高牆。在 Android ecosystem 裡，Google 很清楚自已所扮演的角色：「Android Product Manager」，因此，Google 有責任了解廠商的「產品理念」，才能扮演好自已的角色。

封閉程式碼，與做好 Product Manager 的工作，格局差異太大，前者並不是大格局做法，實際上目前也未聽聞 Android 有這項計畫。個人看法是，Google 接下來應會加速開放 API 以及部份程式碼的腳步。過去 Android 產品是一種失控的狀態，為避免重蹈覆徹，完全開放源始碼短期可能性應不高。

有了底層的程式碼、HAL 技術架構等，透過軟體工程技術，將開放 API 整合至產品並不困難。開放 API 已足夠，並不需要完全開放源碼才能做產品。早在 Android 1.6 版時代，Google API 就以 Open API（封裝後的二進位程式碼）的形式提供在 AOSP 裡。

<strong>看看 Arduino、回頭想想自已</strong>

Arduino 是一個開放源碼的 I/O Board，可用來連接外部控制器或週邊裝置，如：馬達。Arduino 是一個知名的開放源碼專案，它做硬體，同時整合軟體並提供一個開發環境。這項硬體技術，對台灣的硬體廠來說，只是小兒科。

Google 於今年五月發表的 Android Open Accessory Development Kit（ADK）就是基於 Arduino 專案及其硬體。台灣的硬體技術水準很高，零件廠夠多夠大，但對 Android 的影響力卻不及 Arduino 專案，很明顯地是經理能力出現問題：缺乏開放平臺觀念、軟體與社群社交等能力。

<strong>Lession Learing</strong>

這二天有一些合作廠商，因 Google 購併 Motorola Mobility Inc 表現出不安，提出的許多疑問其實也很合理，但 Google 並沒有照顧硬體廠的責任。AOSP 是自由軟體的精神，儘快建立自已的軟體實力，靠自已最實在，就算基於 AOSP 也能做出好東西，一些主要的 Android 手機製造商已經學到這一課。

再者，台灣主要的硬體廠，也都早已取得 Android 3.x 程式碼，並不是無法取得最新的程式碼，只是過去太重度依賴 Google 的 Android 團隊，這是比較大的問題。如果連 Android 3.x 的程式碼都無法取得，封閉之說才有那麼一些道理。

上述想法並沒有任何預設主場，僅只是想法分享。過去幾年為許多台灣硬體廠提供 Android 技術服務，其實大家也都很有學習的企圖心，只是我們還需要一些時間，多一點正面想法，接著拭目以待囉。]]>
      
   </content>
</entry>
<entry>
   <title>淺談 GNU/Linux 與 Android/Linux 的差異：Android 非常需要 Permissive License 的授權模式</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/07/android-needs-permissive-license-to-distribute-products.html" />
   <id>tag:www.jollen.org,2011:/blog//2.743</id>
   
   <published>2011-07-11T10:42:24Z</published>
   <updated>2011-07-11T22:56:07Z</updated>
   
   <summary>上週五受台北科技大學資工系的邀請，發表了一個小時的演講，講題是「淺談 GNU/Linux 與 Android/Linux 的差異」，如同題目所要表達的，「Android+Linux」並不是「GNU+Linux」。傳統的 Embedded Linux 系統是基於 GNU/Linux 開發，因此在這次的演講裡，也做了一個「Embedded Linux 不等於 Android+Linux」的結論。 這個題目相當有趣，因為涉及非技術面的議題。在真槍實彈開發 Android 產品前，認識我們使用的 Android/Linux 系統是很重要的前置作業。這次的講題涉及層面較廣，細節也很多，小弟特別從二個層面切入：技術面談 Android/Linux Toolchain、非技術面談 FLOSS 授權。 Android 的商業模式需要 Permissive License 在 FLOSS 授權方面，並不是「不同授權的 FLOSS 軟體」都能「任意合併使用」，在了解各授權的特性與「合併使用」議題前，有必要先了解現有授權的類型。現今較廣為使用的 FLOSS（Free and Libre Open Source Software）授權有：GPLv2、GPLv3、LGPL 系列、Apache 2.0、BSD 系列、MIT...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[上週五受台北科技大學資工系的邀請，發表了一個小時的演講，講題是「淺談 GNU/Linux 與 Android/Linux 的差異」，如同題目所要表達的，「Android+Linux」並不是「GNU+Linux」。傳統的 Embedded Linux 系統是基於 GNU/Linux 開發，因此在這次的演講裡，也做了一個「Embedded Linux 不等於 Android+Linux」的結論。

這個題目相當有趣，因為涉及非技術面的議題。在真槍實彈開發 Android 產品前，認識我們使用的 Android/Linux 系統是很重要的前置作業。這次的講題涉及層面較廣，細節也很多，小弟特別從二個層面切入：技術面談 Android/Linux Toolchain、非技術面談 FLOSS 授權。

<strong>Android 的商業模式需要 Permissive License</strong>

在 FLOSS 授權方面，並不是「不同授權的 FLOSS 軟體」都能「任意合併使用」，在了解各授權的特性與「合併使用」議題前，有必要先了解現有授權的類型。現今較廣為使用的 FLOSS（Free and Libre Open Source Software）授權有：GPLv2、GPLv3、LGPL 系列、Apache 2.0、BSD 系列、MIT 等等。

上述的授權條款可分為三大類型：

<ul>
<li>1. Permissive License</li>
<li>2. Weak Copyleft</li>
<li>3. Strong Copyleft</li>
</ul>

Copyleft 的授權模式主要在限制軟體不能以 proprietary software 形式散佈，copyleft 的授權模式又分為 weak 與 strong 二種；例如 GPLv2 是屬於 strong copyleft 的授權，大大地限制軟體不能以 proprietary 的形式散佈。

Permissive license 則允許軟體以 proprietary software 的形式散佈，開發 Android 需要從產品面思考，不能單方面只思考技術面，從產品面來看，Android 程式碼非常需要 permissive license 的授權模式，因為有許多核心技術或是關鍵的軟硬整合實作，需要以 proprietary software 的形式散佈。]]>
      
   </content>
</entry>
<entry>
   <title>台灣廠商與老闆們，可以枉尺直尋的心態投入「架構研究」工作</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/07/view-of-architecture-research-for-taiwan-industry.html" />
   <id>tag:www.jollen.org,2011:/blog//2.742</id>
   
   <published>2011-07-06T08:15:46Z</published>
   <updated>2011-07-06T13:37:11Z</updated>
   
   <summary>先前談了有關「架構分析工程師」的重要性，在這裡再分享「為什麼研究架構」是一項重要的工作，也值得業界投入。 架構分析與研究還有一個很重要的目的：找出問題、解決問題，透過較為有系統的方式找出問題的起因，並研究解決問題的有效方法。在研發工作上，可以大幅縮短開發時間。從專案的角度來看，有二個好處： 縮短自行摸索時間。在有經驗者的引領下，從學習、訓練、實習、經驗累積到開發案參與，都有明確的方法；在技術工作上，可立即了解每個技術議題所涉及的背景知識。在真正專案開始後，能往正確的方向前進。 解決問題。系統廠普遍存在一個老問題，就是「try-and-error」的解決問題方法。從架構分析面著手，能了解問題可能發生的層面，逐步縮小範圍，以找出解決問題的方法。從實務角度來看，「Research」是為了解決問題，完成工作任務。 因此，「架構分析」是幫助我們「解決問題」與「縮短摸索時間」的良方。學術上的「做研究」是為了學問，但業界做研究，很大一部份是為了解決問題，目的大不同。因此，研究工作、研究型軟體公司，或是顧問公司，將會扮演重要的角色。 研究工作在追求更大範圍的收獲 不過是縮短摸索時間，或是解決問題，關鍵都在「時間」這項資源上。架構分析導向的問題解決過程，確實能加快解決問題的時間。反之，有時在解決技術上的問題後，常常會有走了很多冤枉路的感覺，「要是當初知道這樣做，早就解決問題了」，可不是嗎？ 不過是自行投入技術研究工作，或是尋求與技術研究公司合作，雖然一開始會有「沒有產出」，或是「不夠具體化」的感覺，也會感覺前期的投資沒有回收；但是，如果看得更長遠，枉尺而直尋，宜若可為也。最後，總結看法並簡單翻譯，「研究工作長遠來看，當可創造新的營收來源」，因為研究者能以創作心態做產品，製造者是以成本心態做產品。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[先前談了有關「架構分析工程師」的重要性，在這裡再分享「為什麼研究架構」是一項重要的工作，也值得業界投入。

架構分析與研究還有一個很重要的目的：找出問題、解決問題，透過較為有系統的方式找出問題的起因，並研究解決問題的有效方法。在研發工作上，可以大幅縮短開發時間。從專案的角度來看，有二個好處：

<ul>
<li>縮短自行摸索時間。在有經驗者的引領下，從學習、訓練、實習、經驗累積到開發案參與，都有明確的方法；在技術工作上，可立即了解每個技術議題所涉及的背景知識。在真正專案開始後，能往正確的方向前進。</li>

<li>解決問題。系統廠普遍存在一個老問題，就是「try-and-error」的解決問題方法。從架構分析面著手，能了解問題可能發生的層面，逐步縮小範圍，以找出解決問題的方法。從實務角度來看，「Research」是為了解決問題，完成工作任務。</li>
</ul>

因此，「架構分析」是幫助我們「解決問題」與「縮短摸索時間」的良方。學術上的「做研究」是為了學問，但業界做研究，很大一部份是為了解決問題，目的大不同。因此，研究工作、研究型軟體公司，或是顧問公司，將會扮演重要的角色。

<strong>研究工作在追求更大範圍的收獲</strong>

不過是縮短摸索時間，或是解決問題，關鍵都在「時間」這項資源上。架構分析導向的問題解決過程，確實能加快解決問題的時間。反之，有時在解決技術上的問題後，常常會有走了很多冤枉路的感覺，「要是當初知道這樣做，早就解決問題了」，可不是嗎？

不過是自行投入技術研究工作，或是尋求與技術研究公司合作，雖然一開始會有「沒有產出」，或是「不夠具體化」的感覺，也會感覺前期的投資沒有回收；但是，如果看得更長遠，枉尺而直尋，宜若可為也。最後，總結看法並簡單翻譯，「研究工作長遠來看，當可創造新的營收來源」，因為研究者能以創作心態做產品，製造者是以成本心態做產品。]]>
      
   </content>
</entry>
<entry>
   <title>培養 Android 軟體人才： 從落實軟體工程教育開始</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/06/android-software-engineering-education.html" />
   <id>tag:www.jollen.org,2011:/blog//2.741</id>
   
   <published>2011-06-29T15:24:40Z</published>
   <updated>2011-06-30T17:11:33Z</updated>
   
   <summary>文／Jollen（原文刊載於零組件雜誌 2011 年 6 月號） 「開發 Android」是台灣科技業的全民運動了。未來幾年，如果要尋求更大的突破，並提升整體軟體開發能力，根本的做法與策略為何？個人看法是「落實軟體工程的基本教育」。以下是個人對於「軟體人才培養」的看法與心得，請不吝指教。 提昇 Android 軟體能量，我們的當務之急是：培養一批「架構分析」的工程師。架構分析需要考量的層面較廣，包括技術面與產品面。軟硬整合的工作，幾年前訴求的是硬體驅動程式與系統軟體，主要工作是效能的提昇與優化，這是從硬體層面思考的軟硬整合。從產品層面重新思考軟硬整合，涉及的層面會放大至中間軟體（Middleware、Application Framework）、應用程式（Application）以及網路服務等。 架構分析的重點工作之一，在於了解 Application Framework 與驅動程式（硬體）間的關係，使用各種現有的技術來整合系統，並提出更好的架構設計方案。架構分析的技術屬於「軟體工程」領域，而不是硬體或系統程式領域。但具備驅動程式與硬體經驗，可以幫助工程師找出更好的架構設計方法。 Android 是軟體框架的技術。台灣廠商得天獨厚的優勢在於，過去積累大量的IC設計、硬體主板、驅動程式與系統軟體經驗，若能補足軟體框架的分析與設計能力，未來競爭力將有很大的想像空間。因此，導入架構分析技術，培養架構分析工程師，理論上能讓我們發揮這項得天獨厚的能力，建立獨特的競爭力。這也是三星（Samsung）正在積極進行的工作。 落實軟體工程教育是根本，必須從教育做起。軟體工程所討論的「軟體框架」就像資訊科學的「位元運算」一樣，屬於通識學科。軟體框架技術，重度依賴這些基礎學科：物件導向（OO）、物件導向語言（OOP）、物件導向分析與設計（OOAD）、分層架構設計、設計模式（Design Patterns）等，這些知識缺一不可。 軟體框架 (Software Framework ) 的四大特性 以下針對軟體框架做簡單的說明，以做為研究「軟體框架」的起步點。軟體框架具備四項特性：控制點反轉、預設行為、不可修改性與擴充性。第一、控制點反轉（Inverse of control），整體來看，控制應用程式執行流程的人，是軟體框架，而不是應用程式本身的函數呼叫關係。這與一般循序式的結構化語言（如：C語言）很不同。 第二、預設行為（default behavior），軟體框架本身都有預先設定好的行為。這些行為通常都是預先定義好後，才釋出軟體框架。所謂的「行為」範圍廣大，例如同步呼叫、非同步呼叫、阻塞式I/O等。 第三、不可修改性，這是軟體框架相當重要的觀念。以 Android 為例，其 Application Framework 的程式碼「不能」修改，開發者「不能直接改 Code」。意思是我們下載 AOSP（Android Open Source Project）程式碼後，不能直接修改框架層的程式碼。若直接修改...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[文／Jollen（原文刊載於零組件雜誌 2011 年 6 月號）

「開發 Android」是台灣科技業的全民運動了。未來幾年，如果要尋求更大的突破，並提升整體軟體開發能力，根本的做法與策略為何？個人看法是「落實軟體工程的基本教育」。以下是個人對於「軟體人才培養」的看法與心得，請不吝指教。

提昇 Android 軟體能量，我們的當務之急是：培養一批「架構分析」的工程師。架構分析需要考量的層面較廣，包括技術面與產品面。軟硬整合的工作，幾年前訴求的是硬體驅動程式與系統軟體，主要工作是效能的提昇與優化，這是從硬體層面思考的軟硬整合。從產品層面重新思考軟硬整合，涉及的層面會放大至中間軟體（Middleware、Application Framework）、應用程式（Application）以及網路服務等。

架構分析的重點工作之一，在於了解 Application Framework 與驅動程式（硬體）間的關係，使用各種現有的技術來整合系統，並提出更好的架構設計方案。架構分析的技術屬於「軟體工程」領域，而不是硬體或系統程式領域。但具備驅動程式與硬體經驗，可以幫助工程師找出更好的架構設計方法。

 Android 是軟體框架的技術。台灣廠商得天獨厚的優勢在於，過去積累大量的IC設計、硬體主板、驅動程式與系統軟體經驗，若能補足軟體框架的分析與設計能力，未來競爭力將有很大的想像空間。因此，導入架構分析技術，培養架構分析工程師，理論上能讓我們發揮這項得天獨厚的能力，建立獨特的競爭力。這也是三星（Samsung）正在積極進行的工作。

落實軟體工程教育是根本，必須從教育做起。軟體工程所討論的「軟體框架」就像資訊科學的「位元運算」一樣，屬於通識學科。軟體框架技術，重度依賴這些基礎學科：物件導向（OO）、物件導向語言（OOP）、物件導向分析與設計（OOAD）、分層架構設計、設計模式（Design Patterns）等，這些知識缺一不可。

<strong>軟體框架 (Software Framework ) 的四大特性</strong>

以下針對軟體框架做簡單的說明，以做為研究「軟體框架」的起步點。軟體框架具備四項特性：控制點反轉、預設行為、不可修改性與擴充性。第一、控制點反轉（Inverse of control），整體來看，控制應用程式執行流程的人，是軟體框架，而不是應用程式本身的函數呼叫關係。這與一般循序式的結構化語言（如：C語言）很不同。

第二、預設行為（default behavior），軟體框架本身都有預先設定好的行為。這些行為通常都是預先定義好後，才釋出軟體框架。所謂的「行為」範圍廣大，例如同步呼叫、非同步呼叫、阻塞式I/O等。

第三、不可修改性，這是軟體框架相當重要的觀念。以 Android 為例，其 Application Framework 的程式碼「不能」修改，開發者「不能直接改 Code」。意思是我們下載 AOSP（Android Open Source Project）程式碼後，不能直接修改框架層的程式碼。若直接修改 Android 應用框架程式碼，在編譯時期便會出現警告訊息。直接修改 Android 應用框架程式碼也會造成 API 相容性的問題，可能無法通過 CTS，導致產品無法上市，不可不重視。

最後是擴充性，在不能直接修改軟體框架的前提下，我們如何「加入自已的功能」至 Android 框架呢？正確的方法是以覆載（override）方式進行擴充（extend）。覆載是物件導向領域的基本知識，也是開發 Android 應用框架的重要技術。撰寫「應用程式」補上軟體框架所沒有的功能，也是「擴充性」的另外一個做法。現在正在進行 Android 開發工作的我們，具備這四個基本觀念了嗎？從以上的介紹便能發現，未來如果要在 Android 應用框架開發上有所突破，軟體工程教育就必須要落實，畢竟這是軟體開發的基本學科。]]>
      
   </content>
</entry>
<entry>
   <title>台灣，軟體意識抬頭了！Android 大功臣與 3個 M 型現象</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/05/ctimes-2011-5-taiwan-android-software-human-resource.html" />
   <id>tag:www.jollen.org,2011:/blog//2.740</id>
   
   <published>2011-05-30T15:29:21Z</published>
   <updated>2011-06-08T17:41:46Z</updated>
   
   <summary>文／Jollen Chen（原文刊載於零組件雜誌 2011 年 5 月號） 新一波的產業核心競爭力，有一個最簡單的答案，那就是「軟體」。軟體不只是「程式碼」與「技術」的代名詞，而是代表了整個新時代，從產品面來看，就是「創意」、「社群」與「網路」。「軟體提升附加價值」、「軟體才是產品的核心」等口號，不再是「下一波」產業的趨勢，而是「現在進行式」了。 近期台灣許多大廠，不約而同，大舉招募「軟體工程師」，說明軟體反客為主，將在「硬體成本競爭」時代自創格局。從「人力資源」的角度來看，經營教育訓練市場多年，最近也發現到許多過去沒有的有趣現象：人才移動很M型，自有開發能力很M型，建立軟體能力意識很M型。 第一、要人、找人 vs 找不到人。這是過去幾年沒有過的現象，可以說是「幾乎所有」的科技廠，都在設法招募優秀的軟體人員，以提升公司的軟體能力。軟體相關的招募需求旺盛，前所未見。從目前開放出來的軟體職務，以及招募現況來看，呈現相當兩極的現象。頂尖人才或即戰力，幾乎都往少數科技大廠移動，更多廠商開放出來的職務則是乏人問津，顯見「軟體」的新時代，公司的號召力、形象、品牌、活力與產品等，才是吸引人才的關鍵。 第二、委外、再委外 vs 自有開發能力。因為Android前景大好，有不少軟體外包的案件，為數可觀；廠商也大舉採取委外方式，「設法解決一些技術問題」。不過，有一點可以讓我們思考的現象是，有軟體開發「丟包」需求的，幾乎都是中小型廠商，甚至是一些二線品牌，從另一個角度來看，我們應該是設法提升自我的軟體開發能量，建立自已的核心價值，委外不再是面對軟體時代的良好解決方案。有能力自製軟體的，大多數都是大型產品公司，或是小型新創軟體公司。台灣品牌找深圳山寨做「代工」，就是很好的例子。 第三、內部軟體人才的培養。從事教育訓練多年，很明顯感受到，這一年公司對內部軟體人員養成的重視。不單單只是從這一年接受內訓委託案的數量來看，更可以從廠商心態轉變來看。很令人感到興奮的是，廠商不但有強烈的「建立軟體團隊」意識，更願意投入資源，培養內部團隊。大部份具規範的廠商，積極採取內部培養的方式建立軟體能力，這與中小型廠商的「委外」做法，大相逕庭。現在的現象是，有人積極培養軟體能力，也有人認為仍必須做成本競爭，軟體只是附件。 最後，這是個人看法。不過是招募、委外或內部養成，都能有效地解決「軟體開發面」的問題，但就像我們知道的，軟體是「網路」、「應用」、「創意」、「社群」、「產品」等多面向的技術，除了開發技術外，產品規劃也是很重要的能力。台灣一些品牌廠的成功經驗，是值得我們借鏡與學習的。從這個角度來看，提升產品經理人對軟體的認知，才能擺脫「硬體思惟」，擺脫「成本、規格與 BOM」的硬體勝利方程式 (Hardware)；有了軟體，應該來做真正的「產品 (Product)」。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      文／Jollen Chen（原文刊載於零組件雜誌 2011 年 5 月號）

新一波的產業核心競爭力，有一個最簡單的答案，那就是「軟體」。軟體不只是「程式碼」與「技術」的代名詞，而是代表了整個新時代，從產品面來看，就是「創意」、「社群」與「網路」。「軟體提升附加價值」、「軟體才是產品的核心」等口號，不再是「下一波」產業的趨勢，而是「現在進行式」了。

近期台灣許多大廠，不約而同，大舉招募「軟體工程師」，說明軟體反客為主，將在「硬體成本競爭」時代自創格局。從「人力資源」的角度來看，經營教育訓練市場多年，最近也發現到許多過去沒有的有趣現象：人才移動很M型，自有開發能力很M型，建立軟體能力意識很M型。

第一、要人、找人 vs 找不到人。這是過去幾年沒有過的現象，可以說是「幾乎所有」的科技廠，都在設法招募優秀的軟體人員，以提升公司的軟體能力。軟體相關的招募需求旺盛，前所未見。從目前開放出來的軟體職務，以及招募現況來看，呈現相當兩極的現象。頂尖人才或即戰力，幾乎都往少數科技大廠移動，更多廠商開放出來的職務則是乏人問津，顯見「軟體」的新時代，公司的號召力、形象、品牌、活力與產品等，才是吸引人才的關鍵。

第二、委外、再委外 vs 自有開發能力。因為Android前景大好，有不少軟體外包的案件，為數可觀；廠商也大舉採取委外方式，「設法解決一些技術問題」。不過，有一點可以讓我們思考的現象是，有軟體開發「丟包」需求的，幾乎都是中小型廠商，甚至是一些二線品牌，從另一個角度來看，我們應該是設法提升自我的軟體開發能量，建立自已的核心價值，委外不再是面對軟體時代的良好解決方案。有能力自製軟體的，大多數都是大型產品公司，或是小型新創軟體公司。台灣品牌找深圳山寨做「代工」，就是很好的例子。

第三、內部軟體人才的培養。從事教育訓練多年，很明顯感受到，這一年公司對內部軟體人員養成的重視。不單單只是從這一年接受內訓委託案的數量來看，更可以從廠商心態轉變來看。很令人感到興奮的是，廠商不但有強烈的「建立軟體團隊」意識，更願意投入資源，培養內部團隊。大部份具規範的廠商，積極採取內部培養的方式建立軟體能力，這與中小型廠商的「委外」做法，大相逕庭。現在的現象是，有人積極培養軟體能力，也有人認為仍必須做成本競爭，軟體只是附件。

最後，這是個人看法。不過是招募、委外或內部養成，都能有效地解決「軟體開發面」的問題，但就像我們知道的，軟體是「網路」、「應用」、「創意」、「社群」、「產品」等多面向的技術，除了開發技術外，產品規劃也是很重要的能力。台灣一些品牌廠的成功經驗，是值得我們借鏡與學習的。從這個角度來看，提升產品經理人對軟體的認知，才能擺脫「硬體思惟」，擺脫「成本、規格與 BOM」的硬體勝利方程式 (Hardware)；有了軟體，應該來做真正的「產品 (Product)」。
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android Leak 開發解密, #4: Don&apos;t Create Unnecessary Objects in Main Thread</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/05/android-leak-3-dont-create-unnecessary-object-in-main-thread.html" />
   <id>tag:www.jollen.org,2011:/blog//2.739</id>
   
   <published>2011-05-29T15:56:54Z</published>
   <updated>2011-05-29T22:13:50Z</updated>
   
   <summary>在 Dev Guide 裡還有另外一個重要的觀念：避免產生不必要的物件。這個觀念真的很重要，如果要讓程式的效能更好，不斷在 Main Thread 裡產生物件是 bad idea。原因是 Garbage Collection。 Android 的 Dalvik 虛擬機在初始化時，會建立 Main Thread。Main Thread 負責眾多任務，其中之一是 Garbage Collection，也就是負責做資源回收，把用不到的物件回收再利用。如果我們不斷在 Main Thread 裡產生物件，Main Thread 很可能忙著幫我們收拾垃圾，當 Main Thread 花費太多心思幫我們撿垃圾，處理其它工作的效率就會變差，例如：UI 事件處理。 所以，這告訴我們一個重要的觀念：「不要產生不必要的物件」，難怪 Dev Guide 在講「Designing for Performance」時，把這個觀念放在首位。有些 Class 在設計時，提供了多種 instantiate（實例化）方法，以 android.os.Message...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[在 Dev Guide 裡還有另外一個重要的觀念：避免產生不必要的物件。這個觀念真的很重要，如果要讓程式的效能更好，不斷在 Main Thread 裡產生物件是 bad idea。原因是 Garbage Collection。

Android 的 Dalvik 虛擬機在初始化時，會建立 Main Thread。Main Thread 負責眾多任務，其中之一是 Garbage Collection，也就是負責做資源回收，把用不到的物件回收再利用。如果我們不斷在 Main Thread 裡產生物件，Main Thread 很可能忙著幫我們收拾垃圾，當 Main Thread 花費太多心思幫我們撿垃圾，處理其它工作的效率就會變差，例如：UI 事件處理。

所以，這告訴我們一個重要的觀念：「不要產生不必要的物件」，難怪 Dev Guide 在講「Designing for Performance」時，把這個觀念放在首位。有些 Class 在設計時，提供了多種 instantiate（實例化）方法，以 android.os.Message 為例，我們可以這樣做：

<blockquote>Message msg = new Message();</blockquote>

也可以這樣做：

<blockquote>Message msg = Message.obtain();</blockquote>

透過 Message.obtain() 做實例化，可以重用先前的 Message object：

<blockquote>Return a new Message instance from the global pool. Allows us to avoid allocating new objects in many cases. (--Android SDK Reference)</blockquote>

如果要在 Main Thread 裡以 Message 方式處理「按鍵事件」，較好的寫法就是：

<pre>
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		...
		mHandler.sendMessage(Message.obtain()); // 可避免產生不必要的物件
		...
	}
</pre>
	
要避免，也不要在 Main Thread 裡產生不必要的物件。

<em>Android Leak 開發解密系列，整理自 Jollen 過去在 Android 領域的經驗，以「Do & Don't Do」形式分享一些重要但常被略的開發觀念。轉載請全文引用，並註明出處 (Jollen's Blog, <a href="http://www.jollen.org/blog">http://www.jollen.org/blog</a>)，謝謝您對數位內容著作權的支持。</em>]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android Leak 開發解密, #3: Don&apos;t Access the Android UI toolkit at Worker Threads </title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/05/android-leak-3-dont-access-android-ui-toolkit-at-worker-threads.html" />
   <id>tag:www.jollen.org,2011:/blog//2.738</id>
   
   <published>2011-05-01T14:36:40Z</published>
   <updated>2011-05-01T21:10:10Z</updated>
   
   <summary>這是 Android 官方「Dev Guide」裡提到的重要級觀念，但經常被忽略，因此在這裡做個簡單的說明。 許多 Android 應用程式經常發生「undefined」與「unexpected」的錯誤，很多錯誤的起因都是違反了這個觀念。在 Android Dev Guide 裡提到，每一個 Android process 都有一個「UI thread」負責處理 UI 事件，為了避免 ANR，應用程式開發者應該建立 Java thread 來執行像是 long operation 等的工作，由應用程式自行產生的 thread，稱為「worker thread」。Worker thread 有時也稱為 secondary thread 或 child thread。但問題發生了，一些應用程式在 woker thread 裡操作 Android UI toolkit。 所謂的...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[這是 Android 官方「Dev Guide」裡提到的重要級觀念，但經常被忽略，因此在這裡做個簡單的說明。

許多 Android 應用程式經常發生「undefined」與「unexpected」的錯誤，很多錯誤的起因都是違反了這個觀念。在 Android Dev Guide 裡提到，每一個 Android process 都有一個「UI thread」負責處理 UI 事件，為了避免 ANR，應用程式開發者應該建立 Java thread 來執行像是 long operation 等的工作，由應用程式自行產生的 thread，稱為「worker thread」。Worker thread 有時也稱為 secondary thread 或 child thread。但問題發生了，一些應用程式在 woker thread 裡操作 Android UI toolkit。

所謂的 Android UI tookit 就是 android.widget 與 android.view 二個 package。以下是 Dev Guide 上的範例片斷：

<pre>
public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            Bitmap b = loadImageFromNetwork("http://example.com/image.png");
            mImageView.setImageBitmap(b);
        }
    }).start();
}</pre>
(Source: Android Dev Guide)

範例中的 mImageView 物件就是 android.widget.ImageView。這是不對的寫法。根據 Dev Guide 上的說明，採用以下的方式可修正此問題：

<ul>
<li>Activity.runOnUiThread(Runnable)</li>
<li>View.post(Runnable)</li>
<li>View.postDelayed(Runnable, long)</li>
</ul>

使用 View.post() 將 'Runnable' 放到 message queue 裡即可解決此問題。Message queue 裡的 'Runnable' 會在 UI thread 上執行。

<em>Android Leak 開發解密系列，整理自 Jollen 過去在 Android 領域的經驗，以「Do & Don't Do」形式分享一些重要但常被略的開發觀念。轉載請全文引用，並註明出處 (Jollen's Blog, <a href="http://www.jollen.org/blog">http://www.jollen.org/blog</a>)，謝謝您對數位內容著作權的支持。</em>]]>
      
   </content>
</entry>
<entry>
   <title>矽島論壇(2011.04)，Honeycomb到位：Android成為平板作業系統的關鍵特色</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/04/many-important-features-of-honeycomb.html" />
   <id>tag:www.jollen.org,2011:/blog//2.737</id>
   
   <published>2011-04-09T04:12:14Z</published>
   <updated>2011-04-09T09:14:34Z</updated>
   
   <summary>Honeycomb到位：Android成為平板作業系統的關鍵特色 多項重要技術的推出，讓Honeycomb成為真正的平板電腦作業系統。 文／Jollen Chen（原文刊載於零組件雜誌2011年4月份） 一場iPad 2的發表會上，賈伯斯以「copycats」來形容Android平板電腦大軍，著實給了一記當頭棒喝。不過這也是事實。在iPad取得大成功後，Android大軍很快地轉向了平板電腦市場。原本定位在智慧型手機的Android 2.0作業系統，也開始進行專門針對平板電腦的版本開發。如今，Android 3.0平板電腦終於正式開賣了，讓我們從技術角度來看，讓Android成為真正平板作業系統的是哪些關鍵特色。 首先，不得不提的重要技術就是「多核心支援」，這是Android 3.0的重要特色，也是Android首次支援多核心架構。Android 3.0在Dalvik VM與Bionic均做了修改，讓Android能開始支援多核心，讓Android在雙核心的Cortex-A9處理器上可以有更好的表現。 第二，新的UI框架，這是Android 3.0的重點。Android 3.0開發的目的是為了支援較大的螢幕，例如：平板電腦。因此，Android 3.0在UI框架方面做了大幅度的修改。例如：加入了Fragments功能。Fragments，這個新的設計，可以將Activity切割成不同的subcomponent，可應用在需要「multipane」的UI開發上。在iPad上也常見此類型的應用程式。 第三，Animation與Clipboard也是Android 3.0的更新重點。為了讓UI操作有更佳的體驗，Android 3.0加入了全新的動畫框架。針對「平板」的使用特性，Android 3.0加了新的Clipboard框架，即剪貼功能。從產品的角度來看，Clipboard是平板電腦的一項重要功能，它讓應用開發者可以為自已的應用程式加入基本的編輯功能。過去在中小尺吋的手機產品上，要讓應用程式提供基本的編輯功能並不是很方便，因此手機軟體是以「操作」為主；現在，在大尺吋的Android平板上，已經能加入基本的編輯功能了。 最後，3D運算也是Android 3.0平板的重要功能。除了支援更佳的硬體加速外，Android 3.0還加入了一項稱之為Renderscript的技術。透過Renderscript技術，應用程式開發者可以很方便地以撰寫script的方式進行3D運算；Renderscript被儲存為*.rs檔案，並且透過Android SDK開發工具編譯為bytecode形式，並打包在*.apk裡。 Renderscript是為了高效能的3D rendering與運算所開發的技術。Renderscript的語法非常類似C語言（實際上是C99標準），透過這項技術，開發者可開發更有視覺效果的平板軟體；例如，電子書軟體，可能就會大量採用這項技術。Renderscript的技術其實早在Android 2.1（Eclair）就已存在，當時的Renderscript技術尚未發展更熟，編譯器也是基於acc來發展，因此較沒有被重視。 如今，Honeycomb已經有發展成熟的Renderscript技術，也改用效能較佳的LLVM編譯技術，Renderscript API與相關開發工具也已經公開在Android 3.0 SDK裡，想見未來Honeybom平板電腦將有比Android手機更豐富的視覺效果。 另外，Android 2.3/3.0的區隔，可以從技術面來看。Android 2.x針對中小尺吋螢幕的應用，例如：手機；Android 3.0針對大尺吋螢幕的應用，例如：平板電腦。中小尺吋與大尺吋的分界技術上沒有明顯的界線，從產品的角度來看，一般認為是以7吋做為分界。 因此，使用10吋面板的Android平板電腦，就採用Android 3.0作業系統。 從產品面來看，以單核心為主的產品或中小尺吋裝置，仍會使用Android 2.3；以多核心為主的產品，或大尺吋裝置，將會採用Android 3.0作業系統。未來的產品開發，將是Android...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<h2>Honeycomb到位：Android成為平板作業系統的關鍵特色</h2>
<h3>多項重要技術的推出，讓Honeycomb成為真正的平板電腦作業系統。</h3>

文／Jollen Chen（原文刊載於零組件雜誌2011年4月份）

一場iPad 2的發表會上，賈伯斯以「copycats」來形容Android平板電腦大軍，著實給了一記當頭棒喝。不過這也是事實。在iPad取得大成功後，Android大軍很快地轉向了平板電腦市場。原本定位在智慧型手機的Android 2.0作業系統，也開始進行專門針對平板電腦的版本開發。如今，Android 3.0平板電腦終於正式開賣了，讓我們從技術角度來看，讓Android成為真正平板作業系統的是哪些關鍵特色。

首先，不得不提的重要技術就是「多核心支援」，這是Android 3.0的重要特色，也是Android首次支援多核心架構。Android 3.0在Dalvik VM與Bionic均做了修改，讓Android能開始支援多核心，讓Android在雙核心的Cortex-A9處理器上可以有更好的表現。

第二，新的UI框架，這是Android 3.0的重點。Android 3.0開發的目的是為了支援較大的螢幕，例如：平板電腦。因此，Android 3.0在UI框架方面做了大幅度的修改。例如：加入了Fragments功能。Fragments，這個新的設計，可以將Activity切割成不同的subcomponent，可應用在需要「multipane」的UI開發上。在iPad上也常見此類型的應用程式。

第三，Animation與Clipboard也是Android 3.0的更新重點。為了讓UI操作有更佳的體驗，Android 3.0加入了全新的動畫框架。針對「平板」的使用特性，Android 3.0加了新的Clipboard框架，即剪貼功能。從產品的角度來看，Clipboard是平板電腦的一項重要功能，它讓應用開發者可以為自已的應用程式加入基本的編輯功能。過去在中小尺吋的手機產品上，要讓應用程式提供基本的編輯功能並不是很方便，因此手機軟體是以「操作」為主；現在，在大尺吋的Android平板上，已經能加入基本的編輯功能了。

最後，3D運算也是Android 3.0平板的重要功能。除了支援更佳的硬體加速外，Android 3.0還加入了一項稱之為Renderscript的技術。透過Renderscript技術，應用程式開發者可以很方便地以撰寫script的方式進行3D運算；Renderscript被儲存為*.rs檔案，並且透過Android SDK開發工具編譯為bytecode形式，並打包在*.apk裡。

Renderscript是為了高效能的3D rendering與運算所開發的技術。Renderscript的語法非常類似C語言（實際上是C99標準），透過這項技術，開發者可開發更有視覺效果的平板軟體；例如，電子書軟體，可能就會大量採用這項技術。Renderscript的技術其實早在Android 2.1（Eclair）就已存在，當時的Renderscript技術尚未發展更熟，編譯器也是基於acc來發展，因此較沒有被重視。

如今，Honeycomb已經有發展成熟的Renderscript技術，也改用效能較佳的LLVM編譯技術，Renderscript API與相關開發工具也已經公開在Android 3.0 SDK裡，想見未來Honeybom平板電腦將有比Android手機更豐富的視覺效果。

另外，Android 2.3/3.0的區隔，可以從技術面來看。Android 2.x針對中小尺吋螢幕的應用，例如：手機；Android 3.0針對大尺吋螢幕的應用，例如：平板電腦。中小尺吋與大尺吋的分界技術上沒有明顯的界線，從產品的角度來看，一般認為是以7吋做為分界。

因此，使用10吋面板的Android平板電腦，就採用Android 3.0作業系統。 從產品面來看，以單核心為主的產品或中小尺吋裝置，仍會使用Android 2.3；以多核心為主的產品，或大尺吋裝置，將會採用Android 3.0作業系統。未來的產品開發，將是Android 2.3/3.0並行。

另一個值得一提的非技術面議題是，「Android註冊商標的使用權未來可能也會更有規範」。這從Android 3.0將可能「更晚」推出AOSP找到線索。目前，Google採取CTS（Compatibility Test Suite）的做法來規範「Android」註冊商標使用權，未能通過CTS測試的裝置，都不能自稱為Android裝置。這項做法其實是很令人肯定的。CTS可以保障產品的技術品質，沒有通過品質測試的產品，若以Android裝置名義上市，使用者若產生不好的觀感，對Android的名聲也是一種打擊。

Renderscript技術、新的UI框架、新的Animation框架、Clipboard功能、Multipane UI、支援多核心ARM等重要技術，讓Honeycomb成為真正的平板電腦作業系統。]]>
      
   </content>
</entry>
<entry>
   <title>矽島論壇（2011.03）：解析 Android 今年的重要技術發展</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/03/android-in-2011-technology.html" />
   <id>tag:www.jollen.org,2011:/blog//2.736</id>
   
   <published>2011-03-30T15:10:21Z</published>
   <updated>2011-03-30T21:18:38Z</updated>
   
   <summary>（原文刊載於零組件雜誌2011年3月） 今年是智慧型手機與平板電腦的大年，重量級的國際品牌，幾乎都已進入這個戰場。除了應用處理器與面板外，還有幾個重要的關鍵零組件，包括：DRAM、FLASH與感測元件，也是觀察要點。軟體部份，近期最令人感興趣的莫過於 Nokia 事件，若 Nokia 確定投靠微軟陣營，對Symbian與 MeeGo的影響力無非是一個重傷害，Android也確定會成為主角。讓我們來「細看」這個主角幾個重要的發展藍圖。 第一、強化Web Application支援性，過去也在本論壇裡介紹過的Mobile Widget也是相同的技術。Mobile Widget是OPhone作業系統提供的特色，從各版本的Android發展歷程顯示，Web Application的支援將是未來重要的發展重心。基於WebView元件所打造的Web Application功能，是未來重要的手機應用軟體技術。 第二、視窗化。Android 2.x作業系統的應用程式，採取「瀏灠式」的架構，也就是每個應用程式的畫面，就像是一張「頁面」。在手機上操作應用程式，就好像在閱讀並切換頁面。針對較大螢幕的產品來說，「視窗式」瀏灠比較能符合過去使用者的習慣，也較為適合「多工式」作業系統。因此，Android3.x作業系統加入了視窗化的架構，讓使用者可以同時操作多個「視窗」而非頁面。 不過，Mac OS的發展趨勢做法有點不同。使用在MacBook Air上的作業系統是視窗式瀏覽，使用在iPad上的作業系統除了採取頁面式瀏灠外，也加入許多「平板專用特色」。現在，這些特色將被移植到MacBook Air產品裡，讓平板專用特色也能在「個人電腦」型的產品上使用。 第三、SDK。產品開發化將提供自有特色的API成為重要特色。在 Android 2.3 SDK 裡，大家都能發現「Samsung Mobile Add-ons」，這是Samsung針對Galaxy系列產品所開發的API，使用這些API能開發自有特色的應用程式。在Android作業系統框架裡加入API，並提供客製化的SDK並非難事。但重點不在於如何製作客製化SDK，而是在「讓API突顯硬體特色」。 第四、Native 化。客製化API目的是呈現產品特色，因此軟硬整合技術是關鍵。客製化API另一個目的是提供給「開發者」，因此API的「意圖」尤為重要。從軟硬整合的角度來看，Android將會有更大幅度的更新，特別是「Native 化」。Android 2.3 在部份硬體單元（Component）做了一些架構調整。隨著 AOSP 程式碼的大幅進步，硬體廠需要加強對 Android HAL 的技術掌握度。 為什麼在過去的 Android OS 裡，HAL...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      （原文刊載於零組件雜誌2011年3月）

今年是智慧型手機與平板電腦的大年，重量級的國際品牌，幾乎都已進入這個戰場。除了應用處理器與面板外，還有幾個重要的關鍵零組件，包括：DRAM、FLASH與感測元件，也是觀察要點。軟體部份，近期最令人感興趣的莫過於 Nokia 事件，若 Nokia 確定投靠微軟陣營，對Symbian與 MeeGo的影響力無非是一個重傷害，Android也確定會成為主角。讓我們來「細看」這個主角幾個重要的發展藍圖。

第一、強化Web Application支援性，過去也在本論壇裡介紹過的Mobile Widget也是相同的技術。Mobile Widget是OPhone作業系統提供的特色，從各版本的Android發展歷程顯示，Web Application的支援將是未來重要的發展重心。基於WebView元件所打造的Web Application功能，是未來重要的手機應用軟體技術。

第二、視窗化。Android 2.x作業系統的應用程式，採取「瀏灠式」的架構，也就是每個應用程式的畫面，就像是一張「頁面」。在手機上操作應用程式，就好像在閱讀並切換頁面。針對較大螢幕的產品來說，「視窗式」瀏灠比較能符合過去使用者的習慣，也較為適合「多工式」作業系統。因此，Android3.x作業系統加入了視窗化的架構，讓使用者可以同時操作多個「視窗」而非頁面。

不過，Mac OS的發展趨勢做法有點不同。使用在MacBook Air上的作業系統是視窗式瀏覽，使用在iPad上的作業系統除了採取頁面式瀏灠外，也加入許多「平板專用特色」。現在，這些特色將被移植到MacBook Air產品裡，讓平板專用特色也能在「個人電腦」型的產品上使用。

第三、SDK。產品開發化將提供自有特色的API成為重要特色。在 Android 2.3 SDK 裡，大家都能發現「Samsung Mobile Add-ons」，這是Samsung針對Galaxy系列產品所開發的API，使用這些API能開發自有特色的應用程式。在Android作業系統框架裡加入API，並提供客製化的SDK並非難事。但重點不在於如何製作客製化SDK，而是在「讓API突顯硬體特色」。

第四、Native 化。客製化API目的是呈現產品特色，因此軟硬整合技術是關鍵。客製化API另一個目的是提供給「開發者」，因此API的「意圖」尤為重要。從軟硬整合的角度來看，Android將會有更大幅度的更新，特別是「Native 化」。Android 2.3 在部份硬體單元（Component）做了一些架構調整。隨著 AOSP 程式碼的大幅進步，硬體廠需要加強對 Android HAL 的技術掌握度。

為什麼在過去的 Android OS 裡，HAL 的架構或程式碼如此陽春？簡單講，「就是還沒有發展成熟。」但今年Android將會有大幅度的進展。Android 應用程式存取硬體的做法，大致分為二個路徑：Android Service 與 Native Service。Native Service往上的架構是Application Service，Application Service是一個統稱，目的就是提供API。

最後、封閉源碼。這點是過去不斷討論到的觀念。雖然Google透過AOSP（Android Open Source Project）提供Android程式碼，但有更多的私有程式碼是由各家廠商所發展，因此現象是「更多的實作都是封閉源碼」，AOSP上的程式碼最多只是參考實作。廠商想要更早推出產品，等待AOSP並不是好辦法，因為實作的時間不容易評估，也處於完全被動狀態。Android 在技術與產業的變化有時還真摸不著頭緒，例如：Nokia 過去在 Android 作業框架的「貢獻度」也是榜上有名的，今年將是精采又奇妙的一年。
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android HAL 技術解析, #9: 理想中的完整架構</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/02/android-hal-complate-architecture-outlook.html" />
   <id>tag:www.jollen.org,2011:/blog//2.735</id>
   
   <published>2011-02-21T13:15:36Z</published>
   <updated>2011-02-21T20:33:29Z</updated>
   
   <summary>一年多前，「Android 的 HAL 技術」系列日記闡釋了 Android HAL 的觀念與基本設計方法；在小弟的「Android HAL &amp; Framework: 軟硬整合實作訓練 」訓練規劃中，也對 Android Service 與 HAL 做了完整的介紹。 現在，再度回到 Android HAL 的主題；主要是 Android 2.3 在部份硬體單元（Component）做了一些架構調整。隨著 AOSP 程式碼的大幅進步，硬體廠需要加強對 Android HAL 的技術掌握度，這是十萬火急的工作了。因為，硬體廠唯有具備發展高品質軟硬整合程式碼的能力，才能在 Android 產品開發工作上具備競爭力。 「Native 化」 過去在「Android 的 HAL 技術, #3: 小探Android Service與Native...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[一年多前，「<a href="http://www.jollen.org/blog/android_os/">Android 的 HAL 技術</a>」系列日記闡釋了 Android HAL 的觀念與基本設計方法；在小弟的「Android HAL & Framework: 軟硬整合實作訓練 」訓練規劃中，也對 Android Service 與 HAL 做了完整的介紹。

現在，再度回到 Android HAL 的主題；主要是 Android 2.3 在部份硬體單元（Component）做了一些架構調整。隨著 AOSP 程式碼的大幅進步，硬體廠需要加強對 Android HAL 的技術掌握度，這是十萬火急的工作了。因為，硬體廠唯有具備發展高品質軟硬整合程式碼的能力，才能在 Android 產品開發工作上具備競爭力。

<strong>「Native 化」</strong>

過去在「<a href="http://www.jollen.org/blog/2009/11/android-hal-android-native-service.html">Android 的 HAL 技術, #3: 小探Android Service與Native Service</a>」裡提及 Android 應用程式存取硬體的做法，大致分為二個路徑：Android Service 與 Native Service。在「Android HAL & Framework: 軟硬整合實作訓練 」裡，分別以「紅色路徑」與「綠色路徑」來表示。

在日記「<a href="http://www.jollen.org/blog/2011/01/andriod-23-sensorservice-native.html">Android 2.3 的更新：SensorService 的 Native 化</a>」裡提到的「Native 化」會成為日後 Android 作業系統發展的趨勢之一。「也就是紅色路徑慢慢往綠色路徑移動」。

<strong>理想中的 Android HAL 架構</strong>

要了解這項發展趨勢，可以從理想中的 Android HAL 架構說起，先在腦海裡建立大方向圖（Big Picture）。根據 Android 各版本的發展，可以推測出 Android HAL 將朝向下圖的架構來發展。

這個架構不是憑空想像，事實上也不是 Android 作業系統的創舉。

研究作業系統的朋友可以知道，Hardware Abstraction Layer (HAL) 的觀念已經行之多年了，在許多重量級的 OS 裡都能看到。為什麼在過去的 Android OS 裡，HAL 的架構或程式碼如此陽春？簡單講，「就是還沒有發展成熟。」

<img src="http://www.jollen.org/blog/2011/02/21/a-complete-android-hal-architect.png" />
圖一：理想且完整的 Android HAL 架構

根據我們的研究，理想中且完善的 Android HAL 架構包含四個部份：

<ul>
 <li>Service Layer 屬於 Application Framework 層，提供 Application 存取硬體的「服務」。理論上，這些服務是以 instance 的形式存在。</li>
 <li>Hardware Abstraction Layer 介於 Application Framework 與 Driver Framework 之間，以抽象形式存取硬體。理論上，HAL 層的存在形式有三種 - library (module) / server / communication bus。</li>
 <li>Native Servier 屬於整個 Android 作業系統最底層。理論上，它應該在 HAL 層之下，也是 HAL 不會是我們想像中「隔絕 kernel 的最下層」，存在形式為 daemon。
 <li>Driver Framework 屬於 kernel-space 層，也就是包含在 Linux kernel 裡，「非常 long-term 來看」也可以是其它 OS。理論上，Driver Framework 是以 instance 的形式存在。
</ul>

Service Layer 實作在 Application Framework 層，為了提供更上層（Application）存取硬體而設計，因此，在有些研究上，也稱之為「Application Service」；等同於過去我們所講的 Android Service。Application Service 最多就是提供 API 而已。

這個架構並非一種創新，因為在許多重量級的作業系統裡都能看到這樣的設計，例如：Mac OS X。統一架構，讓硬體存取一致化，實作整齊劃一。不過，以上的觀點都只是理論，目的是推測 Android 在這個部份的發展輪廓。

實務上，看到的程式碼與理論研究總是有點落差。現行的 AOSP 程式碼實作，還是與我們所討論的架構不一樣；至於未來如何發展，只能密切與 AOSP 同步。螢幕上的程式碼，背後總是有許多思惟邏輯，有些能從程式碼推敲一二，更多則是沒有文獻記載，技術研究的樂趣在於發覺這些內涵。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android Leak 開發解密, #2: Play Music in Secondary Thread</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/01/android-leak-2-play-music-secondary-thread.html" />
   <id>tag:www.jollen.org,2011:/blog//2.734</id>
   
   <published>2011-01-11T11:05:11Z</published>
   <updated>2011-01-11T17:52:40Z</updated>
   
   <summary>根據先前所討論過的觀念，我們把 &quot;play&quot; music 的功能設計在 secondary thread 裡。Android SDK 使用 java.lang.Thread 來建立 thread，使用 secondary thread 來產生 MediaPlayer 的 instance，並撥放音樂。Music Player v2 設計圖如下： 圖一：Music Player v2 設計 針對 Music Player 個案，因為 MediaPlayer.create() 是以同步 (Synchronous) 方式準備 MediaPlayer，所以有出現 ANR 的機會。在早期 (2008 年) 的 MediaPlayer...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[根據先前所討論過的觀念，我們把 "play" music 的功能設計在 secondary thread 裡。Android SDK 使用 java.lang.Thread 來建立 thread，使用 secondary thread 來產生 MediaPlayer 的 instance，並撥放音樂。Music Player v2 設計圖如下：

<img alt="musicplayer-v2-threading.png" src="http://www.jollen.org/blog/2011/01/11/musicplayer-v2-threading.png" width="666" height="472" />
圖一：Music Player v2 設計

針對 Music Player 個案，因為 MediaPlayer.create() 是以同步 (Synchronous) 方式準備 MediaPlayer，所以有出現 ANR 的機會。在早期 (2008 年) 的 MediaPlayer 設計中，因為 .create() 的實作上有點問題，遇到比較大的音樂檔時，.create() 花費的時間可能較久，形成一個 long operation。雖然後續版本已經改善這個問題，不過如果我們的資料來源不是檔案 (file) 的話，對 UI 就會有很不好的影響。

因此，採用 secondary thread 的方式來把 Music Player 設計的更好，避免可能產生的問題。這個範例衍生的議題是關於 association 的設計。假設我們想在「撥完音樂後」回報 MusicPlayerUI，我們可以讓 secondary thread 以 callback 方式回報 MusicPlayerUI，不過這不是一個好設計。

Music Player v2 的設計，MusicPlayerUI 成為一個 navigable object，意思是，實作上，我們可能會採取以下的實作（pseudo code）：

Thread thr = new Thread(this);

因為不理想，所以暫時不進行程式碼實作。現在，我們已經將撥音樂的動作放到 secondary thread 裡了，接下來我們會想重構 association 的設計。

<em>Android Leak 開發解密系列，整理自 Jollen 過去在 Android 領域的經驗，以「Do & Don't Do」形式分享一些重要但常被略的開發觀念。轉載請全文引用，並註明出處 (Jollen's Blog, <a href="http://www.jollen.org/blog">http://www.jollen.org/blog</a>)，謝謝您對數位內容著作權的支持。</em>]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android Leak 開發解密, #1: Dont&apos; Play Music in UI Thread</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/01/android-leak-1-dont-in-ui-thread.html" />
   <id>tag:www.jollen.org,2011:/blog//2.733</id>
   
   <published>2011-01-10T07:20:11Z</published>
   <updated>2011-01-11T18:14:59Z</updated>
   
   <summary>設計音樂撥放器應用程式時，如何正確地進行「Play Music」的動作？在按下 Button 後立即進行音樂撥放，是可行 (work) 的做法，但卻不建議這樣設計。在類似 onButtonPressed() 的 event callback 裡直接撥音樂會有「UI 成本」產生，意思是可能對 UI 反應造成不利影響。 設計一個簡單的 Music Player 界面如下： 圖一：Music Player 以 Android SDK 2.3 為例，我們可使用 android.view.View.OnClickListener 以及 android.media.MediaPlayer 設計出「不建議」的音樂撥放器。 圖二：Bad Design: Music Player v1 以下以 pseudo code 呈現圖二的實作： public class...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[設計音樂撥放器應用程式時，如何正確地進行「Play Music」的動作？在按下 Button 後立即進行音樂撥放，是可行 (work) 的做法，但卻不建議這樣設計。在類似 <em>onButtonPressed()</em> 的 event callback 裡直接撥音樂會有「UI 成本」產生，意思是可能對 UI 反應造成不利影響。

設計一個簡單的 Music Player 界面如下：

<img alt="musicplayer-v1-ui.png" src="http://www.jollen.org/blog/2011/01/10/musicplayer-v1-ui.png" width="320" height="480" />
圖一：Music Player

以 Android SDK 2.3 為例，我們可使用 android.view.View.OnClickListener 以及 android.media.MediaPlayer 設計出「不建議」的音樂撥放器。

<img alt="musicplayer-v1-ood.gif" src="http://www.jollen.org/blog/2011/01/10/musicplayer-v1-ood.gif" width="676" height="327" />
圖二：Bad Design: Music Player v1

<font color="#ff0000">以下以 pseudo code 呈現圖二的實作：</font>

<pre>
public class MusicPlayerUI extends Activity implements OnClickListener {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
　
        Button playBtn = (Button) findViewById(R.id.playBtn);
        Button stopBtn = (Button) findViewById(R.id.playBtn);
　
        playBtn.setOnClickListener(this);
        stopBtn.setOnClickListener(this);
    }
　
	public void onClick(View v) {
		Access Audio Hardware and get it ready.
		Control Audio Hardware and start music.
	}
}
</pre>

以 MediaPlayer 來實作音樂撥放功能，完整程式碼片斷如下：

<pre>
public class MusicPlayerUI extends Activity implements OnClickListener {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
　
        Button playBtn = (Button) findViewById(R.id.playBtn);
        Button stopBtn = (Button) findViewById(R.id.playBtn);
　
        playBtn.setOnClickListener(this);
        stopBtn.setOnClickListener(this);
    }
　
	public void onClick(View v) {
		// TODO Auto-generated method stub
		MediaPlayer p = MediaPlayer.create(this, R.raw.test);
		p.start();
	}
}
</pre>

在了解 Android Process 模式後會發現，在 UI thread 裡做撥音樂的動作，會對 UI 反應有不利影響。<font color="#ff0000">以 MediaPlayer.create() 為例，在實例化 MediaPlayer 時，會去讀取音樂檔，並預先將檔案準備好，這個動作由 .prepare() 完成。由於 .prepare() 是同步式的實作，所以在 UI thread 裡不適合進行這項操作。</font>

一般來說，我們不會在 UI thread 裡做控制（control）或硬體存取（hardware access）的操作。我們將利用以下二種方式來設計 Music Player：

1. 使用 secondary thread 執行「撥」的動作
2. 使用 separated process 執行「撥」的動作

Secondary thread 指的是由應用程式本身建立的 thread；由系統自動建立的 thread 稱為 main thread。在設計 iPhone 應用程式，或是撰寫 C# 時，也經常使用到 main thread 與 secondary thread 的觀念。Don't play music in UI thread 可說是通識觀念。Android Leak #2 將說明 how to do。

<strong>Revision history</strong>

* 2011.1.11: 加入一段 pseudo code 輔助說明。根據網友 allstars 的意見，加強 MediaPlayer 例子說明，之前寫得太簡單，造成困擾了，sorry!

<em>Android Leak 開發解密系列，整理自 Jollen 過去在 Android 領域的經驗，以「Do & Don't Do」形式分享一些重要但常被略的開發觀念。轉載請全文引用，並註明出處 (Jollen's Blog, <a href="http://www.jollen.org/blog">http://www.jollen.org/blog</a>)，謝謝您對數位內容著作權的支持。</em>]]>
      
   </content>
</entry>
<entry>
   <title>Dalvik VM 與 JVM 差異比較：Zygote 與 Class Preload</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/01/dalvik-vm-jvm-zygote-class-preload.html" />
   <id>tag:www.jollen.org,2011:/blog//2.732</id>
   
   <published>2011-01-04T02:34:20Z</published>
   <updated>2011-01-04T17:12:12Z</updated>
   
   <summary>Android 2.3 框架源碼釋出後，開始有必要對 Dalvik VM 做深入的研究。建議可以由 Dalvik VM 與 Java VM 的差異起步。Dalvik VM 與 Java VM 雖然字面上都是「Java 虛擬機」，但內部設計並不完全相同，存在一些差異。最中最重要的差異，就是 Dalvik VM 加入了 Zygote 的設計。 在過去許多的演講場合，不斷提到 Zygote 的觀念，在 [Jollen 的 Android 觀念解析, #1: Zygote Mode] 日記裡也曾簡要提及。Zygote 負責幾項重要的工作： 1. Listening Socket (Forking child...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Android 2.3 框架源碼釋出後，開始有必要對 Dalvik VM 做深入的研究。建議可以由 Dalvik VM 與 Java VM 的差異起步。Dalvik VM 與 Java VM 雖然字面上都是「Java 虛擬機」，但內部設計並不完全相同，存在一些差異。最中最重要的差異，就是 Dalvik VM 加入了 Zygote 的設計。

在過去許多的演講場合，不斷提到 Zygote 的觀念，在 [<a href="http://www.jollen.org/blog/2010/04/android-concept-1-zygote-mode.html">Jollen 的 Android 觀念解析, #1: Zygote Mode</a>] 日記裡也曾簡要提及。Zygote 負責幾項重要的工作：

1. Listening Socket (Forking child process)
2. Preload Resource
3. Preload Class
4. Start System Server
5. Enter Zygote Fork Mode

與 JVM 最大的不同是，Dalvik VM 透過 Zygote 進行「Class Preloading」。意思是，把絕大部份的「Java class file」載入記憶體。Java class file 被打包成 *.jar 檔，Java class file 就是 Java library，提供 Android 應用程式與框架所需的 API。Zygote 所載入的 class file，幾乎包含所有的 API，當然，大部份自已都用不到，因此稱之為「preload」，也就是「預載」。透過 preload，讓 Android 應用程式在載入時，不需要重覆「class loading」的動作，除了加快應用程式啟動速度外，也達到許多效果。

Class preloading 是 Dalvik VM 最重要的特色之一，也是與 JVM 不同之處。Class preloading 是在 Android 裝置開機時進行，可能產生的不良效應之一就是「開機變慢」，不過，已經有一些方法可以解決這個問題。在了解 Dalvik VM 與 Zygote 後，便能開始深入 Dalvik VM 的 heap 原理。]]>
      
   </content>
</entry>
<entry>
   <title>Android 2.3 的更新：SensorService 的「Native 化」</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/01/andriod-23-sensorservice-native.html" />
   <id>tag:www.jollen.org,2011:/blog//2.731</id>
   
   <published>2011-01-03T08:45:07Z</published>
   <updated>2011-01-03T14:59:03Z</updated>
   
   <summary>近期在進行 Android 2.3 的新框架程式碼研究，Android 2.3 在 Platform (Framework) 部份包含了許多重大的更新，其中一個部份就是 SensorService 改寫成 Native Service 形式。在 Android 2.2 以前的框架，SensorService 包含在 SystemServer 裡，實務上，可能也會對 SensorService 做小幅度改寫，以增進效能，或是將 SensorService 獨立成為一個 process。 在 Android 2.3 裡的 SystemServer 已經找不到 SensorService 了，這個重要的 Android Service 被改寫成 Native Service。「如何將 Android Service...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[近期在進行 Android 2.3 的新框架程式碼研究，Android 2.3 在 Platform (Framework) 部份包含了許多重大的更新，其中一個部份就是 SensorService 改寫成 Native Service 形式。在 Android 2.2 以前的框架，SensorService 包含在 SystemServer 裡，實務上，可能也會對 SensorService 做小幅度改寫，以增進效能，或是將 SensorService 獨立成為一個 process。

在 Android 2.3 裡的 SystemServer 已經找不到 SensorService 了，這個重要的 Android Service 被改寫成 Native Service。「如何將 Android Service 改寫為 Native Service」，以及「Native Service」的開發，從 Android 2.3 開始，將成為重量級主題。由於本週即將進行「<a href="http://www.moko365.com/training/android-hal-framework-practice" target="_blank">Android HAL & Framework: 軟硬整合實作訓練</a>」課程，利用元旦假期，也順利完成課程以及教材的更新，將開始著重 Native Service 的講解，並透過實例解說 Native Service 的開發。

由於 Android 2.2/2.3 可能是併行的關係，而非取代關係。因此，Android 2.2 以及 Android 2.3 的學習必要性很高；意思是，最好能由 2.1/2.2 的框架開發開始學習。了解 Android 2.1/2.2 的 SensorService 架構，再對 Android 2.3 的 SensorService 進行了解，除了可比較其設計與實作差異外，也能知道「效能改進之道」。了解過去 SensorService 架構與實作上的不足，以及 Android 2.3 的改寫，解決了什麼問題。

Android 2.3 的 libhardware 沒有太大變動。從 Anroid 2.1/2.2 開始的開發者，可以由 Android 2.3 的 SensorService 做為「更新知識」的進入點。]]>
      
   </content>
</entry>
<entry>
   <title>Android 軟體開發的思惟與建議 </title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2011/01/android-software-development.html" />
   <id>tag:www.jollen.org,2011:/blog//2.730</id>
   
   <published>2011-01-03T05:06:18Z</published>
   <updated>2011-01-03T11:08:09Z</updated>
   
   <summary>（原文刊載於零組件雜誌，2010年12月） 2011年是Android揮軍平板電腦的重要一年。 AP+OS+APP主導產品開發，AP（Application Processor）應用處理器是產品主板（PCBA）的靈魂，主要的功能是用來執行作業系統。OS（Operating System）的重要性在於它提供應用軟體的執行環境，並負責驅動主板上的所有硬體。APP（Applications）則是基本作業系統所撰寫的應用程式。 作業系統有近二十年來，不斷蓬勃發展，並採取社群模式開發的Linux kernel。應用程式部份，有Google提供的AOSP（Android Open Source Project）以及Android API標準。應用程式開發者基於標準API撰寫各式有創意的應用程式，產品開發商或硬體製造商，可基於AOSP的架構以及API標準發展產品。對產品開發商的優點是，基於AOSP架構與API標準所發展的產品，可搭載「現有的 Android 應用程式」。意思是，Android Market或第三方來源的各種Android應用軟體，「很早就為我們的產品準備好了」。 因此，AP+OS+APP的產品公式，可等價於AP+Android Application Framework+Developers。這讓產品開發的思惟很不同，但也可以很傳統，取決定產品本身的定義。以下是幾點「很不同」的想法，提供大家參考指教。 第一、Android Application Framework的開發強調「相容性」。這個相容性並不是傳統上的「硬體相容」或是「舊版本軟體相容」，而是「API相容」。如同上述所提，當一個 Android框架無法開發到API相容時，「很可能多數的現成軟體都無法正常執行」。開發Android產品不是只為了硬體，而是要支援網路上「現成的各種軟體」。消費者可能無法接受一個API不相容的Android產品。大部份的應用開發者都基於標準Android SDK做開發，此時，API不相容的產品，會讓這些應用軟體無法執行。因應這個問題，Google提出了CTS套件，希望廠商開發的 Android 框架與產品都可以通過CTS（Compatible Test Suite）測試。 第二、開發軟體是「設計導向思惟」。寫程式（Coding）並不等於做軟體（Software），寫code可以很straight forward，意思是，大家可以通往直前，不受任何限制地自由發揮，程式碼怎麼寫，很自由心證。但是做軟體就很不同了。以Android框架的開發為例，寫code要考慮架構，要先做設計（OOD），要驗證設計的正確性，同時也要達到重用（Design Reuse）框架設計的要求；所以開發Android框架，是在一套系統化且制式的規模下進行，寫code受到規範。過去硬體商寫code是為了驅動硬體，或驗證硬體，現在要擔綱軟體開發的工作，coding的思惟就要改變。 第三、這是開放平台。開放平台（Open Platform）與開源軟體（Free and Open Source Software）是二個概念。開放平台代表開放API給開發者使用，或是開放Platform Builder供製造商使用，製造商很可能無法取得內部的實作源碼（Implementation source），取而代之的是一個configurable的環境。意思是說，AOSP版本的程式碼很可能永遠都是reference code，廠商自已的implementation也不會公開源碼。Android裡的Launcher是reference Launcher，Android裡的rild也只是reference code；大部份implementation是reference...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      （原文刊載於零組件雜誌，2010年12月）

2011年是Android揮軍平板電腦的重要一年。

AP+OS+APP主導產品開發，AP（Application Processor）應用處理器是產品主板（PCBA）的靈魂，主要的功能是用來執行作業系統。OS（Operating System）的重要性在於它提供應用軟體的執行環境，並負責驅動主板上的所有硬體。APP（Applications）則是基本作業系統所撰寫的應用程式。

作業系統有近二十年來，不斷蓬勃發展，並採取社群模式開發的Linux kernel。應用程式部份，有Google提供的AOSP（Android Open Source Project）以及Android API標準。應用程式開發者基於標準API撰寫各式有創意的應用程式，產品開發商或硬體製造商，可基於AOSP的架構以及API標準發展產品。對產品開發商的優點是，基於AOSP架構與API標準所發展的產品，可搭載「現有的 Android 應用程式」。意思是，Android Market或第三方來源的各種Android應用軟體，「很早就為我們的產品準備好了」。

因此，AP+OS+APP的產品公式，可等價於AP+Android Application Framework+Developers。這讓產品開發的思惟很不同，但也可以很傳統，取決定產品本身的定義。以下是幾點「很不同」的想法，提供大家參考指教。

第一、Android Application Framework的開發強調「相容性」。這個相容性並不是傳統上的「硬體相容」或是「舊版本軟體相容」，而是「API相容」。如同上述所提，當一個 Android框架無法開發到API相容時，「很可能多數的現成軟體都無法正常執行」。開發Android產品不是只為了硬體，而是要支援網路上「現成的各種軟體」。消費者可能無法接受一個API不相容的Android產品。大部份的應用開發者都基於標準Android SDK做開發，此時，API不相容的產品，會讓這些應用軟體無法執行。因應這個問題，Google提出了CTS套件，希望廠商開發的 Android 框架與產品都可以通過CTS（Compatible Test Suite）測試。

第二、開發軟體是「設計導向思惟」。寫程式（Coding）並不等於做軟體（Software），寫code可以很straight forward，意思是，大家可以通往直前，不受任何限制地自由發揮，程式碼怎麼寫，很自由心證。但是做軟體就很不同了。以Android框架的開發為例，寫code要考慮架構，要先做設計（OOD），要驗證設計的正確性，同時也要達到重用（Design Reuse）框架設計的要求；所以開發Android框架，是在一套系統化且制式的規模下進行，寫code受到規範。過去硬體商寫code是為了驅動硬體，或驗證硬體，現在要擔綱軟體開發的工作，coding的思惟就要改變。

第三、這是開放平台。開放平台（Open Platform）與開源軟體（Free and Open Source Software）是二個概念。開放平台代表開放API給開發者使用，或是開放Platform Builder供製造商使用，製造商很可能無法取得內部的實作源碼（Implementation source），取而代之的是一個configurable的環境。意思是說，AOSP版本的程式碼很可能永遠都是reference code，廠商自已的implementation也不會公開源碼。Android裡的Launcher是reference Launcher，Android裡的rild也只是reference code；大部份implementation是reference implementation，不是workable或useable code。所以，不能只顧著等候AOSP的釋出，也不能渴望著取得所有的源碼。強化開發能力，動手發展AOSP成為好用的自有版本，才是務實之道。

2011年是Android揮軍平板電腦的重要一年， 要知道製造商在Android的研發儲備能量，這將是重要的觀察指標。
      
   </content>
</entry>
<entry>
   <title>AMOLED 的戰爭，從產品面看二零一一</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/12/amoled-war.html" />
   <id>tag:www.jollen.org,2010:/blog//2.729</id>
   
   <published>2010-12-16T09:54:05Z</published>
   <updated>2010-12-16T20:55:23Z</updated>
   
   <summary>AMOLED 應用在智慧型手機以及移動裝置，明年 (2011) 勢必有大幅的成長，影響力也將更為擴大。面對這個已經成形的趨勢，更值得討論的應該是解決方案，因為 AMOLED 並非不可替代，也不是難以入門；反之，有一點比較另人擔心的是，若經過長時間的媒體曝光，「讓 AMOLED 變成消費者心中的神聖規格」，這才是難以解決的問題。AMOLED 三星公司不是獨家。最關鍵的轉折點在金融海潚時期，因為經費、成本以及產業前景問題，讓這項技術停滯，沒有堅持下去，這是台灣比較可惜的地方。以下是小弟的一些個人看法，請不吝指教，有不合適的地方，也請來函指正。 AMOLED 是 OLED 的一種，適合用在手持裝置，同時也有色彩較鮮艷的優勢，但並不是一種「完美」的技術，當然也有許多缺點；AMOLED 並不神聖；反倒有一點被發展成「必備的手機規格」，成為一種市場行銷名詞。從技術面來看，TFT 與 AMOLED 同樣都是 24-bit 的數位輸出；因此主要的差異在硬體的表現。 從產品規格的角度來看 TFT 與 AMOLED，我們取同一個品牌生產的產品來比較。3.5 吋 TFT 與 AMOLED 的尺吋 (outline) 當然是差不多，高度大約在 86mm 左右，寬度則是 51mm 上下。但厚度則是有比顯的差異，3.5 吋 AMOLED 厚度大約在 1.5 之間，同樣尺吋的 TFT...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="產品開發" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      AMOLED 應用在智慧型手機以及移動裝置，明年 (2011) 勢必有大幅的成長，影響力也將更為擴大。面對這個已經成形的趨勢，更值得討論的應該是解決方案，因為 AMOLED 並非不可替代，也不是難以入門；反之，有一點比較另人擔心的是，若經過長時間的媒體曝光，「讓 AMOLED 變成消費者心中的神聖規格」，這才是難以解決的問題。AMOLED 三星公司不是獨家。最關鍵的轉折點在金融海潚時期，因為經費、成本以及產業前景問題，讓這項技術停滯，沒有堅持下去，這是台灣比較可惜的地方。以下是小弟的一些個人看法，請不吝指教，有不合適的地方，也請來函指正。

AMOLED 是 OLED 的一種，適合用在手持裝置，同時也有色彩較鮮艷的優勢，但並不是一種「完美」的技術，當然也有許多缺點；AMOLED 並不神聖；反倒有一點被發展成「必備的手機規格」，成為一種市場行銷名詞。從技術面來看，TFT 與 AMOLED 同樣都是 24-bit 的數位輸出；因此主要的差異在硬體的表現。

從產品規格的角度來看 TFT 與 AMOLED，我們取同一個品牌生產的產品來比較。3.5 吋 TFT 與 AMOLED 的尺吋 (outline) 當然是差不多，高度大約在 86mm 左右，寬度則是 51mm 上下。但厚度則是有比顯的差異，3.5 吋 AMOLED 厚度大約在 1.5 之間，同樣尺吋的 TFT 則是大約在 2.0。因此，設計薄型手機時，初步會選用 AMOLED。亮度方面，這款 3.5&quot; TFT 的單位亮度為 380 (cd/m2)，同品牌尺吋的 AMOLED 則是 300 (cd/m2)，與典型亮度相差不多。

但是對比度就有比較大的差異了。這款 AMOLED 的對比度為 2000， 同品牌尺吋的 TFT 則是 1000。對比度越高，顏色的漸變層次越明顯，這就是為什麼 AMOLED 會讓人感覺到色彩較鮮艷的原因。TFT 的對比度隨著尺吋越大，對比度可能變低，例如同品牌的 7 吋 TFT 對比度只有 700；但同樣 7 吋 AMOLED 對比度則是「破萬」。實際上，目前 AMOLED 的滲透率並不算高，因此，2010 年才是 AMOLED 真正的「元年」。從產品規格的角度來看，戰線將從智慧型手機延伸到平板電腦，特別是採用 7 吋 AMOLED 高鮮艷色彩的平板電腦，這會是重要的決戰點。7 吋 AMOLED 的厚度大約在 1.0 左右，比 3.5 吋的 AMOLED 更「薄」。

另外，供應鍊的關鍵在於，小尺吋 AMOLED 的產能幾乎都由三星開出 (SMD)，台灣的產能初期落差較大。目前 SMD 的月產能為 300 萬片，2011 年中 (Q2)，將達到 3000 萬片，可望解決目前量產不足的問題，各大手機品牌將可望導入至產品。可以確認的是，AMOLED 明年的強烈需求，將從手機延伸到平板電腦，也就是，3.5~4.2 吋與 7 吋的二種主流規格。三星藉由 AMOLED 搶攻智慧型手機市場的戰略已經很清楚了，其它手機品牌是否能取得 AMOLED 供貨，關鍵在 SMD 公司這 3000 萬片的月產能，是否能滿足三星自家需求。7 吋平板電腦市場，今年三星已經開始佈局了， 是否再以 7 吋 AMOLED 攻城掠地，相當值得觀察。

從這個角度來看，AMOLED 的關鍵似乎不在技術問題，而是產能問題。「今年六月宏達電曾推出一款手機Legend，就是採用AMOLED面板，上市時雖然頗受好評，但才賣了不到三個月就面臨斷貨問題，幕後的操控者就是三星。 『三星對我們總量管制！』一位宏達電主管氣憤表示。」（引述自商業周刊）。台灣要急起直追的機會是非常高的，友達就擁有 AMOLED 的相關專利。戰略上可以採取自創規格的方式，而不是「跟進規格」，4.2 到 4.8 吋的 WVGA 可能是一個不錯的規格，因為在 TFT 規格上，這樣的尺吋已經慢慢被消費者接受，喜愛度也慢慢提升。
      
   </content>
</entry>
<entry>
   <title>Android 2.3 終於來囉：新的多媒體框架、NFC、NativeActivity 等等</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/12/android-2-3-nexus-s-announced.html" />
   <id>tag:www.jollen.org,2010:/blog//2.728</id>
   
   <published>2010-12-08T10:31:56Z</published>
   <updated>2010-12-08T17:39:20Z</updated>
   
   <summary>Android 2.3 這次終於如傳聞中的日期釋出了，許多重要的新特色也出現在這個重要的版本裡了。官方網站上有完整的 [Android 2.3 Platform Highlights]，網路新聞也有不少的介紹；在這裡簡單聊一下一些看法。 Android 2.3 已經來到 API Level 9，有許多有趣的更新，像是加入了 VoIP、NFC 與 Download Manager，還有強化了遊戲開發的功能。多媒體框架部份也有重要的更新。新的 Multimedia Framework 已經可以完全取代 OpenCore。新產品開發上，已經能去除 OpenCore 並使用 Android 2.3 的 VP8/WebM 新技術，理論上，多媒體的效能以及應用將有大幅度的進展。 在遊戲開發部份，因為有不少的 native code 開發需求，這次 Android 2.3 也加入了 android.app.NativeActivity 幫助遊戲開發者撰寫 native code，例如：存取 OpenSL...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Android 2.3 這次終於如傳聞中的日期釋出了，許多重要的新特色也出現在這個重要的版本裡了。官方網站上有完整的 [<a href="http://developer.android.com/sdk/android-2.3-highlights.html">Android 2.3 Platform Highlights</a>]，網路新聞也有不少的介紹；在這裡簡單聊一下一些看法。

Android 2.3 已經來到 API Level 9，有許多有趣的更新，像是加入了 VoIP、NFC 與 Download Manager，還有強化了遊戲開發的功能。多媒體框架部份也有重要的更新。新的 Multimedia Framework 已經可以完全取代 OpenCore。新產品開發上，已經能去除 OpenCore 並使用 Android 2.3 的 VP8/WebM 新技術，理論上，多媒體的效能以及應用將有大幅度的進展。

在遊戲開發部份，因為有不少的 native code 開發需求，這次 Android 2.3 也加入了 android.app.NativeActivity 幫助遊戲開發者撰寫 native code，例如：存取 OpenSL ES、audio，以及其它 NDK 裡的 native API。Dalvik 也加入了 StrictMode debugging 的功能，對於效能以及記憶體使用的統計分析，相信有很大的幫助。

不過，API 終究是 API，需要應用開發者花費巧思；platform 還是 platform，需要實作硬體驅動程式，以及精緻的軟硬整合工作。過去硬體廠老是被 AOSP 拉著跑，每當新的 AOSP 出現，就要花費力氣進行實作，或是整合至硬體；過去許多製造商已經累積了許多程式碼與實作，只要能做到 API 相容，並符合架構，相信能重用程式碼的機會相當高。因此，理論上，將 Android 2.1/2.2 更新至 Android 2.3 將不再這麼花費力氣，速度也將更快，至少不再像過去，需要幾個月的實作與測試時間。

從產品面來看，三星的 Nexus S 應該是值得期待的，會有許多更先進的軟硬整合技術出現。像是：Nexus S 內嵌 NFC 晶片，是很值得研究的技術。還有像是 Nexus S 的顯示面板，採用三星最強悍的 AMOLED 技術，在戶外也可以有很棒的表現，相信是很重要的亮點：搭配 480x800 畫面解析度的 4 吋面板，很適合用來撥放高清視頻 (HD)。Nexus S 還跟 Google 服務有很好的整合，總之，趕快來買一支吧。]]>
      
   </content>
</entry>
<entry>
   <title>山寨市場是常規市場：下一波的市場新機會 </title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/11/china-the-next-wave-of-new-android-market-opportunities.html" />
   <id>tag:www.jollen.org,2010:/blog//2.727</id>
   
   <published>2010-11-29T04:51:13Z</published>
   <updated>2010-11-29T10:53:07Z</updated>
   
   <summary>將山寨市場正名為「常規市場」，這種的現象是一種新的社會文化。 2010年又到了尾聲，傳聞中的Android 3.0版本以及Android平板電腦，都將在明年成為科技業的重頭戲之一。將近一年前，在本論壇也提及二個主題：「發展自有Android分支」以及「山寨軍品牌革命：下一個山寨影響力」。根據Google對Android未來的發展策略，以及對廠商的支援政策來看，發展自有Android分支已經成為一項必要的工作。 在山寨軍品牌革命這篇評論裡，提到Android帶來的機會，以及山寨的轉型方向。隨著Android手機以及相關產品的大舉佔市，以及山寨大軍一年多來的努力，我們發現「山寨市場」以及「山寨文化」確實有一些顯著的改變。許多山寨商已經擁有自有的Android分支，但我們從更大的層面來放大觀察「山寨」：山寨改變了社會文化。以下是針對「山寨」所做的一些觀察，以及延續性的討論，請不吝指教。 針對「山寨」這個名詞，許多人都有「一個層面」上的誤解，即「山寨就是盜版」。即先前提到的：在抄襲與非正統的「模式」下所開發與製造的手機，就被暱稱為「山寨機」，意謂拷貝與強取之意。大陸知名山寨觀察家「阿甘」在他的著作「山寨手機幕後真相」裡指出，「山寨機」成為一種「社會文化」。 在阿甘先生的著作裡提出這樣的看法。過去的大型企業，做習慣了「規模經濟」，由於一些因素，這些企業在發展穩定後，便開始「貴族化」，這與山寨文化是非常鮮明的對比。山寨機經過幾年的發展，居然開始影響社會文化，讓山寨起家的「草根階層」也能和以大企業為代表的「精英階段」相互競爭。從產品的角度來看，這是個性化與「私品牌化」的潮流。 由山寨所帶起的社會文化改變，最鮮明的現象就是「個人與團隊」的快速堀起。這點在阿甘先生的著作裡也有觀察。有技術的個人，或是有能力的團隊，掌握了關鍵的資源或技術，因此萌生自立門戶的想法。關鍵的資源包含：市場、人力、商業模式、社會資源等等。單純從技術面來分析，Android帶動巨大的機會，許多優秀的Android開發小公司，都是個人自立門戶下的成果。這就是山寨機崛起的關鍵因素：眾多的個人或小團隊。 因此，把山寨定位為盜版集團，可能是過時的看法了。維基百科、Linux kernel以及山寨機本質本並無差別，他們都是以一種「籠統」、「非正規組織」、「個人」、「螞蟻大軍」等模式所建構出來的；從十多年前開始，透過網際網路的推波助灡與影響，這種新的社會文化就開始形成了。所以，就如同阿甘先生在他的著作裡的看法，「山寨企業將顛覆傳統的競爭法則」；自由軟體或 Android給了技術人員很好的機會。 在十月份的「2010 Android社群平臺開發大會」上，小弟也發表了一個淺見。「山寨市場」或「類山寨市場」，與「正規市場」完全衝突，但山寨機廠商不但國際化也品牌化，許多山寨廠商的產品品質也和正規產品不相上下了，許多更已經「正規化」。因此，不如將山寨市場正名為「常規市場」，這種「非大企業也能為之」的現象是一種新的社會文化，許多山寨廠商都能直接和大公司建立商業關係，這代表精英階層的鬆動；阿甘先生在其著作裡所做的觀察，令人發省。從Android或自由軟體的技術面深入觀察，將角度提升到社會層面，將會發現許多有趣的改變。(原文刊載於「零組件雜誌 2010.11月」）...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="產品開發" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      將山寨市場正名為「常規市場」，這種的現象是一種新的社會文化。

2010年又到了尾聲，傳聞中的Android 3.0版本以及Android平板電腦，都將在明年成為科技業的重頭戲之一。將近一年前，在本論壇也提及二個主題：「發展自有Android分支」以及「山寨軍品牌革命：下一個山寨影響力」。根據Google對Android未來的發展策略，以及對廠商的支援政策來看，發展自有Android分支已經成為一項必要的工作。

在山寨軍品牌革命這篇評論裡，提到Android帶來的機會，以及山寨的轉型方向。隨著Android手機以及相關產品的大舉佔市，以及山寨大軍一年多來的努力，我們發現「山寨市場」以及「山寨文化」確實有一些顯著的改變。許多山寨商已經擁有自有的Android分支，但我們從更大的層面來放大觀察「山寨」：山寨改變了社會文化。以下是針對「山寨」所做的一些觀察，以及延續性的討論，請不吝指教。

針對「山寨」這個名詞，許多人都有「一個層面」上的誤解，即「山寨就是盜版」。即先前提到的：在抄襲與非正統的「模式」下所開發與製造的手機，就被暱稱為「山寨機」，意謂拷貝與強取之意。大陸知名山寨觀察家「阿甘」在他的著作「山寨手機幕後真相」裡指出，「山寨機」成為一種「社會文化」。

在阿甘先生的著作裡提出這樣的看法。過去的大型企業，做習慣了「規模經濟」，由於一些因素，這些企業在發展穩定後，便開始「貴族化」，這與山寨文化是非常鮮明的對比。山寨機經過幾年的發展，居然開始影響社會文化，讓山寨起家的「草根階層」也能和以大企業為代表的「精英階段」相互競爭。從產品的角度來看，這是個性化與「私品牌化」的潮流。

由山寨所帶起的社會文化改變，最鮮明的現象就是「個人與團隊」的快速堀起。這點在阿甘先生的著作裡也有觀察。有技術的個人，或是有能力的團隊，掌握了關鍵的資源或技術，因此萌生自立門戶的想法。關鍵的資源包含：市場、人力、商業模式、社會資源等等。單純從技術面來分析，Android帶動巨大的機會，許多優秀的Android開發小公司，都是個人自立門戶下的成果。這就是山寨機崛起的關鍵因素：眾多的個人或小團隊。

因此，把山寨定位為盜版集團，可能是過時的看法了。維基百科、Linux kernel以及山寨機本質本並無差別，他們都是以一種「籠統」、「非正規組織」、「個人」、「螞蟻大軍」等模式所建構出來的；從十多年前開始，透過網際網路的推波助灡與影響，這種新的社會文化就開始形成了。所以，就如同阿甘先生在他的著作裡的看法，「山寨企業將顛覆傳統的競爭法則」；自由軟體或 Android給了技術人員很好的機會。

在十月份的「2010 Android社群平臺開發大會」上，小弟也發表了一個淺見。「山寨市場」或「類山寨市場」，與「正規市場」完全衝突，但山寨機廠商不但國際化也品牌化，許多山寨廠商的產品品質也和正規產品不相上下了，許多更已經「正規化」。因此，不如將山寨市場正名為「常規市場」，這種「非大企業也能為之」的現象是一種新的社會文化，許多山寨廠商都能直接和大公司建立商業關係，這代表精英階層的鬆動；阿甘先生在其著作裡所做的觀察，令人發省。從Android或自由軟體的技術面深入觀察，將角度提升到社會層面，將會發現許多有趣的改變。(原文刊載於「零組件雜誌 2010.11月」）
      
   </content>
</entry>
<entry>
   <title>簡介 Android Camera 三大功能區塊</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/11/android-camera-block-diagram.html" />
   <id>tag:www.jollen.org,2010:/blog//2.726</id>
   
   <published>2010-11-25T12:41:05Z</published>
   <updated>2010-11-25T19:01:59Z</updated>
   
   <summary>近期為客戶進行 Android Camera 的顧問服務，主要的任務是改善 Android 在拍照方面的效能，撰寫了一些相當基本的觀念介紹，在此與大家分享。Android 的 Camera 系統大概念上可分成三大區塊： 1. android.hardware.Camera 2. Camera Service 3. Camera HAL + videodev 其中最核心的 Camera Service 預設是實作在 SystemServer 裡。控制 Camera 硬體的 HAL 部份，目前大多採用 Linux 的 videodev 介面來擷取視訊。以下簡介 Android Camera 的三大功能區塊。 1. android.hardware.Camera 屬於 Java...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[近期為客戶進行 Android Camera 的顧問服務，主要的任務是改善 Android 在拍照方面的效能，撰寫了一些相當基本的觀念介紹，在此與大家分享。Android 的 Camera 系統大概念上可分成三大區塊：

1. android.hardware.Camera
2. Camera Service
3. Camera HAL + videodev

其中最核心的 Camera Service 預設是實作在 SystemServer 裡。控制 Camera 硬體的 HAL 部份，目前大多採用 Linux 的 videodev 介面來擷取視訊。以下簡介 Android Camera 的三大功能區塊。

<strong>1. android.hardware.Camera</strong>

屬於 Java 層，Camera 應用程式可透過 Camera.open() 來取得 android.hardware.Camera 的實例化 (instance)，並且可實作 Camera.PictureCallback 介面來取得「照片影像」。Camera.PictureCallback 提供二種照片資料：JPEG Data 與 Raw Data。這部份的細節可參考 Camera.takePicture()。

<strong>2. Camera Service</strong>

Android 的 Camera Service 重要程式碼實作於 libcameraservice.so，對於 Android 平臺的移植者來說，可忽略 Camera Service 的內部細節，直接實作 Camera HAL 即可驅動 Camera 硬體。但對於 Camera Service 的設計，以及實作細節進行一些研究，對於改善現有 reference code 的效率會有一些幫助。關於 Camera Service 的設計細節，留待後續做說明。

<strong>3. Camera HAL</strong>

驅動 Camera 硬體最關鍵的部份。在 Google 官方的 Android Platform Developer's Guide 文件裡指出，平臺移植者可實作 CameraHardwareInterface 來驅動 Camera 硬體。CameraHardwareInterface 是 Android 的 Camera HAL 設計，開發者可參考 Android 裡的 CameraHardwareStub.c 範例，以了解 CameraHardwareInterface 的實作原理。

Camera HAL 裡設計了二個 thread，分別是：preview thread 與 picture thread。Picture thread 在取得影像資料後，以 callback 方式將 JPEG data 或 raw data 往 Java 層傳遞。如上述，Camera 應用程式透過實作 Camera.PictureCallback 取得影像資料。]]>
      
   </content>
</entry>
<entry>
   <title>Android 產品開發工作談：嵌入式系統技術講求整機開發</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/11/android-embedded-system.html" />
   <id>tag:www.jollen.org,2010:/blog//2.725</id>
   
   <published>2010-11-17T03:41:58Z</published>
   <updated>2010-11-17T10:52:42Z</updated>
   
   <summary>嵌入式系統畢竟是一個需要高度「軟硬整合」的技術工作，這和過去台灣所熟悉的「PC」是很不一樣的工程。過去把 PC 模組化，大家可以分工生產個別模組，組裝後，安裝作業系統以及軟體。把這個思惟用在嵌入式系統開發上，可能會產生一些盲點。 以 Android 作業系統為例，廠商都能取得 reference code，以及 Android 使用許多開放源碼專案的成果，因此技術人員能進行更精緻的技術工作，例如：針對處理器優化編譯器。過去，把硬體做好，再安裝微軟作業系統，是台灣習慣的模式，但廠商無法取得源碼，最多只能使用 API 進行開發，所以直接取得能支援硬體的作業系統，是微軟模式的特色。 近期與許多經理人洽談 Android 產品的合作，發現微軟習慣真是如影隨形，以舊思惟思考新的產品，可能有許多盲點。產品研發的根本是技術，尚未脫離技術工作階段時，把專業的工作交給專業，是最基本的態度與責任。以下是小弟的一些個人看法，希望在此與大家分享，讓專案的成敗由技術決定，而不是身段與心態。請不吝指教。 嵌入式系統技術講求整機開發 如同一開始提的，嵌入式系統是非常講求細節的工作，所有的細節是為了讓軟體與硬體有更好的整合性，效能與穩定性的期中考卷，技術工作者必須努力交出及格的成績單。嵌入式系統的技術細節，往往超乎技術人員自已的想像。 過去的 PC &amp; NB 研發工作，努力把硬體做好，用更快的處理器，把作業系統安裝到硬體上。「直接把軟體安裝在硬體上」，不管是硬體工程師，或軟體工程師，都不需要考慮軟硬體間的細節。所以，PC &amp; NB 是一種不必過度講究開發細節的工作。 現在把 Android 放到 ARM 平臺上，開發手機，不但需要把 Android 提供的 reference code 做實作，更要進行許多細節的工作。幾個大細節像是： 1. Android 提供的 reference Launcher...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[嵌入式系統畢竟是一個需要高度「軟硬整合」的技術工作，這和過去台灣所熟悉的「PC」是很不一樣的工程。過去把 PC 模組化，大家可以分工生產個別模組，組裝後，安裝作業系統以及軟體。把這個思惟用在嵌入式系統開發上，可能會產生一些盲點。

以 Android 作業系統為例，廠商都能取得 reference code，以及 Android 使用許多開放源碼專案的成果，因此技術人員能進行更精緻的技術工作，例如：針對處理器優化編譯器。過去，把硬體做好，再安裝微軟作業系統，是台灣習慣的模式，但廠商無法取得源碼，最多只能使用 API 進行開發，所以直接取得能支援硬體的作業系統，是微軟模式的特色。

近期與許多經理人洽談 Android 產品的合作，發現微軟習慣真是如影隨形，以舊思惟思考新的產品，可能有許多盲點。產品研發的根本是技術，尚未脫離技術工作階段時，把專業的工作交給專業，是最基本的態度與責任。以下是小弟的一些個人看法，希望在此與大家分享，讓專案的成敗由技術決定，而不是身段與心態。請不吝指教。

<strong>嵌入式系統技術講求整機開發</strong>

如同一開始提的，嵌入式系統是非常講求細節的工作，所有的細節是為了讓軟體與硬體有更好的整合性，效能與穩定性的期中考卷，技術工作者必須努力交出及格的成績單。嵌入式系統的技術細節，往往超乎技術人員自已的想像。

過去的 PC & NB 研發工作，努力把硬體做好，用更快的處理器，把作業系統安裝到硬體上。「直接把軟體安裝在硬體上」，不管是硬體工程師，或軟體工程師，都不需要考慮軟硬體間的細節。所以，PC & NB 是一種不必過度講究開發細節的工作。

現在把 Android 放到 ARM 平臺上，開發手機，不但需要把 Android 提供的 reference code 做實作，更要進行許多細節的工作。幾個大細節像是：

1. Android 提供的 reference Launcher 夠不夠用？（穩定性、反應速度等）
2. Android 提供的 prebuilt toolchain 夠不夠用？（符號處理、指令集等等）
3. 開機速度。

還有更多的小細節需要我們努力，例如：PNG24 在 PNG8 的處理有失真問題 (GIF)。不同的硬體，細節不會相同，例如這裡提到的 PNG24 與 PNG8 處理問題。所有的細節是為了讓「整機」有更棒的表現，例如避免 PNG24 不出現失真，這個失真會是肉眼可見的問題，不該被忽略。

我們是一個專注嵌入式系統的研發團隊，開發「整機」讓我們全心在「這個硬體」上處理各種軟體細節。Android 產品也是如此。一開始就定位「整機研發」，因為這是技術的本質，嵌入式系統考慮硬體來做軟體，所以軟體綁硬體，是技術所導致的結果。

在我們 A 機器上表現良好的軟體，直接安裝到 B 機器，我們的軟體可能是 dirty software：達不到好的穩定性，也做不到好的速度，或許只有部份功能可以正常。因此，身為一個專業的技術工作者，當您遇到客戶提出「給我們源碼與硬體設計」，「我們要自已改硬體」，「我們自已改Driver」，「應用程式可以用外包方式處理」，等典型要求時，最好為自已爭取一段時間，靜下心來思考專案的可行性。

請不要把我的 Android framework 軟體直接「安裝」在您的硬體上。

技術學習者也應該更務實，以「Embedded Linux」來說，我們應該有耐心地去了解每個單元的設計、運作原理與架構，因為細節就是在處理這些技術，而不是學習操作或是 how-to。

取得參考設計，在硬體上加入模組，更換零件，把源碼當護身符，「因為樣機都可以跑了、改改東西不難」，是良方還是毒藥，需專業判斷，而不是籠統的認定。例如：2個G-Sensor還是3個G-Sensor，是不同的二件事情。商業周刊第1191期的標題「忘記會做微軟　不然就等死」，看起來聳動，但也真實；但是，我們必須往好處想，因為我們面臨的將不會是技術問題，而是心態問題。《待續》]]>
      
   </content>
</entry>
<entry>
   <title>又說 Android 2.3 將透過 OTA 更新了</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/11/android-23-ota.html" />
   <id>tag:www.jollen.org,2010:/blog//2.724</id>
   
   <published>2010-11-09T16:21:23Z</published>
   <updated>2010-11-09T22:48:01Z</updated>
   
   <summary>「OHA Team Member Confirms Gingerbread Version As 2.3, Hints At Dev Nexus Ones Receiving An OTA Update In The Next Few Days」說把 Nexus One 準備好，因為 Android 2.3 將於近日內釋出。根據文章裡的消息來看，最有可能釋出的是 Android 2.3 SDK，時間是在 11 月 11 日。至於將令各界人仰馬翻的 AOSP 目前依然狀況未明。不過總結目前的謠言來看，下一個版本 Gingerbread 是 2.3...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="產品開發" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[「<a href="http://www.androidpolice.com/2010/11/07/oha-team-member-confirms-gingerbread-version-as-2-3-hints-at-dev-nexus-one-versions-receving-an-ota-update-in-the-next-few-days/" target="_blank">OHA Team Member Confirms Gingerbread Version As 2.3, Hints At Dev Nexus Ones Receiving An OTA Update In The Next Few Days</a>」說把 Nexus One 準備好，因為 Android 2.3 將於近日內釋出。根據文章裡的消息來看，最有可能釋出的是 Android 2.3 SDK，時間是在 11 月 11 日。至於將令各界人仰馬翻的 AOSP 目前依然狀況未明。不過總結目前的謠言來看，下一個版本 Gingerbread 是 2.3 而不是 3.0。之前謠傳的 Nexus Two 現在「據說」硬體出了問題，無法如期推出。最近真是太有趣了。

Gingerbread 除了大幅改善使用者介面外，也加入了 WebM 技術，很值得期待；Android 多媒體架構與支援程度，等到 AOSP 釋出後需要了解一下，是否有較大的設計變更。WebM 導入後，Android 的影音串流技術預期將進入新的里程碑。其它像是 Flash 以及 HTML5 等，只能等到 AOSP 釋出才知道了。 ]]>
      
   </content>
</entry>
<entry>
   <title>最近的二個八卦：Android 2.3 與 Nexus Two</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/10/android-gingerbread-nexus-two.html" />
   <id>tag:www.jollen.org,2010:/blog//2.723</id>
   
   <published>2010-10-29T15:32:19Z</published>
   <updated>2010-10-29T22:51:35Z</updated>
   
   <summary>最近有關 Android 的八卦消息還挺多的。Gingerbread 是 Android 3.0 的代號，不過上週的小道消息指出，Gingerbread 應該是 Android 2.3 而不是 3.0。這應該不是 Android 在玩版本遊戲，未來 Android 的版本如何釋出與命名，關係重大。 Android 即將由手機延伸至平板電腦，這個重要的版本里程碑落在哪一個數字，現在眾說紛云，不過很可能是 Android 3.5。如果是這樣，Android 2.3 應該只是 2.2 版的一個 update，算是對手機用途的 Android 版本有個交待。 跟 Android 2.3 有關的另一個八卦是，十一月初，Google 很可能將發表 Nexus Two，並交由 Samsung 代工。延續先前的看法「Nexus One是下架 還是承先啟後」，Android 在線上市集（Android Market）已經有了一些重要的改變，理論上應該有個...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="產品開發" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[最近有關 Android 的八卦消息還挺多的。Gingerbread 是 Android 3.0 的代號，不過上週的小道消息指出，Gingerbread 應該是 Android 2.3 而不是 3.0。這應該不是 Android 在玩版本遊戲，未來 Android 的版本如何釋出與命名，關係重大。

Android 即將由手機延伸至平板電腦，這個重要的版本里程碑落在哪一個數字，現在眾說紛云，不過很可能是 Android 3.5。如果是這樣，Android 2.3 應該只是 2.2 版的一個 update，算是對手機用途的 Android 版本有個交待。

跟 Android 2.3 有關的另一個八卦是，十一月初，Google 很可能將發表 Nexus Two，並交由 Samsung 代工。延續先前的看法「<a href="http://www.ctimes.com.tw/news/ShowCols.asp?O=201007011401114982" target="_blank">Nexus One是下架 還是承先啟後</a>」，Android 在線上市集（Android Market）已經有了一些重要的改變，理論上應該有個 2.x 的版本，擔負整合新授權機制與產品展示的工作；很期待 2.3 能達陣。

以產品面來看，Android 2.3（如果真有其事）與 Samsung 合作，很可能是在 AMOLED 以及 Touch UI 部份尋求突破；以 Nexus One 的精神來看，Nexus Two 的展示意味應該也很濃厚。「如果」Nexus Two 真的投向三星的懷抱，展示「硬體設計」的可能性又高了一些。這是從技術發展的角度「做出的猜想」，純屬個人憶測，不一定會中獎。]]>
      
   </content>
</entry>
<entry>
   <title>長江三號 Android 手機來囉：來自瑞芯微電子（Rockchip）與中一無線（ZinnWireless）</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/10/rockchip-zinnwireless-android-cj-3.html" />
   <id>tag:www.jollen.org,2010:/blog//2.722</id>
   
   <published>2010-10-04T20:21:59Z</published>
   <updated>2010-10-05T01:57:27Z</updated>
   
   <summary>前陣子幫大家簡略介紹過 [長江二號] Android 智能手機，由於一些原因，長江二號將不進行量產，轉而全力投入長江三號的研發；現在再來簡略地向大家更新一下狀態。我們的 [長江三號] 智能手機，在八月時，大致有了原型；第一批大量測試機，也在九月中陸續出廠，目前正在進行密集的產品與測試工作。 長江三號是由瑞芯微電子（Rockchip）與中一無線（ZinnWireless Inc）共同推出的 Android 智能手機，也是第一支採用中國芯的 Android 手機。過去曾在香港電子展（今年4月份），以及德國 IFA 會場現身過： [多图]3D+3G+Android 瑞芯IFA2010火爆直击 其實，網路上已經有許多大大小小的相關消息了，只是因為機器還在研發階段，「官方」的部份幾乎沒有任何直接的公開訊息。想先認識我們的長江三號（三仔）的朋友，可以從下面的報導開始： 瑞芯微RK28新机 - 中一无线iZiNN CJ-3(长江3号)抢先报道 或是先從我們簡陋的小網站開始 [Zinn.Mobi]，很抱歉，大家實在都太忙了，我們近期會儘快為大家更新「三仔」的消息。更多有關長江三號的消息，接下來，我們都會發佈到 zinn.mobi 的網站上；不過，小弟的 Blog 也會做一些簡單的轉載以及說明。 目前長江三號將進入量產，以及商務階段；歡迎閱讀 Engaget 的文章，簡單了解一下量產機的狀況： N8的系统换成Android如何：中一长江3号量产开盒 再跟大家宣佈一則好消息。由於長江三號將進入量產，以及商務階段，因此，我們也會陸續進行一些公開活動。首先，在10月11日的北京通訊展上，我們的合作伙伴「瑞芯微電子」將現場展示長江三號產品機，歡迎大家前往會展，給我們支持喔。 接著，在10月21-22舉辦的「2010 Android 平臺社群開發大會」活動上，ZinnWireless（深圳中一無線軟件有限公司）也會親自為大家介紹長江三號，中一無線的經營團隊，也會到場與大家交流。介紹機器的部份，將由小弟來操刀介紹，不嫌棄的朋友請給我們指教與意見。小弟也會簡單說明，ZinnWireless 的 Android 技術發展構想。ZinnWireless 將開始供應全球第一款 Android...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="產品開發" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[前陣子幫大家簡略介紹過 [<a href="http://www.jollen.org/blog/2010/08/zinn-mobi-android-gsm-phone.html" target="_blank">長江二號</a>] Android 智能手機，由於一些原因，長江二號將不進行量產，轉而全力投入長江三號的研發；現在再來簡略地向大家更新一下狀態。我們的 [<a href="http://www.google.com/search?q=%E9%95%B7%E6%B1%9F%E4%B8%89%E8%99%9F+android&hl=zh-TW&client=firefox-a&hs=IHD&rls=org.mozilla:zh-TW:official&source=lnt&tbs=qdr:m&sa=X&ei=dTyqTLWWHsbpOdCrockM&ved=0CA4QpwU" target="_blank">長江三號</a>] 智能手機，在八月時，大致有了原型；第一批大量測試機，也在九月中陸續出廠，目前正在進行密集的產品與測試工作。

長江三號是由瑞芯微電子（Rockchip）與中一無線（ZinnWireless Inc）共同推出的 Android 智能手機，也是第一支採用中國芯的 Android 手機。過去曾在香港電子展（今年4月份），以及德國 IFA 會場現身過：

<a href="http://cnbeta.com/articles/121197.htm" target="_blank">[多图]3D+3G+Android 瑞芯IFA2010火爆直击</a>

其實，網路上已經有許多大大小小的相關消息了，只是因為機器還在研發階段，「官方」的部份幾乎沒有任何直接的公開訊息。想先認識我們的長江三號（三仔）的朋友，可以從下面的報導開始：

<a href="http://www.cnbeta.com/articles/118130.htm" target="_blank">瑞芯微RK28新机 - 中一无线iZiNN CJ-3(长江3号)抢先报道</a>

或是先從我們簡陋的小網站開始 [<a href="http://www.Zinn.Mobi" target="_blank">Zinn.Mobi</a>]，很抱歉，大家實在都太忙了，我們近期會儘快為大家更新「三仔」的消息。更多有關長江三號的消息，接下來，我們都會發佈到 zinn.mobi 的網站上；不過，小弟的 Blog 也會做一些簡單的轉載以及說明。

目前長江三號將進入量產，以及商務階段；歡迎閱讀 Engaget 的文章，簡單了解一下量產機的狀況：

<a href="http://www.cnbeta.com/articles/122021.htm" target="_blank">N8的系统换成Android如何：中一长江3号量产开盒</a>

再跟大家宣佈一則好消息。由於長江三號將進入量產，以及商務階段，因此，我們也會陸續進行一些公開活動。首先，在10月11日的北京通訊展上，我們的合作伙伴「瑞芯微電子」將現場展示長江三號產品機，歡迎大家前往會展，給我們支持喔。

接著，在10月21-22舉辦的「<a href="http://www.moko365.com/2010-android/" target="_blank">2010 Android 平臺社群開發大會</a>」活動上，ZinnWireless（深圳中一無線軟件有限公司）也會親自為大家介紹長江三號，中一無線的經營團隊，也會到場與大家交流。介紹機器的部份，將由小弟來操刀介紹，不嫌棄的朋友請給我們指教與意見。小弟也會簡單說明，ZinnWireless 的 Android 技術發展構想。ZinnWireless 將開始供應全球第一款 Android PCBA 量產解決方案，並「結合技術咨詢以及教育訓練」，請大家拭目以待囉。

目前，大家的心力都在研發以及產品工作上，有關長江三號的最新消息，要先請大家從網路上收看了；後續再幫大家發佈官方的「實機展示影片」。]]>
      
   </content>
</entry>
<entry>
   <title>平板電腦熱潮來臨，Android 不缺席，出自深圳的 Android Pad</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/09/android-pad-rockchip-rk2808.html" />
   <id>tag:www.jollen.org,2010:/blog//2.721</id>
   
   <published>2010-09-18T15:49:34Z</published>
   <updated>2010-09-18T21:41:46Z</updated>
   
   <summary>深圳特產再一樁，道地的 Android 平板電腦。外觀不錯，使用起來還算及格。這款 Android Pad 的使用手感仍不及 iPad，但是從 Android 的技術角度來看這個板子，還是很有趣的。這是在深圳出現的 Android 平板電腦，左邊是真正的 iPad，右邊則是 Android 平板電腦的包裝。 包裝盒已經說明這款產品的身世了，這是「Android 平板電腦」，外觀有點像 iPad，事實上根本是一模一樣的。 Android 平板電腦比 iPad 更小巧，經過一天的隨身使用，發現其實攜帶性很不錯，放在背包裡頗為方便，而且重量較輕。最重要的面板與觸控面板部份，不需要再多說了，明眼人一看就知道囉。iPad 深邃鳥黑的顯示屏，帶來的是最佳的視覺表現，這不是 Android Pad 這個有點白汒汒的白內障顯示屏可以抗衡的。 正版 iPad 的 LED 背光顯示可以說是它最不可或缺的特色。9.7 吋的 LED 背光 IPS 顯示屏，支援超廣視角，以及 multi-touch，讓 iPad 的視覺與操作達到很棒的同步。iPad 讓大腦、視覺與手指操作達到一種匪夷所思的同步，Android 平板大概還要花很長一段時間，才能達到這個境界。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="產品開發" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[深圳特產再一樁，道地的 Android 平板電腦。外觀不錯，使用起來還算及格。這款 Android Pad 的使用手感仍不及 iPad，但是從 Android 的技術角度來看這個板子，還是很有趣的。這是在深圳出現的 Android 平板電腦，左邊是真正的 iPad，右邊則是 Android 平板電腦的包裝。

<img src="http://jimg.jollen.org/2010/09/apad-1.jpg" alt="Android PAD" />

包裝盒已經說明這款產品的身世了，這是「Android 平板電腦」，外觀有點像 iPad，事實上根本是一模一樣的。

<img src="http://jimg.jollen.org/2010/09/apad-2.jpg" alt="Android PAD" />

Android 平板電腦比 iPad 更小巧，經過一天的隨身使用，發現其實攜帶性很不錯，放在背包裡頗為方便，而且重量較輕。最重要的面板與觸控面板部份，不需要再多說了，明眼人一看就知道囉。iPad 深邃鳥黑的顯示屏，帶來的是最佳的視覺表現，這不是 Android Pad 這個有點白汒汒的白內障顯示屏可以抗衡的。

正版 iPad 的 LED 背光顯示可以說是它最不可或缺的特色。9.7 吋的 LED 背光 IPS 顯示屏，支援超廣視角，以及 multi-touch，讓 iPad 的視覺與操作達到很棒的同步。iPad 讓大腦、視覺與手指操作達到一種匪夷所思的同步，Android 平板大概還要花很長一段時間，才能達到這個境界。

<img src="http://jimg.jollen.org/2010/09/apad-3.jpg" alt="Android PAD" />

從側面來比較，厚度非常接近；特別的是在材質方面，觸感還不錯，比起一些厚重的塑膠感平板電腦，這塊 Android 平板的整體質感確實不錯，目前為止還另人滿意。

<img src="http://jimg.jollen.org/2010/09/apad-4.jpg" alt="Android PAD" />

再近看，如果只看這個角度，其實已經可以達到以假亂真的效果了。

<img src="http://jimg.jollen.org/2010/09/apad-5.jpg" alt="Android PAD" />

外觀設計流著 iPad 的圓滑設計血液，再加上又是深圳出品，早早就被貫上「山寨 iPad」的雅號了。山寨 iPad 的喇叭設計在底部，試用後「音質」可以算得上及格。

<img src="http://jimg.jollen.org/2010/09/apad-6.jpg" alt="Android PAD" />

這款 Android 平板電腦，使用的是 Rockchip 的處理器（RK2808）。目前，已經有幾家深圳的 Android 研發公司，準備推出搭載 Rockchip 新一代處理器的 Android 平板電腦了；讓我們拭目以待吧。
]]>
      
   </content>
</entry>
<entry>
   <title>Android Telephony &amp; RIL: 通訊系統架構與實作，課後小記</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/09/android_telephony_ril.html" />
   <id>tag:www.jollen.org,2010:/blog//2.720</id>
   
   <published>2010-09-12T16:32:54Z</published>
   <updated>2010-09-18T20:48:42Z</updated>
   
   <summary>Android Telephony 以及 RIL 是一個重要的議題，內容主要在談論 Android 的電話系統框架，以及 RIL (Radio Interface Layer) 的實作。由於 Android 提供的 RIL 幾乎沒有實作 Modem 端的功能，也缺乏像是 Data Multiplexer 的實作，因此，研究 Telephony 以及實作 RIL 成為了 Android 手機開發的關鍵技術。 在經過一段相當長時間的規劃與調整後，終於在日前成功開設「Android Telephony &amp; RIL: 通訊系統架構與實作」課程，本程也在9月12日順利結訓。這是截至目前為止，在參與過的課程規劃案中，技術複雜度較高的題目。 課程內容除了採集過去開發 Android 手機的經驗外，也將 Telephony &amp; RIL 做了很完整的研究，目標是以深入淺出方式，介紹這個有意思的主題。希望這門課程，能協助學員開發 Android...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Android Telephony 以及 RIL 是一個重要的議題，內容主要在談論 Android 的電話系統框架，以及 RIL (Radio Interface Layer) 的實作。由於 Android 提供的 RIL 幾乎沒有實作 Modem 端的功能，也缺乏像是 Data Multiplexer 的實作，因此，研究 Telephony 以及實作 RIL 成為了 Android 手機開發的關鍵技術。

在經過一段相當長時間的規劃與調整後，終於在日前成功開設「Android Telephony & RIL: 通訊系統架構與實作」課程，本程也在9月12日順利結訓。這是截至目前為止，在參與過的課程規劃案中，技術複雜度較高的題目。

課程內容除了採集過去開發 Android 手機的經驗外，也將 Telephony & RIL 做了很完整的研究，目標是以深入淺出方式，介紹這個有意思的主題。希望這門課程，能協助學員開發 Android 手機的通訊功能。

<img src="http://images.moko365.com/images/coursegallery/tpe-telephony-20100912-1_b.jpg" />
圖：GPRS 上網 (Data Multiplexer) 實作討論

總計4天的課程裡，對 Telephony Service、PhoneProxy、PhoneInterfaceManager、RIL、Phone Service 等重要的通訊系統設計做了全面的解說，並以產品開發的實務經驗進行實作討論，將複雜又龐大的 Android Telephony 框架以及 RIL (Radio Interface Layer) 架構，做了整體的分析。

實作討論部份，針對實務面常見的實作議題做了許多討論，例如：

1. 實作 Android 未完成的 USSD (簡碼服務) 功能
2. 加入 SetMute 音量開關功能至 Android 通訊系統
3. Mux 實作 (資料多工) 討論、GPRS 上網、PDP
4. Timed callbacked 以及 synchronous AT I/O stream 討論等

此外，課程也將通訊系統使用到的架構設計觀念做了很清楚的說明；課程也將 Android 通訊系統使用到的 Design Pattern 做了整理，例如：Abstract Factory Pattern、Factoy Method Pattern、Proxy Method Pattern 以及 Singleton Pattern 等，都放入課程裡做說明。期望能告訴學員，Android 的開發最好以「設計再實作」的角度出發。]]>
      
   </content>
</entry>
<entry>
   <title>Nexus One 晉升 Android Developer Phone 3</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/08/nexus-one-became-adp3.html" />
   <id>tag:www.jollen.org,2010:/blog//2.718</id>
   
   <published>2010-08-10T15:55:20Z</published>
   <updated>2010-08-10T21:16:49Z</updated>
   
   <summary>Nexus One 雖然在日前停止網路銷售，不過，根據幾天前在的 Android Developer Blog 上的一則新聞來看，Nexus One 榮獲「Android Developer Phone」頭銜。也就是，雖然 Nexus One 下架了，但改以 ADP3（Android Developer Phone 3）的名稱對開發者進行銷售。第一代 Android Developer Phone 就是由 T-Mobile G1（aka HTC Dream）換名而來，並且做了解鎖動作；Android Developer Phone 2（aka G2 or HTC Magic）於去年 11 月推出，同樣也是 Unlocked Phone。ADP3 則是將 Nexus One...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      Nexus One 雖然在日前停止網路銷售，不過，根據幾天前在的 Android Developer Blog 上的一則新聞來看，Nexus One 榮獲「Android Developer Phone」頭銜。也就是，雖然 Nexus One 下架了，但改以 ADP3（Android Developer Phone 3）的名稱對開發者進行銷售。第一代 Android Developer Phone 就是由 T-Mobile G1（aka HTC Dream）換名而來，並且做了解鎖動作；Android Developer Phone 2（aka G2 or HTC Magic）於去年 11 月推出，同樣也是 Unlocked Phone。ADP3 則是將 Nexus One 下架上架再解鎖（Unlocked）。

這是 Android 開發者的一大福音（除了它的價格之外），Google 總是提供好用的開發者手機（Developer Phone）。ADP3 的購買方法還是一樣，需要 Android Developer 帳號。
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android Booting 解析, #3: 製作 Android Bootchart</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/08/jollen-android-booting-column-3.html" />
   <id>tag:www.jollen.org,2010:/blog//2.716</id>
   
   <published>2010-08-03T03:15:46Z</published>
   <updated>2010-08-03T08:19:23Z</updated>
   
   <summary>前一則日記提到的 Bootchart 是典型的開機量測工具，主要能進行開機過程以及開機時間的量測。由於 Bootchart 的原理是取代 init process 或是內建在 init process 裡，所以只能取得 initial script 的開機過程報告。不過，這已經很有幫助了。 關於 Android Bootchart 以下是一份使用 Bootchart 所製作的 Android 開機流程圖。過去有一些以 C 重寫 Bootchart 的專案，而 Android 也有一份 C re-implementation，放置於 [system/core/init/bootchart.c]。由此可知，Android init 已經內建一份 C re-implement 的 Bootchart。 圖一：使用 Bootchart 製作的...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[前一則日記提到的 Bootchart 是典型的開機量測工具，主要能進行開機過程以及開機時間的量測。由於 Bootchart 的原理是取代 init process 或是內建在 init process 裡，所以只能取得 initial script 的開機過程報告。不過，這已經很有幫助了。

<strong>關於 Android Bootchart</strong>

以下是一份使用 Bootchart 所製作的 Android 開機流程圖。過去有一些以 C 重寫 Bootchart 的專案，而 Android 也有一份 C re-implementation，放置於 [<a href="http://android.git.kernel.org/?p=platform/system/core.git;a=blob;f=init/bootchart.c;h=f72fcaaca06ea42e077ea984017dccbdfeb8a38c;hb=35237d135807af84bf9b0e5b8d7f8633e58db6f5" target="_blank">system/core/init/bootchart.c</a>]。由此可知，Android init 已經內建一份 C re-implement 的 Bootchart。

<a href="http://www.jollen.org/blog/2010/07/28/bootchart-2.png" target="_blank"><img alt="android bootchart" src="http://www.jollen.org/blog/2010/07/28/bootchart-2.png" width="640" border="0" /></a>
圖一：使用 Bootchart 製作的 Android 開機流程圖

以下說明如何製作 Android Bootchart。

<strong>1. 編譯 Android Bootchart</strong>

Android 的 init process 雖然已內建 Bootchart，但編譯系統預設並不會將 Bootchart 編譯至 init 裡。因此，需要重新編譯 init.c 才能加入 Bootchart：

<pre>
jollen@android:~/try/mokoid_elcair-20100511$ touch system/core/init/init.c
jollen@android:~/try/mokoid_elcair-20100511$ . build/envsetup.sh 
including vendor/aosp/vendorsetup.sh
jollen@android:~/try/mokoid_elcair-20100511$ m INIT_BOOTCHART=true PRODUCT-dma6410xp-eng -j 8
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=2.1-update1
TARGET_PRODUCT=dma6410xp
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=ECLAIR
============================================
</pre>

完成後，使用 Android 模擬器開啟製作好的 image file。

<strong>2. 設定 Bootchart Timeout 時間</strong>

要讓 Bootchart 在「下一次開機」時開始運作，以進行取樣並紀錄開機過程，需要指定 Timeout 時間：

<pre>
$ adb shell 'echo 120 > /data/bootchart-start'
$ adb shell 'mkdir /data/bootchart'
</pre>

重新啟動模擬器。對 /data 目錄進行的變動，「可以」寫回 userdata.img 裡。這裡指定 Timeout 時間為 '120' 秒；實際測試時，可以視情況自由調整。

<strong>3. 取得 Bootchart 紀錄檔</strong>

在 Android 系統裡的 /data/bootchart 取得開機紀錄檔：

<pre>
linux@android:~/android/mokoid$ adb shell
# ls -l /data/bootchart
-rw-rw-rw- root     root          389 2010-07-28 11:06 header
-rw-r--r-- root     root            0 2010-07-28 11:06 kernel_pacct
-rwxr-xr-x root     root       589824 2010-07-28 11:08 proc_diskstats.log
-rwxr-xr-x root     root      2293760 2010-07-28 11:08 proc_ps.log
-rwxr-xr-x root     root       196608 2010-07-28 11:07 proc_stat.log
# 
</pre>

接下來，必須取出這幾個檔案，並製作成漂亮的統計圖檔。貼心的 Android 已經幫我們準備好一個 script 檔了，因此，先切換到 system/core/init 目錄下，直接執行 grab-bootchart.sh：

<pre>
linux@android:~/android/mokoid$ cd system/core/init/
linux@android:~/android/mokoid/system/core/init$ ./grab-bootchart.sh 
7 KB/s (389 bytes in 0.048s)
1439 KB/s (405771 bytes in 0.275s)
2014 KB/s (3861856 bytes in 1.872s)
1936 KB/s (979391 bytes in 0.493s)
look at bootchart.tgz
</pre>

最後的統計報告存放於 /tmp/android-bootchart/bootchart.tgz。

<strong>4. 製作精美 Bootchart 報告</strong>

Bootchart 包含一個以 Java 寫成的圖表製作工具，因此，還是必須取得原始的 Bootchart 套件。在 Ubuntu 環境下，可以用 apt 直接安裝：

<pre>$ sudo apt-get install bootchart</pre>

接著，將 bootchart.tgz 製作成圖檔：

<pre>$ java -jar /usr/share/bootchart/bootchart.jar /tmp/android-bootchart/bootchart.tgz
Parsing /tmp/android-bootchart/bootchart.tgz
Wrote image: ./bootchart.png
</pre>

最後，得到如圖一的精美報告。接下來的工作，就是對 Bootchart 的內容進行分析。

<strong>延伸閱讀</strong>

2010.07.28: <a href="http://www.jollen.org/blog/2010/07/jollen-android-booting-column-1.html">Jollen 的 Android Booting 解析, #1: 整體開機流程</a>
2010.07.29: <a href="http://www.jollen.org/blog/2010/07/jollen-android-booting-column-2.html">Jollen 的 Android Booting 解析, #2: 關於開機的評估</a>
分享您的 Android Bootchart 筆記：<a href="http://jollen.org/wiki/Build_Android_Bootchart">Build Android Bootchart</a>]]>
      
   </content>
</entry>
<entry>
   <title>Android GSM Phone：長江二號 (CJ-2) 開機囉</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/08/zinn-mobi-android-gsm-phone.html" />
   <id>tag:www.jollen.org,2010:/blog//2.717</id>
   
   <published>2010-08-02T05:25:22Z</published>
   <updated>2010-08-02T10:31:26Z</updated>
   
   <summary>執行 Android 2.1 的智能手機「長江二號」開機囉。目前使用起來還算順暢，雖然 Engineering Build 的開機時間有點長，不過能看到 Linux 小企鵝，是一件興奮的事情。 長江二號（CJ-2）是使用 Rockchip RK2808 的 Android GSM 智能手機，目前正在測試中的「長江三號」是令人更興奮的版本。長江二號的團隊（Zinn.Mobi）正在很努力地催生三號中，希望 3G 版本也能儘快與大家見面。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[執行 Android 2.1 的智能手機「長江二號」開機囉。目前使用起來還算順暢，雖然 Engineering Build 的開機時間有點長，不過能看到 Linux 小企鵝，是一件興奮的事情。

<object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/CakdoDHGMRM&amp;hl=zh_TW&amp;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/CakdoDHGMRM&amp;hl=zh_TW&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object>

長江二號（CJ-2）是使用 Rockchip RK2808 的 Android GSM 智能手機，目前正在測試中的「長江三號」是令人更興奮的版本。長江二號的團隊（Zinn.Mobi）正在很努力地催生三號中，希望 3G 版本也能儘快與大家見面。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android Booting 解析, #2: 關於開機的評估</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/07/jollen-android-booting-column-2.html" />
   <id>tag:www.jollen.org,2010:/blog//2.715</id>
   
   <published>2010-07-29T13:12:45Z</published>
   <updated>2010-07-29T18:16:09Z</updated>
   
   <summary>針對「開機過程」的評估，可以採取個別擊破的方式；針對三個不同的開機階段，分別進行開機過程的評估。評估開機過程的典型做法，當然是測量「開機時間」。 確認訴求 費勁進行開機時間的評估，最首要的目的當然是「快速開機」，想辦法讓開機速度加快。策略上，因為手機是一種重視使用者經驗的產品，所以「儘早顯示桌面環境」就是一個好想法。採用「一大堆」非同步的做法，可以達到很不錯的效果。簡單來說，儘速顯示桌面環境的目的，就是造成開機很快的「假象」。 因此，快速開機在智慧型手機產品端，也可以歸類到 User Experience 主題。 確認方向 OS-Level 的部份，包含 Linux kernel 本身的開機時間測量，在此先行略過。針對 Android-Level 的開機時間測量，可以採用廣受歡迎的工具 [Bootchart] 來製作；對使用者來說，進入 Zygote Mode 時，已經是處於桌面環境下了，因此理論上也能先略過這個階段。 關鍵部位 (Critical Parts) 圖一：由 Android-Level 切入、尋找議題 如圖一。綜合上述，對 Android-Level 的開機過程進行評估，就是我們的首部曲，也是第一個研究方向。傳統的評估方式，是測量其開機時間；接下來，將會以知名的 Bootchart 來進行這項工作。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[針對「開機過程」的評估，可以採取個別擊破的方式；針對三個不同的開機階段，分別進行開機過程的評估。評估開機過程的典型做法，當然是測量「開機時間」。

<strong>確認訴求</strong>

費勁進行開機時間的評估，最首要的目的當然是「快速開機」，想辦法讓開機速度加快。策略上，因為手機是一種重視使用者經驗的產品，所以「儘早顯示桌面環境」就是一個好想法。採用「一大堆」非同步的做法，可以達到很不錯的效果。簡單來說，儘速顯示桌面環境的目的，就是造成開機很快的「假象」。

因此，快速開機在智慧型手機產品端，也可以歸類到 User Experience 主題。

<strong>確認方向</strong>

OS-Level 的部份，包含 Linux kernel 本身的開機時間測量，在此先行略過。針對 Android-Level 的開機時間測量，可以採用廣受歡迎的工具 [<a href="http://www.bootchart.org/" target="_blank">Bootchart</a>] 來製作；對使用者來說，進入 Zygote Mode 時，已經是處於桌面環境下了，因此理論上也能先略過這個階段。

<strong>關鍵部位 (Critical Parts)</strong>

<img src="http://www.jollen.org/blog/2010/07/28/android-booting-2.gif" />
圖一：由 Android-Level 切入、尋找議題

如圖一。綜合上述，對 Android-Level 的開機過程進行評估，就是我們的首部曲，也是第一個研究方向。傳統的評估方式，是測量其開機時間；接下來，將會以知名的 Bootchart 來進行這項工作。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android Booting 解析, #1: 整體開機流程</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/07/jollen-android-booting-column-1.html" />
   <id>tag:www.jollen.org,2010:/blog//2.714</id>
   
   <published>2010-07-28T06:20:44Z</published>
   <updated>2010-07-28T11:42:30Z</updated>
   
   <summary>Android 開機流程，是一個很值得詳細討論的主題；近期，也正在進行相關的技術工作，因此簡單整理一些相關資料，和大家分享。了解「整體開機流程」，是最重要的第一門課。我們將開機劃分為三大階段： 1. OS-Level，由 Bootloader 載入 Linux kernel 後，開始進行 kernel 本身的初始化，並載入 built-in 的驅動程式。Kernel 完成開機後，載入 init process，切換至 user-space 後，結束 kernel 的循序過程（sequence），進入排程模式（process scheduling）。 2. Android-Level，由 init process 開始，讀取 init.rc 並啟動重要的外部程式，例如：servicemanager、Zygote 以及 SystemServer。 3. Zygote-Mode，Zygote 啟動完 SystemServer 後，進入 Zygote Mode，在 Socket 等候命令。隨後，使用者將看到一個桌面環境（Home Screen）。桌面環境由一個名為...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Android 開機流程，是一個很值得詳細討論的主題；近期，也正在進行相關的技術工作，因此簡單整理一些相關資料，和大家分享。了解「整體開機流程」，是最重要的第一門課。我們將開機劃分為三大階段：

1. OS-Level，由 Bootloader 載入 Linux kernel 後，開始進行 kernel 本身的初始化，並載入 built-in 的驅動程式。Kernel 完成開機後，載入 init process，切換至 user-space 後，結束 kernel 的循序過程（sequence），進入排程模式（process scheduling）。

2. Android-Level，由 init process 開始，讀取 init.rc 並啟動重要的外部程式，例如：servicemanager、Zygote 以及 SystemServer。

3. Zygote-Mode，Zygote 啟動完 SystemServer 後，進入 Zygote Mode，在 Socket 等候命令。隨後，使用者將看到一個桌面環境（Home Screen）。桌面環境由一個名為 [<a href="http://android.git.kernel.org/?p=platform/packages/apps/Launcher.git;a=summary" target="_blank">Launcher</a>] 的應用程式負責提供。

整體開機流程如圖一所示。

<img src="http://www.jollen.org/blog/2010/07/28/android-booting-1.gif" />
圖一：Android 整體開機流程圖

初探 Android 開機技術的朋友，建議可以先行閱讀 init.rc 檔案，並了解 Android 的 init.rc 語法。Android init language 可參考 [<a href="http://pdk.android.com/online-pdk/guide/bring_up.html" target="_blank">PDK</a>] 的說明。

<strong>延伸閱讀</strong>

2010.04.24: <a href="http://www.jollen.org/blog/2010/04/android-initrc-setprop.html">
Jollen 的 Android 系統管理雜記, #3: init.rc 與 setprop</a>]]>
      
   </content>
</entry>
<entry>
   <title>文藝復興運動，軟體我能創作</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/07/rinascimento-floss.html" />
   <id>tag:www.jollen.org,2010:/blog//2.713</id>
   
   <published>2010-07-18T15:12:49Z</published>
   <updated>2010-07-20T03:53:13Z</updated>
   
   <summary> 自由，而不是免費啤酒 (註1)。 Rinascimento, FOSS or FLOSS (free/libre/open source software) 神權至上的時期，被稱為「黑暗時期」，在 14 世紀興起的「文藝復興」運動，打破這個現象。也就是說，黑暗時代，神權至上，可能有很多像是「魔法」的東西，或是很多霍格華茲魔法學校（註：哈利波特的學校）；文藝復興後，很多近代科學開始發展，生活在此時期後的人類，哈利波特稱之為麻瓜（Muggle，指沒有魔法的人）。 在 13 世紀晚期，義大利中產階段因為生活上的富足，開始尋求更優雅與時尚的生活，於是萠生「脫離神權」的想法。知名詩人「但丁（1265-1321）」的出現，被認為是義大利文藝復興時代的開始。於是，「個人主義」，也就是文藝復興運動的重要產物之一，開始發展。許多耳熟能詳的「大師」，也在文藝復興時期開始出現，例如：米開朗基羅（忍者龜）；天文學、物理學、數學、生物學等，高中時期最令我頭痛的近代科學，有了重要的發展。 用近代的網路現象來比喻，文藝復興運動很像是 Web 2.0。出現很多新現象，例如：個人主義的興起，每個人都可以自由創作，發表成果，這裡的「個人主義」指的是「好的」個人主義，例如：分享、討論、知識交換，而不是自私的這種個人主義。 文藝復興時期，經典創作「聖彼得大教堂」花了 120 年的時間建造，由多位大師共同創作而成，很像是 Web 2.0 時代的「共筆」或是「協作」。Linux kernel 是網際網路時代，社群協作的重要創作之一。今天我們使用的 Android 手機，都是運行於 Linux kernel 軟體之上。 聖彼得大教堂，肯定是背包客必定點名的景點，這是天主教最神聖的地方。聖彼得大教堂花了這麼久的時間才完工，當然不可能是由同一位建築師獨立完成，參與聖彼得大教堂設計的建築師有勃拉芒特、拉斐爾、米開朗基羅、小莎迦洛，這也是聖彼得大教堂的特色；現今，自由軟體界，稱重要且具代表性的 developer 為「大神」。感謝以上四位大神的共同協作，讓我們在 700 年後的今天，能親眼目睹這個偉大的建築，能欣賞到令人嘆為觀止的繪畫與雕刻。 文藝復興運動，就像 Internet/WWW 的出現，以及後來的...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[                              <p>自由，而不是免費啤酒 (註1)。</p>

<blockquote><em>Rinascimento, FOSS or FLOSS (free/libre/open source software) </em></blockquote>

<p>神權至上的時期，被稱為「黑暗時期」，在 14 世紀興起的「文藝復興」運動，打破這個現象。也就是說，黑暗時代，神權至上，可能有很多像是「魔法」的東西，或是很多霍格華茲魔法學校（註：哈利波特的學校）；文藝復興後，很多近代科學開始發展，生活在此時期後的人類，哈利波特稱之為麻瓜（Muggle，指沒有魔法的人）。</p>

<p>在 13 世紀晚期，義大利中產階段因為生活上的富足，開始尋求更優雅與時尚的生活，於是萠生「脫離神權」的想法。知名詩人「但丁（1265-1321）」的出現，被認為是義大利文藝復興時代的開始。於是，「個人主義」，也就是文藝復興運動的重要產物之一，開始發展。許多耳熟能詳的「大師」，也在文藝復興時期開始出現，例如：米開朗基羅（<a href="http://www.epochtimes.com/b5/6/6/21/n1186091.htm" target="_blank"><strike>忍者龜</strike></a>）；天文學、物理學、數學、生物學等，高中時期最令我頭痛的近代科學，有了重要的發展。</p>

<p>用近代的網路現象來比喻，文藝復興運動很像是 Web 2.0。出現很多新現象，例如：個人主義的興起，每個人都可以自由創作，發表成果，這裡的「個人主義」指的是「好的」個人主義，例如：分享、討論、知識交換，而不是自私的這種個人主義。</p>

<p>文藝復興時期，經典創作「聖彼得大教堂」花了 120 年的時間建造，由多位大師共同創作而成，很像是 Web 2.0 時代的「共筆」或是「協作」。Linux kernel 是網際網路時代，社群協作的重要創作之一。今天我們使用的 Android 手機，都是運行於 Linux kernel 軟體之上。</p>

<p>聖彼得大教堂，肯定是背包客必定點名的景點，這是天主教最神聖的地方。聖彼得大教堂花了這麼久的時間才完工，當然不可能是由同一位建築師獨立完成，參與聖彼得大教堂設計的建築師有勃拉芒特、拉斐爾、米開朗基羅、小莎迦洛，這也是聖彼得大教堂的特色；現今，自由軟體界，稱重要且具代表性的 developer 為「大神」。感謝以上四位大神的共同協作，讓我們在 700 年後的今天，能親眼目睹這個偉大的建築，能欣賞到令人嘆為觀止的繪畫與雕刻。</p>

<p>文藝復興運動，就像 Internet/WWW 的出現，以及後來的 Web 2.0 與開放源碼運動（Open Source Movement）一樣，影響全人類的生活與文化發展。近年來，手機也從封閉走向開放，以及「個人創作手機軟體」的運動發展，相信只要再 1~2 年的時間，我們的生活與文化，都會產生很大的改變。</p>

<p>自由軟體，打破「軟體黑暗時期」；每個人都能在手機上創作內容，也將打破「手機黑暗時期」。軟體黑暗時期？據可靠資料，可能指微x時期。</p>

<p>註1：這句話來自於 Richard M. Stallman 大師，對於自由軟體的自由「Free」之 [<a href="http://en.wikipedia.org/wiki/Gratis_versus_Libre" target="_blank">解釋</a>]。</p>
]]>
      
   </content>
</entry>
<entry>
   <title>Android SystemServer 對 Linux 驅動程式程式碼風格的影響，一個簡單的概念</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/07/how-android-systemserver-change-code-style-of-linux-driver.html" />
   <id>tag:www.jollen.org,2010:/blog//2.712</id>
   
   <published>2010-07-07T16:02:36Z</published>
   <updated>2010-07-07T21:26:34Z</updated>
   
   <summary>今天為一家國際手機廠進行 Android 底層相關的內訓，課堂中提到一個概念，就是基於 Android 的 SystemServer 架構，可以藉由「架構面」改善過去 Linux 驅動程式在 Rentrant Code 議題面的程式碼模式。藉由模式的調整，可改善程式碼的效率。 過去，多個 Process 同時（Concurrency）存取同一份 Linux 驅動程式時，若驅動程式進行 Re-scheduling 操作，驅動程式的 Driver Method 就會重覆進入，因此需要考量做同步控制。 若是藉由 SystemServer 的架構，也就是「Single Process 存取驅動程式」，就能簡化重覆進入的議題。如下圖所示。 這是一個很簡單的模型，在 Middleware 層面，透過「限制應用程式的模式」來達到簡化重覆進入的議題。以 Android 作業系統為例，SystemServer 可以扮演這個「Single Process」的角色。當然，也可以設計成一個獨立的「My SystemServer」，根據對問題的分析來決定要修改 SystemServer，或是建立 My SystemServer。 對應用程式來說，只需要透過 IPC...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Linux Device Drivers &amp; Kernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[今天為一家國際手機廠進行 Android 底層相關的內訓，課堂中提到一個概念，就是基於 Android 的 SystemServer 架構，可以藉由「架構面」改善過去 Linux 驅動程式在 Rentrant Code 議題面的程式碼模式。藉由模式的調整，可改善程式碼的效率。

過去，多個 Process 同時（Concurrency）存取同一份 Linux 驅動程式時，若驅動程式進行 Re-scheduling 操作，驅動程式的 Driver Method 就會重覆進入，因此需要考量做同步控制。

若是藉由 SystemServer 的架構，也就是「Single Process 存取驅動程式」，就能簡化重覆進入的議題。如下圖所示。

<img alt="android-linux-driver-model.png" src="http://www.jollen.org/blog/2010/07/08/android-linux-driver-model.png" width="378" height="454" />

這是一個很簡單的模型，在 Middleware 層面，透過「限制應用程式的模式」來達到簡化重覆進入的議題。以 Android 作業系統為例，SystemServer 可以扮演這個「Single Process」的角色。當然，也可以設計成一個獨立的「My SystemServer」，根據對問題的分析來決定要修改 SystemServer，或是建立 My SystemServer。

對應用程式來說，只需要透過 IPC 與 SystemServer 溝通即可。當 SystemServer 需要交付資料（Data）給應用程式（Clients）時，可以採取下列二種方式：

1. Message & Handler
2. 註冊 Listener、由 SystemServer Callback

目前，正在進行「Android HAL & Framework：軟硬整合實作訓練」課程的第三次修訂，將會加入這個主題，以實例介紹 Android 框架如何影響 Linux 驅動程式的程式碼寫作風格，希望能在驅動程式的程式碼優化方面進行討論。]]>
      
   </content>
</entry>
<entry>
   <title>最近的新玩具，研發中的 Android 手機</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/06/my-new-android-solution.html" />
   <id>tag:www.jollen.org,2010:/blog//2.711</id>
   
   <published>2010-06-30T15:46:33Z</published>
   <updated>2010-06-30T21:06:44Z</updated>
   
   <summary>最近有關 Android 的大新聞，大概就是 Froyo 的發佈消息了。有在關心 Android 部落格的朋友應該都已經都看到這則消息了，Android 2.2（Froyo）的程式碼已經正式發佈，除了釋出大家最關心的 Dalvik JIT Compiler 外，也加入了 V8 Javascript Engine。又有工作要做囉。 小弟也順勢發佈一張即將推出的一款 Android 樣機照片，目前這款樣機已進入試產階段，不過，這是一個解決方案平臺，並不是正式發行的終端產品。 未來，使用這個平臺，將可以達到一些快速開發的需求。在這款平臺上，也會進行一些 Enhanced API 的開發，以協助廠商開發自有特色的應用軟體。目前正在持續進行產品的規劃，以及後續的開發準備工作。希望能加速技術面的發展，未來才能繼續和大家分享最新進展。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[最近有關 Android 的大新聞，大概就是 Froyo 的發佈消息了。有在關心 Android 部落格的朋友應該都已經都看到這則消息了，Android 2.2（Froyo）的程式碼已經正式發佈，除了釋出大家最關心的 Dalvik JIT Compiler 外，也加入了 V8 Javascript Engine。又有工作要做囉。

小弟也順勢發佈一張即將推出的一款 Android 樣機照片，目前這款樣機已進入試產階段，不過，這是一個解決方案平臺，並不是正式發行的終端產品。

<img alt="zinn-phone.jpg" src="http://www.jollen.org/blog/2010/06/30/zinn-phone.jpg" width="253" height="434" />

未來，使用這個平臺，將可以達到一些快速開發的需求。在這款平臺上，也會進行一些 Enhanced API 的開發，以協助廠商開發自有特色的應用軟體。目前正在持續進行產品的規劃，以及後續的開發準備工作。希望能加速技術面的發展，未來才能繼續和大家分享最新進展。]]>
      
   </content>
</entry>
<entry>
   <title>MeeGo 1.1 展新頁，首屆 MeeGo 研討會將於11月份舉辦</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/06/meego-get-new-page-started-in-handsets.html" />
   <id>tag:www.jollen.org,2010:/blog//2.710</id>
   
   <published>2010-06-23T14:44:47Z</published>
   <updated>2010-06-23T20:13:06Z</updated>
   
   <summary>MeeGo 開始 1.1 版的開發了。 今年二月份才剛宣佈的 MeeGo 作業系統，已經進入 1.1 版的重要階段了。由 Moblin 與 Maemo 二個 software stack 所合成的 MeeGo 作業系統，最初的焦點是放在 Netbook 硬體，主要在提供更好的使用者經驗。 根據 MeeGo 的 roadmap 指出，今年十月將釋出 MeeGo 1.1。新版本的 MeeGo 將會佈署重兵在「Handset」裝置，令人期待，相信會是一個重要的發行版本。另外，手機作業系統整合「Web Runtime」已經是一個大趨勢了，MeeGo 1.1 也不缺席，根據 MeeGo 官方發佈的 Roadmap 來看，MeeGo 1.1 將加入 Web Runtime...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[MeeGo 開始 1.1 版的開發了。

今年二月份才剛宣佈的 MeeGo 作業系統，已經進入 1.1 版的重要階段了。由 Moblin 與 Maemo 二個 software stack 所合成的 MeeGo 作業系統，最初的焦點是放在 Netbook 硬體，主要在提供更好的使用者經驗。

根據 MeeGo 的 roadmap 指出，今年十月將釋出 MeeGo 1.1。新版本的 MeeGo 將會佈署重兵在「Handset」裝置，令人期待，相信會是一個重要的發行版本。另外，手機作業系統整合「Web Runtime」已經是一個大趨勢了，MeeGo 1.1 也不缺席，根據 MeeGo 官方發佈的 Roadmap 來看，MeeGo 1.1 將加入 Web Runtime 功能，更令人引頸期盼。

目前，在 Android 作業系統上發展 Web Runtime 最著名的專案是 JIL 實驗室的「JIL Mobile Widget」技術。筆者過去曾經撰文「<a href="http://www.ophonesdn.com/article/show/184" target="_blank">JIL Mobile Widget: 我的第一堂课</a>」介紹過 JIL Mobile Widget 的概念。目前已經搭載 JIL Mobile Widget 技術的手機平臺，就是知名的「OPhone」作業系統。

「Web Runtime」簡單來說，「就是以 HTML 5 來撰寫手機應用程式」，也就是改變了手機應用開發的模式。例如：「把 jQuery + CSS 拿來寫手機程式」，就是典型的代表。

MeeGo 從六月份開始進入「Open Development Builds」階段，同時，「Handset User Experience Develoipment」也進入開放發展階段。MeeGo 官方也於6月22日宣佈，第一次的 MeeGo 研討會將於今年11月15-17日，一連三天於愛爾蘭舉辦，相信會是重要的一場發佈活動。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 系統管理雜記, #4: C 如何取得 property</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/05/android-getproperty-using-c.html" />
   <id>tag:www.jollen.org,2010:/blog//2.709</id>
   
   <published>2010-05-21T10:19:15Z</published>
   <updated>2010-05-22T10:06:56Z</updated>
   
   <summary>上一則日記提到 Android property 的設定。在 Android 作業系統裡，取得 property 是很重要的工作。不管是 Android 框架層（使用 Java 語言），或是 Native 層（使用 C/C++ 語言），都可以看到讀取 property 的程式碼。 以下是一段簡單的範例程式，用以說明如何用 C 來讀取 Android 系統的 property： /* * Copyright (C) 2010 The Mokoid Open Source Project * * Licensed under the Apache...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[上一則日記提到 Android property 的設定。在 Android 作業系統裡，取得 property 是很重要的工作。不管是 Android 框架層（使用 Java 語言），或是 Native 層（使用 C/C++ 語言），都可以看到讀取 property 的程式碼。

以下是一段簡單的範例程式，用以說明如何用 C 來讀取 Android 系統的 property：

<pre><blockquote>/*
 * Copyright (C) 2010 The Mokoid Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
  
#define LOG_TAG "LED Stub"
  
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;unistd.h&gt;
#include &lt;assert.h&gt;
  
#include &lt;jni.h&gt;
#include &lt;mokoid/led.h&gt;
#include &lt;cutils/properties.h&gt;
  
#define HAL_DEFAULT_VARIANT     "default"
  
static const char *variant_keys[] = {
    "ro.hardware",  /* This goes first so that it can pick up a different file on the emulator. */
    "ro.product.board",
    "ro.board.platform",
    "ro.arch"
};
#define HAL_VARIANT_KEYS_COUNT  (sizeof(variant_keys)/sizeof(variant_keys[0]))
  
int main()
{
    int i;
    int status;
    char prop[PATH_MAX];
  
    status = -EINVAL;
  
    for (i = 0; (status != 0) && (i < HAL_VARIANT_KEYS_COUNT); i++) {
        if (property_get(variant_keys[i], prop, NULL) == 0) {
	    continue;
        }
        printf("Your property is: %s = %s\n", variant_keys[i], prop);
    }
  
  return 0;
}</blockquote></pre>

上述範例，是由 libhardware 的程式碼修改而成。HAL (即 libhardware) 會讀取以下四個 property：

<ul><li>ro.hardware</li>
<li>ro.product.board</li>
<li>ro.board.platform</li>
<li>ro.arch</li></ul>

習慣上，我們會以 "ro.product.board" 做為 HAL 模組的 "product name"，ro.product.board 決定 HAL 模組的命名方式。例如，當 ro.product.board 為 "mokoid" 時，我們就必須將 HAL 模組命名為 *.mokoid.so，並存放於 system/lib/hw 目錄下。]]>
      
   </content>
</entry>
<entry>
   <title>更新 MokoidBoard (DMA-6410L) 至 Android 2.1 (Eclair)</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/05/update-mokoidboard-to-eclair.html" />
   <id>tag:www.jollen.org,2010:/blog//2.708</id>
   
   <published>2010-05-11T04:24:20Z</published>
   <updated>2010-05-11T11:35:44Z</updated>
   
   <summary>MokoidBoard 是基於 DMA-6410L (S3C6410) 的一款開發板，目前使用在仕橙3G教室的大部份訓練課程裡，目前已經將 Android 2.1 (Eclair) 移植至 MokoidBoard 上。開發板使用者或是課程學員，同樣請使用 [Mokoid] product tree 即可編譯。 升級 Android 2.1 步驟如下 以下步驟提供給 MokoidBoard 使用者參考。依此步驟即可將您的 MokoidBoard 升級 Android 2.1。 圖一：Android 2.1 圖二：Home Screen 1. 準備 Android 1.6 原始碼 請備妥 MokoidBoard CD，將 Android 1.6...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[MokoidBoard 是基於 DMA-6410L (S3C6410) 的一款開發板，目前使用在仕橙3G教室的大部份訓練課程裡，目前已經將 Android 2.1 (Eclair) 移植至 MokoidBoard 上。開發板使用者或是課程學員，同樣請使用 [<a href="http://www.jollen.org/blog/2010/02/mokoid-project-is-up.html" target="_blank">Mokoid</a>] product tree 即可編譯。

<strong>升級 Android 2.1 步驟如下</strong>

以下步驟提供給 MokoidBoard 使用者參考。依此步驟即可將您的 MokoidBoard 升級 Android 2.1。

<img src="http://www.jollen.org/blog/2010/05/11/mokoidboard-eclair-4.jpg" />
圖一：Android 2.1

<img src="http://www.jollen.org/blog/2010/05/11/mokoidboard-eclair-5.jpg" />
圖二：Home Screen

<strong>1. 準備 Android 1.6 原始碼</strong>

請備妥 MokoidBoard CD，將 Android 1.6 (Donut) 取原始碼取出，並解壓縮。

<strong>2. 取得 Mokoid 分支</strong>

將 Mokoid 分支取出，擺放到 vendor/ 目錄下：

<blockquote>$ svn co http://mokoid.googlecode.com/svn/trunk/ mokoid
</blockquote>
Android 以 product tree 方式維護分支與編譯程式碼，請確保 mokoid 分支存在於 vendor/ 目錄下。

<strong>3. 取得 DMA-6410L 的 LED Stub</strong>

Mokoid 上的 LED Stub 為骨架，依開發板硬體，須填入 system call 程式碼。文後附上一個給 DMA-6410L 的 LED Stub 原始碼。

<strong>4. 保留 BatteryService 實作</strong>

請注意，由於 Android 2.1 的 BatteryService native 實作上做了變更。因此，我們先將 1.6 版的 BatteryService natvie 實作備份下來：

<blockquote>$ cp frameworks/base/services/jni/com_android_server_BatteryService.cpp /tmp</blockquote>

待更新至 2.1 版後，再將 1.6 的實作放回 source tree。Android 2.1 在 BatteryService native 端，主要的變動是修改了 sysfs 的讀取方式。

<strong>4. 更新至 Android 2.1 版</strong>

依照 [<a href="http://source.android.com/download" target="_blank">Android 網站</a>] 上的說明，安裝 repo。接著使用 repo 直接取回 Android 2.1 的程式碼即可：

<blockquote>$ cd &lt;path-to-your-android-source&gt;/<br />
$ repo sync</blockquote>

將 com_android_server_BatteryService.cpp  放回 source tree：

<blockquote>$ cp /tmp/com_android_server_BatteryService.cpp frameworks/base/services/jni/com_android_server_BatteryService.cpp
</blockquote>
<strong>5. 編譯 Mokoid Product Tree</strong>

編譯 Android image：

<blockquote>$ make PRODUCT-dma6410xp-eng
</blockquote>
<strong>6. 打包 ramdisk.img</strong>

將編譯完成的 ramdisk.img 包裝成 u-boot 格式：

<blockquote>$ mkimage -A arm -O linux -T ramdisk -C none -a 0x50800000 -n "ramdisk" -d ramdisk.img ramdisk-uboot.img
</blockquote>
將 system.img 與 ramdisk-uboot.img 拷貝到 tftp 根目錄下，並設定好開發板的 tftp 環境。

<strong>7. 更新至 Android 2.1</strong>

最後將 system.img 與 ramdisk-uboot.img 燒錄至 MokoidBoard 即可：

<pre>U-Boot 1.1.6 (Jan 21 2010 - 08:58:14) for SMDK6410                              
                                                                                
                                                                                
CPU:     S3C6410@666MHz                                                         
         Fclk = 666MHz, Hclk = 166MHz, Pclk = 83MHz, Serial = CLKUART (ASYNC Mo 
Board:   SMDK6410                                                               
DRAM:    128 MB                                                                 
Flash:   0 kB                                                                   
NAND:    128 MB                                                                 
In:      serial                                                                 
Out:     serial                                                                 
Err:     serial                                                                 
Initialise LCD with values                                                      
Hit any key to stop autoboot:  0                                                
<strong>SMDK6410 # run system   </strong>                                                        
dm9000 i/o: 0x30000300, id: 0x90000a46                                          
MAC: 00:40:5c:26:0a:5b                                                          
could not establish link                                                        
TFTP from server 10.0.1.24; our IP address is 10.0.1.25                         
<strong>Filename 'system.img'.                                                          </strong>
Load address: 0x50008000                                                        
Loading: T ####################################
...
done                                                                            
Bytes transferred = 59174016 (386ec80 hex)                                      
                                                                                
NAND erase: device 0 offset 0xa00000, size 0x4300000                            
Erasing at 0x4ce0000 -- 100% complete.                                          
OK                                                                              
                                                                                
NAND write: device 0 offset 0xa00000, size 0x386ec80                            
                                                                                
Writing data at 0x40b8800 -- 100% complete.                                     
 59174016 bytes written: OK       
<strong>SMDK6410 # run ramdisk_uboot         </strong>                                           
dm9000 i/o: 0x30000300, id: 0x90000a46                                          
MAC: 00:40:5c:26:0a:5b                                                          
could not establish link                                                        
TFTP from server 10.0.1.24; our IP address is 10.0.1.25                         
<strong>Filename 'ramdisk-uboot.img'.  </strong>                                                 
Load address: 0x50008000                                                        
Loading: ################################                                       
done                                                                            
Bytes transferred = 158894 (26cae hex)                                          
                                                                                
NAND erase: device 0 offset 0x900000, size 0x100000                             
Erasing at 0x9e0000 -- 100% complete.                                           
OK                                                                              
                                                                                
NAND write: device 0 offset 0x900000, size 0x100000                             
 1048576 bytes written: OK          </pre>

<img src="http://www.jollen.org/blog/2010/05/11/mokoidboard-eclair-1.jpg" />
圖三：更新完成、啟動 MokoidBoard

<img src="http://www.jollen.org/blog/2010/05/11/mokoidboard-eclair-2.jpg" />
圖四：執行 LedTest 範例、LED 燈初始化狀況為全滅

<img src="http://www.jollen.org/blog/2010/05/11/mokoidboard-eclair-3.jpg" />
圖五：點亮 LED 1

<strong>DMA-6410L 的 LED Stub 原始碼</strong>

以下是 led.c 的原始碼，支援 DMA-6410L 的 LED 控制：

<pre>/*
 * Copyright (C) 2009 Mokoid Open Source Project
 * Copyright (C) 2009 Moko365 Inc
 * 
 * Author: Jollen Chen &lt;jollen@jollen.org&gt;
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
#define LOG_TAG "MokoidLedStub"
 
#include &lt;hardware/hardware.h&gt;
 
#include &lt;fcntl.h&gt;
#include &lt;errno.h&gt;
 
#include &lt;cutils/log.h&gt;
#include &lt;cutils/atomic.h&gt;
 
#include &lt;mokoid/led.h&gt;
 
/**
 * Definition of kernel-space driver.
 */
#define	LED_DEVICE	"/dev/led"
#define	LED_C608	1
#define	LED_C609	2
 
static int led_device_close(struct hw_device_t* device)
{
	struct led_control_device_t* ctx = (struct led_control_device_t*)device;
 
	if (ctx) {
		close(ctx->fd);
		free(ctx);
	}
	return 0;
}
 
static int led_on(struct led_control_device_t *dev, int32_t led)
{
	int fd;
 
	LOGI("LED Stub: set %d on.", led);
	fd = dev->fd;
 
	switch (led) {
		case LED_C608: 
			ioctl(fd, 1, &led);
			break;
		case LED_C609:
			ioctl(fd, 1, &led);
			break;
		default:
			return -1;
	}
 
	return 0;
}
 
static int led_off(struct led_control_device_t *dev, int32_t led)
{
	int fd;
 
	LOGI("LED Stub: set %d off.", led);
	fd = dev->fd;
 
	switch (led) {
		case LED_C608: 
			ioctl(fd, 2, &led);
			break;
		case LED_C609:
			ioctl(fd, 2, &led);
			break;
		default:
			return -1;
	}
 
	return 0;
}
 
static int led_device_open(const struct hw_module_t* module, const char* name,
        struct hw_device_t** device) 
{
	struct led_control_device_t *dev;
 
	dev = (struct led_control_device_t *)malloc(sizeof(*dev));
	memset(dev, 0, sizeof(*dev));
 
	dev->common.tag =  HARDWARE_DEVICE_TAG;
	dev->common.version = 0;
	dev->common.module = module;
	dev->common.close = led_device_close;
 
	dev->set_on = led_on;
	dev->set_off = led_off;
 
	*device = &dev->common;
 
	/*
         * Initialize Led hardware here.
         */
        dev->fd = open(LED_DEVICE, O_RDONLY);
	if (dev->fd < 0) 
	    dev->fd = 2;   /* Error Handler */
 
	led_off(dev, LED_C608);
	led_off(dev, LED_C609);
 
success:
	return 0;
}
 
static struct hw_module_methods_t led_module_methods = {
    open: led_device_open
};
 
const struct led_module_t HAL_MODULE_INFO_SYM = {
    common: {
        tag: HARDWARE_MODULE_TAG,
        version_major: 1,
        version_minor: 0,
        id: LED_HARDWARE_MODULE_ID,
        name: "Sample LED Stub",
        author: "The Mokoid Open Source Project",
        methods: &led_module_methods,
    }
 
    /* supporting APIs go here. */
};</pre>

新版的 led.h 設計：

<pre>/*
 * Copyright (C) 2009 Mokoid Open Source Project
 * Copyright (C) 2009 Moko365 Inc
 * 
 * Author: Jollen Chen &lt;jollen@jollen.org&gt;
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
#include &lt;hardware/hardware.h&gt;
 
#include &lt;fcntl.h&gt;
#include &lt;errno.h&gt;
 
#include &lt;cutils/log.h&gt;
#include &lt;cutils/atomic.h&gt;
 
/***************************************************************************/
 
struct led_module_t {
   struct hw_module_t common;
};
 
struct led_control_device_t {
   struct hw_device_t common;
 
   /* attributes */
   int fd;
 
   /* supporting control APIs go here */
   int (*set_on)(struct led_control_device_t *dev, int32_t led);
   int (*set_off)(struct led_control_device_t *dev, int32_t led);
};
 
/***************************************************************************/
 
struct led_control_context_t {
	struct led_control_device_t device;
};
 
#define LED_HARDWARE_MODULE_ID "led"</pre>

<strong>下載原始碼</strong>

<ul>
<li><a href="http://www.jollen.org/blog/2010/05/11/led.dma6410xp.c" target="_blank">led.c</a></li>
<li><a href="http://www.jollen.org/blog/2010/05/11/led.h" target="_blank">led.h</a></li>
</ul>
]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 系統管理雜記, #3: init.rc 與 setprop</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/04/android-initrc-setprop.html" />
   <id>tag:www.jollen.org,2010:/blog//2.707</id>
   
   <published>2010-04-24T13:57:27Z</published>
   <updated>2010-04-24T19:21:40Z</updated>
   
   <summary>今天在上海進行「Android Framework &amp; HAL 軟硬整合」培訓課程，課程中提到 init.rc 的用途，因此在此做一個紀錄。init.rc 是 Android 作業系統的 initial script，在開機時由 init 讀取並執行 init.rc 裡的命令。Android 的 init.rc 使用的的語法稱為 Android init language，有別於傳統 Embedded Linux 採用 shell script 的方式。 在 init.rc 裡找到類似以下的命令片斷： on boot setprop ro.FOREGROUND_APP_ADJ 0 setprop ro.VISIBLE_APP_ADJ 1 setprop...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[今天在上海進行「Android Framework & HAL 軟硬整合」培訓課程，課程中提到 init.rc 的用途，因此在此做一個紀錄。init.rc 是 Android 作業系統的 initial script，在開機時由 init 讀取並執行 init.rc 裡的命令。Android 的 init.rc 使用的的語法稱為 Android init language，有別於傳統 Embedded Linux 採用 shell script 的方式。

在 init.rc 裡找到類似以下的命令片斷：

<pre>on boot
    setprop ro.FOREGROUND_APP_ADJ 0
    setprop ro.VISIBLE_APP_ADJ 1
    setprop ro.SECONDARY_SERVER_ADJ 2
    ...</pre>

以上是一個動作（action）區段的設定，說明如下：

1. on boot 表示在開機時（boot）觸發此動作區段裡的所有命令。
2. setprop 是設定 Android property 的命令。

上述提及的「動作區段」設定格式如下：

<pre>on &lt;trigger&gt;
   &lt;command&gt;
   &lt;command&gt;
   &lt;command&gt;</pre>

當 "trigger" 為 "boot" 時，表示「開機觸發」。一個動作區段裡，可以有任意個命令（command），每個命令獨立於一行。最常見，也最重要的命令就是 'setprop'。'setprop' 用來設定 'property' 的值，property 有點像是系統的「環境變數（environment variable）」。其命令格式如下：

<pre>setprop &lt;name&gt; &lt;value&gt;</pre>

例如：

<pre>setprop ro.product.device dma6410xp</pre>

表示「ro.product.device = "dma6410xp"」的意思。Android 系統有非常多 property，這些 property 都是 Android 作業系統本身在使用的重要變數，例如：上例的「ro.product.board」就是給 HAL 使用的重要變數。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 觀念解析, #1: Zygote Mode</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/04/android-concept-1-zygote-mode.html" />
   <id>tag:www.jollen.org,2010:/blog//2.706</id>
   
   <published>2010-04-05T07:14:32Z</published>
   <updated>2010-04-05T12:25:47Z</updated>
   
   <summary>Android 作業系統開機時，會經由 init.rc 來啟動許多外部程式，其中有一個最重要 process 稱為 Zygote。Zygote 是 Android 的 monitor process，它主要負責二項工作： 1. 啟動 system server 2. 執行 Android 應用程式 「System Server」是由 Zygote 所建立的另外一個 process，建立 system server 的方式是使用典型的 Linux system call - fork()。當 Zygote 成功建立 system server 後，便進入 socket listening...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      Android 作業系統開機時，會經由 init.rc 來啟動許多外部程式，其中有一個最重要 process 稱為 Zygote。Zygote 是 Android 的 monitor process，它主要負責二項工作：

1. 啟動 system server
2. 執行 Android 應用程式

「System Server」是由 Zygote 所建立的另外一個 process，建立 system server 的方式是使用典型的 Linux system call - fork()。當 Zygote 成功建立 system server 後，便進入 socket listening 模式。在此模式下，zygote 會監聽（listen）由 socket 所傳入的「命令」，並依據命令的內容啟動 Android 應用程式。

Zygote 啟動外部 Android 應用程式的方式，同樣是使用 Linux kernel 所提供的 fork() system call。因此，在 socket 做 listening，並依據命令來 fork() 並執行外部 Android 應用程式，稱之為「Zygote Mode」。
      
   </content>
</entry>
<entry>
   <title>iSuppli公佈2009年全球手機出貨量</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/03/isuppli-2009-phone-global-market.html" />
   <id>tag:www.jollen.org,2010:/blog//2.705</id>
   
   <published>2010-03-26T08:50:13Z</published>
   <updated>2010-03-26T14:09:27Z</updated>
   
   <summary>iSuppli在2月25日公佈了2009年手機出貨量研究報告，其中包含了關於全球市場與中國市場的統計。簡單摘錄重點數字如下： 1. 2009年全球整體手機出貨量為12億部 2. 承上，中國整體出貨量為4.04億部，佔整體份額33.7%，達三之一 3. 承上，首次來到4.0億部的規模 4. 承上，以成長率來看，到二零一二年，中國整體出貨量將來到5.0億部 5. 在中國的手機業產裡，「手機設計」公司是相當重要的一個環節。二零零九年，由手機設計公司出貨的手機為2.44億部，佔中國整體出貨量的60%，意謂著，有超過一半的手機是由手機設計服務公司出貨。 當然，上述的4.04億部，還包含了「外銷」手機；若以「本土銷售」來計算，數量大約是2.4億部。2010年本土銷售預測成長為11%，即2.66億部，這是feature phone加smart phone的數字，若只計算smart phone的銷售，2010年smart phone的出貨量是2600萬部以上。近期曾看到有關smart phone與feature phone的成長預測報告，但未有正式數據，故不引用。 中國的手機設計服務公司扮演大推手 這些手機設計服務公司的商業模式是，直接為白牌或本土品牌提供設計方案，例如：手機板 (PCBA)。手機設計服務公司具備高效率與客製化服務能力，成為中國手機產業的重要成長推手。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[iSuppli在2月25日公佈了2009年手機出貨量研究報告，其中包含了關於全球市場與中國市場的統計。簡單摘錄重點數字如下：

1. 2009年全球整體手機出貨量為12億部
2. 承上，中國整體出貨量為4.04億部，佔整體份額33.7%，達三之一
3. 承上，首次來到4.0億部的規模
4. 承上，以成長率來看，到二零一二年，中國整體出貨量將來到5.0億部

<img alt="2009-phone-global-market.png" src="http://www.jollen.org/blog/2010/03/26/2009-phone-global-market.png" width="463" height="340" />

5. 在中國的手機業產裡，「手機設計」公司是相當重要的一個環節。二零零九年，由手機設計公司出貨的手機為2.44億部，佔中國整體出貨量的60%，意謂著，有超過一半的手機是由手機設計服務公司出貨。

當然，上述的4.04億部，還包含了「外銷」手機；若以「本土銷售」來計算，數量大約是2.4億部。2010年本土銷售預測成長為11%，即2.66億部，這是feature phone加smart phone的數字，若只計算smart phone的銷售，2010年smart phone的出貨量是2600萬部以上。近期曾看到有關smart phone與feature phone的成長預測報告，但未有正式數據，故不引用。

<strong>中國的手機設計服務公司扮演大推手</strong>

這些手機設計服務公司的商業模式是，直接為白牌或本土品牌提供設計方案，例如：手機板 (PCBA)。手機設計服務公司具備高效率與客製化服務能力，成為中國手機產業的重要成長推手。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android Framework in a Nutshell：台北場演講順利舉辦</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/03/jollen-android-framework-nutshell-taipei.html" />
   <id>tag:www.jollen.org,2010:/blog//2.704</id>
   
   <published>2010-03-24T03:49:36Z</published>
   <updated>2010-03-24T09:24:55Z</updated>
   
   <summary>幾個月前的一則日記，紀錄了「堅果殼精神」的起源，經過數個月的籌劃，第一場「Jollen 的 Android Framework in a Nutshell」演講終於順利結束。距離 [Android Framework in A Nutshell 講題規劃完畢]，到第一場演講正式舉辦，間隔近一個半月的時間，感謝協助本活動的幾位幕後人員，才能使這個活動順利進行。 這次的演講，除了以提及的「堅果殼」精神分享技術研究心得外，也在實現另外一個自已的理念：以半課程形式呈現演講。 半課程形式的意思是，以演講的舉辦形式，加上課程形式的內容，融合演出。演講活動，是啟發思考不可或缺的活動，一場好的演講，有時扣人心弦、有時發人省思，講者也能儘情演出、暢談自已的理念；課程或教育訓練，則是在傳遞知識，設法以授課技巧或教育方法，達到潛移默化的效果，這是授業者的工作。形式與目的大有不同。 如果「演講」又要能達到一部份「課程」的效果，就必須專注在內容本身，也就是著重於技術本身的說明；同時，事前的妥善規劃也很重要。主題的規劃必須客觀大於主觀，才能有課程的感覺。再者，這種形式，讓講者能以更輕鬆的方式進行，就像演講般，帶入一些個人想法，或是加入一些經驗談。 當天也向與會朋友預告了「Dalvik VM in A Nutshell」，希望工作之餘，繼續經營這顆堅果殼。 延伸閱讀 * 2010.1.3: 「Jollen 的 Android Framework in a Nutshell」演講 * 2010.1.26: 「Jollen 的 Android Framework in a Nutshell...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[幾個月前的一則日記，紀錄了「<a href="http://www.jollen.org/blog/2010/01/jollen-android-in-a-nut-shell.html">堅果殼精神</a>」的起源，經過數個月的籌劃，第一場「Jollen 的 Android Framework in a Nutshell」演講終於順利結束。距離 [<a href="http://www.jollen.org/blog/2010/01/android-framework-in-a-nuthsell-preview.html">Android Framework in A Nutshell 講題規劃完畢</a>]，到第一場演講正式舉辦，間隔近一個半月的時間，感謝協助本活動的幾位幕後人員，才能使這個活動順利進行。

這次的演講，除了以提及的「堅果殼」精神分享技術研究心得外，也在實現另外一個自已的理念：以半課程形式呈現演講。

<img src="http://www.moko365.com/project/android-framework-taipei/Android_Taipei_files/shapeimage_1.png" />

半課程形式的意思是，以演講的舉辦形式，加上課程形式的內容，融合演出。演講活動，是啟發思考不可或缺的活動，一場好的演講，有時扣人心弦、有時發人省思，講者也能儘情演出、暢談自已的理念；課程或教育訓練，則是在傳遞知識，設法以授課技巧或教育方法，達到潛移默化的效果，這是授業者的工作。形式與目的大有不同。

如果「演講」又要能達到一部份「課程」的效果，就必須專注在內容本身，也就是著重於技術本身的說明；同時，事前的妥善規劃也很重要。主題的規劃必須客觀大於主觀，才能有課程的感覺。再者，這種形式，讓講者能以更輕鬆的方式進行，就像演講般，帶入一些個人想法，或是加入一些經驗談。

當天也向與會朋友預告了「Dalvik VM in A Nutshell」，希望工作之餘，繼續經營這顆堅果殼。

<strong>延伸閱讀</strong>

* 2010.1.3: <a href="http://www.jollen.org/blog/2010/01/jollen-android-in-a-nut-shell.html">「Jollen 的 Android Framework in a Nutshell」演講</a>
* 2010.1.26: <a href="http://www.jollen.org/blog/2010/01/android-framework-in-a-nuthsell-preview.html">「Jollen 的 Android Framework in a Nutshell 演講」講題規劃完畢</a>
* 2010.2.1: <a href="http://www.jollen.org/blog/2010/02/android-framework-foxconn.html">「Android Framework Introduction」講座</a>]]>
      
   </content>
</entry>
<entry>
   <title>山寨軍品牌革命：下一個山寨影響力</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/03/shenzen-branding-road.html" />
   <id>tag:www.jollen.org,2010:/blog//2.703</id>
   
   <published>2010-03-23T10:02:12Z</published>
   <updated>2010-03-23T15:06:37Z</updated>
   
   <summary>文／Jollen Chen（原文刊登於 CTimes零組件雜誌2010年3月號） 因為聯發科的解決方案、低價手機、不斷創新的外觀設計、龐大的內需市場以及技術螞蟻大軍等要素，造就第一個深圳手機產業的奇觀「山寨機」。在抄襲與非正統的「模式」下所開發與製造的手機，就被暱稱為「山寨機」，意謂拷貝與強取之意。 過去也曾經在本論壇提到的本土品牌廠天宇朗通，是以山寨機起來，轉型為本土品牌製造商的代表。過去一年來，因為受到 Android 開放平臺的影響，讓這批所謂的山寨大軍開始思考國際化與品牌化的道路。Android 作業系統讓這些手機商感受到「自主」的力量，這個力量可以由以下二個技術層面來討論。 第一、開放的作業系統，讓山寨手機商開始有了能「自由使用」的軟體；使用這個開發軟體，便可以不會「直接」受到軟體原廠的控制與限制，在產品開發上有了更大的自由度。第二、開放的作業系統，讓山寨手機商能開始真正思考，「構建自有軟體團隊」的可行性與做法；自有的軟體團隊，可以針對市場或客戶的需求，進行開發與軟體的客製化。 由此看來，「使用上的自由」以及「針對市場做軟體客製化」是山寨轉型需要掌握的二個力量；另人振奮的是，山寨大本營所在的深圳，有了更成熟的產業與資金環境，給了新創自有品牌產品一個難得的好機會。過去山寨品牌化都是個案，現在山寨品牌化已經變成一個現象，氛圍已經形成，許多山寨機製造商對於「自有產品」、「自主解決方案」以及「自有品牌」展現強烈的企圖力，未來將成為不可漠視的力量，山寨大軍的轉型，成為下一個手機產業的關鍵影響力。 山寨品牌化，以及走向國際銷售，供應鍊管理是首要加強的能力。借助台灣供應鍊及供應鍊管理能力，可使山寨品牌化的腳步跨出大步。具體實行上，提昇供應鍊端的價值是必要工作，為不致淪為單純的零件供應商，可以思考幾個具體的做法，由小地方逐步完善。單純就技術面來看，幾個提昇價值的具體做法如下。 第一、提供關鍵零組件更精緻的軟硬整合服務，以服務增加本身價值，並思考開源模式的助益或可能帶來的影響力。第二、提供更完整的平臺解決方案，形式上更像是一個 turnkey key solution 或是公板，這方面台灣有許多掌握關鍵技術的硬體廠，都有很不錯的做法。第三、為產品製造應用軟體，模式上可以和硬體綁定銷售。 山寨大軍若能成功帶起品牌革命，成功走向品牌化與國際化，這個影響力對大家都是有助益的，若能正面看待、樂觀因應，這又是一個開放平臺潮流裡的一個大機會。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      文／Jollen Chen（原文刊登於 CTimes零組件雜誌2010年3月號）

因為聯發科的解決方案、低價手機、不斷創新的外觀設計、龐大的內需市場以及技術螞蟻大軍等要素，造就第一個深圳手機產業的奇觀「山寨機」。在抄襲與非正統的「模式」下所開發與製造的手機，就被暱稱為「山寨機」，意謂拷貝與強取之意。

過去也曾經在本論壇提到的本土品牌廠天宇朗通，是以山寨機起來，轉型為本土品牌製造商的代表。過去一年來，因為受到 Android 開放平臺的影響，讓這批所謂的山寨大軍開始思考國際化與品牌化的道路。Android 作業系統讓這些手機商感受到「自主」的力量，這個力量可以由以下二個技術層面來討論。

第一、開放的作業系統，讓山寨手機商開始有了能「自由使用」的軟體；使用這個開發軟體，便可以不會「直接」受到軟體原廠的控制與限制，在產品開發上有了更大的自由度。第二、開放的作業系統，讓山寨手機商能開始真正思考，「構建自有軟體團隊」的可行性與做法；自有的軟體團隊，可以針對市場或客戶的需求，進行開發與軟體的客製化。

由此看來，「使用上的自由」以及「針對市場做軟體客製化」是山寨轉型需要掌握的二個力量；另人振奮的是，山寨大本營所在的深圳，有了更成熟的產業與資金環境，給了新創自有品牌產品一個難得的好機會。過去山寨品牌化都是個案，現在山寨品牌化已經變成一個現象，氛圍已經形成，許多山寨機製造商對於「自有產品」、「自主解決方案」以及「自有品牌」展現強烈的企圖力，未來將成為不可漠視的力量，山寨大軍的轉型，成為下一個手機產業的關鍵影響力。

山寨品牌化，以及走向國際銷售，供應鍊管理是首要加強的能力。借助台灣供應鍊及供應鍊管理能力，可使山寨品牌化的腳步跨出大步。具體實行上，提昇供應鍊端的價值是必要工作，為不致淪為單純的零件供應商，可以思考幾個具體的做法，由小地方逐步完善。單純就技術面來看，幾個提昇價值的具體做法如下。

第一、提供關鍵零組件更精緻的軟硬整合服務，以服務增加本身價值，並思考開源模式的助益或可能帶來的影響力。第二、提供更完整的平臺解決方案，形式上更像是一個 turnkey key solution 或是公板，這方面台灣有許多掌握關鍵技術的硬體廠，都有很不錯的做法。第三、為產品製造應用軟體，模式上可以和硬體綁定銷售。

山寨大軍若能成功帶起品牌革命，成功走向品牌化與國際化，這個影響力對大家都是有助益的，若能正面看待、樂觀因應，這又是一個開放平臺潮流裡的一個大機會。
      
   </content>
</entry>
<entry>
   <title>HAL Stub 的測試程式範例：Led.c</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/03/write-hal-stub-testbench.html" />
   <id>tag:www.jollen.org,2010:/blog//2.702</id>
   
   <published>2010-03-17T14:52:37Z</published>
   <updated>2010-03-17T20:18:07Z</updated>
   
   <summary>近期進行有關 MokoidBoard 的平臺開發，MokoidBoard 的目的是打造一個「Android 框架與底層」專用的學習平臺，主板的部份是基於 Samsung S3C6410 處理器。目前除了計畫以 S3C6410 打造手機方案外，還有一個一直很想實現的理念：教育訓練方面，提供品質良好、架構完善的範例程式碼。一些 dirty code 對於初步學習，並了解硬體是很有幫助的；但入了門，總是要持續進步、精益求精，研讀架構完善的高品質程式碼，就是煅煉火候的好方法。 目前在 MokoidBoard 上提供的 LedTest 範例，是透過 ServiceManager、LedService 以及 HAL Stub 等觀念所設計的「LED 控制程式」。如圖，LedTest 執行時，會出現一個巨大按鈕，按了後，便會將開發板上的第一個 LED 燈點亮。 範例程式碼並不難讀，比較難懂的是 Android 框架與 HAL 架構的觀念，還有一些設計原理。這些觀念，在上週的 Android Framework in a Nutshell 演講做了一個整體性的介紹。 在開發階段，「如何測試 HAL...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[近期進行有關 MokoidBoard 的平臺開發，MokoidBoard 的目的是打造一個「Android 框架與底層」專用的學習平臺，主板的部份是基於 Samsung S3C6410 處理器。目前除了計畫以 S3C6410 打造手機方案外，還有一個一直很想實現的理念：教育訓練方面，提供品質良好、架構完善的範例程式碼。一些 dirty code 對於初步學習，並了解硬體是很有幫助的；但入了門，總是要持續進步、精益求精，研讀架構完善的高品質程式碼，就是煅煉火候的好方法。

<img alt="mokoid-led.jpg" src="http://www.jollen.org/blog/2010/03/17/mokoid-led.jpg" width="496" height="672" />

目前在 MokoidBoard 上提供的 LedTest 範例，是透過 ServiceManager、LedService 以及 HAL Stub 等觀念所設計的「LED 控制程式」。如圖，LedTest 執行時，會出現一個巨大按鈕，按了後，便會將開發板上的第一個 LED 燈點亮。

範例程式碼並不難讀，比較難懂的是 Android 框架與 HAL 架構的觀念，還有一些設計原理。這些觀念，在上週的 Android Framework in a Nutshell 演講做了一個整體性的介紹。

在開發階段，「如何測試 HAL Stub」其實是另一個很重要題目。因此，隨著 MokoidBoard 進入最後整理階段，Mokoid 範例也將會提供一個 Led.c 測試程式，讓我們能在開發階段以 native 方式進行「HAL Stub 的 API 驗證」，如圖所示。

Led.c 是一個 native 執行檔，執行時會透過 HAL 取得 LED Stub，並以 direct call 方式直接測試 Stub 裡的 API 實作，藉此驗證 Stub 與 kernel-space driver 的硬體控制功能；在未來的演講或是課程裡，將會加入一些「測試程式開發」的主題，請大家不吝指教。



]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 系統管理雜記, #2: Java Package 與 Jar File 對應設定</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/03/java-package-jar-file-mapping.html" />
   <id>tag:www.jollen.org,2010:/blog//2.696</id>
   
   <published>2010-03-02T14:45:09Z</published>
   <updated>2010-03-02T20:56:12Z</updated>
   
   <summary><![CDATA[經由 [Mokoid] 範例，我們可以學習到擴充（Extent）Android 框架的做法。搭配 Product Tree 的方式，我們將 LedManager 與 LedService 二個類別編譯成獨立的 jar 檔（mokoid.jar），mokoid.jar 會被 Android build system 自動佈署到 system.img 裡（system/framework/mokoid.jar）。 因為 mokoid.jar 裡的類別沒有做 preload，並不是「preload class」，所以需要額外的系統設定，才能讓 Android 作業系統找到 LedManager 與 LedService 二個類別。在 Mokoid 範例中，找到一個名為 com.mokoid.server.xml 的設定檔，內容如下： &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;permissions> &lt;library...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[經由 [<a href="http://mokoid.googlecode.com" target="_blank">Mokoid</a>] 範例，我們可以學習到擴充（Extent）Android 框架的做法。搭配 Product Tree 的方式，我們將 LedManager 與 LedService 二個類別編譯成獨立的 jar 檔（mokoid.jar），mokoid.jar 會被 Android build system 自動佈署到 system.img 裡（system/framework/mokoid.jar）。

因為 mokoid.jar 裡的類別沒有做 preload，並不是「preload class」，所以需要額外的系統設定，才能讓 Android 作業系統找到 LedManager 與 LedService 二個類別。在 Mokoid 範例中，找到一個名為 com.mokoid.server.xml 的設定檔，內容如下：

<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;permissions>
    &lt;library name="com.mokoid.server"
            file="/system/framework/mokoid.jar"/&gt;
&lt;/permissions&gt;</pre>

此設定檔的作用為：指定 com.mokoid.server 的相對應 jar 檔。「com.mokoid.server」是 Java package（library name）、mokoid.jar 是檔案。透過 com.mokoid.server.xml 來設定其對應關係，並將此檔案置於 /etc/permissions 目錄下，這是基本的 Android 系統管理。

<strong>延伸閱讀</strong>

<ul>
<li>2010.2.8: <a href="http://www.jollen.org/blog/2010/02/mokoid-project-is-up.html">MOSP: Mokoid Project (Mokoid Open Source Project) 上線</a></li>
</ul>]]>
      
   </content>
</entry>
<entry>
   <title>Override Context.getSystemService()</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/02/override-context-getsystemservice.html" />
   <id>tag:www.jollen.org,2010:/blog//2.700</id>
   
   <published>2010-02-26T14:12:24Z</published>
   <updated>2010-02-26T20:42:03Z</updated>
   
   <summary>Context.getSystemService() 是一個很重要的 API，也是「Android 應用程式控制硬體」的起點。在一個開發項目中，如何擴展 getSystemService() 的實作成為一個重要的課題。 幾天前與客戶進行技術討論時，適巧討論到這個議題，因此在這裡做一個簡單的紀錄與大家分享。應用程式要存取手機上的 Sensor 裝置時，須取得 SensorManager 物件，程式寫法如下： public class mokoidSensor extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); 　 SensorManager sensor = (SensorManager)getSystemService(SENSOR_SERVICE); sensor.getSensors();...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Context.getSystemService() 是一個很重要的 API，也是「Android 應用程式控制硬體」的起點。在一個開發項目中，如何擴展 getSystemService() 的實作成為一個重要的課題。

幾天前與客戶進行技術討論時，適巧討論到這個議題，因此在這裡做一個簡單的紀錄與大家分享。應用程式要存取手機上的 Sensor 裝置時，須取得 SensorManager 物件，程式寫法如下：

<pre>public class mokoidSensor extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        　
        SensorManager sensor = (SensorManager)getSystemService(SENSOR_SERVICE);
        sensor.getSensors();
        /* Do something. */
    }
}</pre>

如果手機上有一個「馬達」裝置，程式碼的寫法，依此邏輯來推論，設想的程式碼會是這樣：

        MotorManager motor = (MotorManager)getSystemService(MOTOR_SERVICE);

只是，AOSP 上的程式碼並無 Motor Service 硬體服務，因此除了加入 MotorManager 與 MotorService 設計外，也要擴充 getSystemService() API。實際能採行的做法很多，這裡討論二種方式：

1. 土方法
2. 符合架構

土方法是一個簡單的方式，直接到 [<a href="http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob_plain;f=core/java/android/app/ApplicationContext.java;hb=HEAD" target="_blank">ApplicationContext.java</a>] 裡把程式碼改掉。這個方式簡單有效，不費勁。

符合架構的方法，是基於「Application Framework 不能修改」的前提下來進行設計。也就是，不要變動 Context 的設計、也不要修改 ApplicationContext 實作。AOSP 的 [<a href="http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob_plain;f=core/java/android/app/Activity.java;hb=HEAD" target="_blank">Activity.java</a>] 以 override 的方式，展示了這個做法：

<pre>    @Override
    public Object getSystemService(String name) {
        if (getBaseContext() == null) {
            throw new IllegalStateException(
                    "System services not available to Activities before onCreate()");
        }
　
        if (WINDOW_SERVICE.equals(name)) {
            return mWindowManager;
        } else if (SEARCH_SERVICE.equals(name)) {
            ensureSearchManager();
            return mSearchManager;
        }
        return super.getSystemService(name);
    }</pre>

因此，改用以下的設計：

<pre>public class mokoidActivity extends Activity {
    ...
    @Override
    public Object getSystemService(String name) {
　
        if (MOTOR_SERVICE.equals(name)) {
            MotorManager mMotorManager = new MotorManager();
            return mMotorManager;
        }
        return <strong>super.getSystemService(name);</strong>
    }	
	...
}</pre>

應用程式的部份也要做修改：

<pre>public class HelloWorld extends <strong>mokoidActivity</strong> {
}</pre>

目前為止，這只是一個想法，尚未實作驗證。

]]>
      
   </content>
</entry>
<entry>
   <title>Android Framework「專案啟動」顧問方案：技術、工程與管理 Start-up 服務</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/02/consulting-android-framework-project-startup.html" />
   <id>tag:www.jollen.org,2010:/blog//2.699</id>
   
   <published>2010-02-14T07:48:36Z</published>
   <updated>2010-02-14T14:59:26Z</updated>
   
   <summary>為什麼要研究 Android Framework？這是一個軟體工程以及專案管理面的問題。Android Framework 是 Application Framework（應用軟體框架），所謂的 Framework 定義上指的是未完成（incomplete）或是不完善（not ready-to-use）的軟體程式庫（嚴格來說是 class library）。 近期收到有關「如何發展 Android 產品」的需求有增多的趨勢，而要解決的最核心問題就是「研究 Android Framework」。雖然目前與一些訓練單位合作，提供許多 Android Framework 方面的課程，但因為都是屬於純技術面，還缺少軟體工程以及專案管理面的內容，尚有不足的地方。 有鑑於此，花費近一個月的時間，整理了一套「標準顧問方案」為企業客戶提供這方面的 On-site 服務，以補齊不足之處。這套顧問方案共分為 5 個層面，並定名為「Android Framework 專案啟動顧問服務」，詳細說明如下。 Framework 是未完成品 「Framework 是參考實作、未完成品。」這是小弟過去在許多演講場合，和大家分享的觀念。 1. Framework is incomplete. Framework 本身是不可用的，需要強化或填寫 framework 的空白，並設計相對應的應用程式，此時 framework...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[為什麼要研究 Android Framework？這是一個軟體工程以及專案管理面的問題。Android Framework 是 Application Framework（應用軟體框架），所謂的 Framework 定義上指的是未完成（incomplete）或是不完善（not ready-to-use）的軟體程式庫（嚴格來說是 class library）。

近期收到有關「如何發展 Android 產品」的需求有增多的趨勢，而要解決的最核心問題就是「研究 Android Framework」。雖然目前與一些訓練單位合作，提供許多 Android Framework 方面的課程，但因為都是屬於純技術面，還缺少軟體工程以及專案管理面的內容，尚有不足的地方。

有鑑於此，花費近一個月的時間，整理了一套「標準顧問方案」為企業客戶提供這方面的 On-site 服務，以補齊不足之處。這套顧問方案共分為 5 個層面，並定名為「Android Framework 專案啟動顧問服務」，詳細說明如下。

<strong>Framework 是未完成品</strong>

「Framework 是參考實作、未完成品。」這是小弟過去在許多演講場合，和大家分享的觀念。

1. Framework is incomplete.

Framework 本身是不可用的，需要強化或填寫 framework 的空白，並設計相對應的應用程式，此時 framework 才能有作用。從學術上的定義來看，framework 本身是 class library，這套 class library 以物件導向的抽象觀念來設計，提供可重用（resuable）或可抽換的單元（component），並提供一套應用程式流程（flow）與反向控制點（Inverse of Control）。

2. Framework is not ready-to-use.

Framework 是 class library，不是一個作業系統。Android Framework 是一套 class library，Android 搭配 Linux kernel 成為 Android OS。因此，framework 必須搭配作業系統核心，並且完成產品端的軟體開發；此處所指的「軟體開發」經常性的工作有2項：1. 補齊驅動程式，2. 並且整合驅動程式與 application framework。

以上說明讓我們了解一點，「廠商需要著手完成收尾工作」，並且 framework 本身是採用物件導向觀念設計的 class library，這說明了研究 Android Framework 內部設計的重要性。

<strong>Android Framework 留下的空白</strong>

因為不完整，所以需要了解我們倒底要填寫什麼空白、擴充哪些功能、開發哪些 abstract class 等等，以建立完整可用的 Android Framework。通常，這是一項針對「產品規格」所進行的工作，即 Specification 階段就該完成的工作。

在專案啟動前期（in the begining）若沒有完善這項工作，將可能影響後面的實作工作（implementation）。

<strong>Framework 只能擴充不要修改</strong>

一個嚴格的軟體工程方法裡，針對 application framework 的完善工作，需要基於「基礎版」進行後續的程式碼撰寫，但是，這個「撰寫」（coding）的工作應該儘量避免修改原始的 framework 實作。即 application framework 具備 non-modifiable 的特性。

Framework 是一個物件導向設計的 class library，因此採用 override 方式就可以實現「擴充」框架的做法；了解 Android Framework 現有設計（OOD）並進行擴充，是重要的工程技術。

<strong>實現 3M 分支維護策略管理程式碼</strong>

Framework 是實體的物體（physical objects），例如：以 JAR 檔形式存在。Framework 不是抽象的，所以像是 GoF 便是一種非實體的觀念。如何在 Android Framework 原始碼裡，將擴充出來的部份產生實體物體，最基本的做法是建立獨立的 JAR 檔。當我們擴充或重用 Android Framework 時，就會面臨三個問題：1. 有哪些實體需要建立？2. 以及如何建立？3. 並且如何在不修改 Android Framework 程式碼的前提下完成這些工作？

過去在課程或演講經常所提出的「3M 分支維護策略」就是一個簡易的解決方案。

<strong>建立 Android Framework 開發主機</strong>

為客戶建立一台專門的開發主機，是最後一項工作。除了提供範例與開發環境外，也會給予一個基本的訓練。

<strong>咨詢方案規劃</strong>

Jollen's Consulting 工作室聯合幾位不同領域的專家，在 Android Framework 的專案研發上做了一些討論，並且提出一個針對企業的咨詢方案，大綱如下：

《1 .觀念入門》Framework 是未完成品
《2. 實務應用》Android Framework 留下的空白
《3. 設計理論》Framework 只能擴充不要修改
《4. 分支管理》實現 3M 分支維護策略管理程式碼
《5. 開發環境》建立 Android Framework 開發主機

這是一套咨詢方案（Consulting），對象是「有意採用 Android 發展產品、想要正確並有效起步」的企業客戶。這套方案的方向是以「專案管理」、「產品開發」以及「軟體工程」做為出發點，雖然只是一個提供 Start-up 的 consulting 服務，但過去實行的成效良好，因此，將本方案公佈在這裡，期望 Jollen's Consulting 的專家團隊，能在「企業導入 Android 工程技術」上有所貢獻。過去的做法，經常是採購實驗板，並自行摸索；本方案提供的是「Start Up」服務，比起自行摸索的做法，更有效率、也更整體。

本方案過去服務過大陸與美國的企業。一些做法，目前也應用在自有的開發項目上。本方案目前的做法是以2-3天的 On-site 顧問服務方式進行，客戶端建議的參與人員必須包含1名專職的PM。本方案的顧問團隊，也包含了 2 位具備 PMP 資格的專案管理師，能為大家在開發上的專案管理提供一些觀念。
]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 系統管理雜記, #1: 關於 android.uid.system 與 AID_SYSTEM</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/02/android-uid-system.html" />
   <id>tag:www.jollen.org,2010:/blog//2.695</id>
   
   <published>2010-02-09T07:46:07Z</published>
   <updated>2010-02-13T15:41:40Z</updated>
   
   <summary><![CDATA[在 [Mokoid] 的 LedTest 範例裡，找到 [AndroidManifest.xml] 檔案。這個檔案為應用程式的「交貨清單」；在開發 LedTest 的過程中，我們加入了一個屬性如下： &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mokoid.LedTest" android:sharedUserId="android.uid.system"&gt; 原來，ServiceManager 會去檢查應用程式的權限；Android 作業系統會根據 UID 做權限管制，這裡所講的 UID 就是 Linux 系統管理面所討論的 User ID，即使用者 ID。在 [frmeworks/base/cmds/servicemanager/service_manager.c] 裡，找到這段實作： int svc_can_register(unsigned uid, uint16_t *name) { unsigned n; 　 if ((uid == 0)...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[在 [<a href="http://mokoid.googlecode.com" target="_blank">Mokoid</a>] 的 LedTest 範例裡，找到 [<a href="http://code.google.com/p/mokoid/source/browse/trunk/apps/LedTest/AndroidManifest.xml" target="_blank">AndroidManifest.xml</a>] 檔案。這個檔案為應用程式的「交貨清單」；在開發 LedTest 的過程中，我們加入了一個屬性如下：

<pre>&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mokoid.LedTest"
    <font color="#ff0000">android:sharedUserId="android.uid.system"</font>&gt;
</pre>

原來，ServiceManager 會去檢查應用程式的權限；Android 作業系統會根據 UID 做權限管制，這裡所講的 UID 就是 Linux 系統管理面所討論的 User ID，即使用者 ID。在 [<a href="http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob_plain;f=cmds/servicemanager/service_manager.c;hb=HEAD" target="_blank">frmeworks/base/cmds/servicemanager/service_manager.c</a>] 裡，找到這段實作：

<pre>int svc_can_register(unsigned uid, uint16_t *name)
{
    unsigned n;
    　
    if ((uid == 0) || (uid == AID_SYSTEM))
        return 1;
　
    for (n = 0; n < sizeof(allowed) / sizeof(allowed[0]); n++)
        if ((uid == allowed[n].uid) && str16eq(name, allowed[n].name))
            return 1;
　
    return 0;
}
　
int do_add_service(struct binder_state *bs,
                   uint16_t *s, unsigned len,
                   void *ptr, unsigned uid)
{
    struct svcinfo *si;
//    LOGI("add_service('%s',%p) uid=%d\n", str8(s), ptr, uid);
　
    if (!ptr || (len == 0) || (len > 127))
        return -1;
　
    if (!svc_can_register(uid, s)) {
        LOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED\n",
             str8(s), ptr, uid);
        return -1;
    }
    ...
}</pre>

AID_SYSTEM 被定義為 1000，即 system server 的 UID。從上述的實作可以了解，ServiceManager 會去檢查應用程式的 UID，當 UID 不符規定時，便無法執行 do_add_service()。

也就是：當應用程式的 UID 不是 1000 時，是沒有權限新增 Android Service 的。所以，在 AndroidManifest.xml 裡加上 android:sharedUserId 屬性的目的在於此：將應用程式的 UID 定義為 android.uid.system 即 1000，程式即可具備新增 Android Service 的權限。

以 Mokoid 所提供的範例為例，「因為我們是在 Android 應用程式裡啟動 Android Service」，因此要特別留意這個部份。典型的新增 Android Service 做法是修改 frameworks/base/services/java/com/android/server/SystemServer.java 檔案，但是，「因為 3M 分支維護策略的理念是儘量避免更動原始的 Android 程式碼」，所以我們採取這種「Start LedService in a seperated process.」的做法。細節請參考 Mokoid 範例。]]>
      
   </content>
</entry>
<entry>
   <title>MOSP: Mokoid Project (Mokoid Open Source Project) 上線</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/02/mokoid-project-is-up.html" />
   <id>tag:www.jollen.org,2010:/blog//2.694</id>
   
   <published>2010-02-08T14:55:00Z</published>
   <updated>2010-02-08T21:08:34Z</updated>
   
   <summary>為了能在「Jollen 的 Android Framework in a Nutshell 演講」上搭配範例做講解，因此「特製」了一個 LedManager 範例；此範例原來是「Android 框架與驅動程式整合: HAL 原理與實作訓練」培訓課程的實作範例，目前計畫以此範例的部份內容做為演講材料。歡迎有意參加 Jollen 的 Android Framework in a Nutshell 演講的朋友，事先下載 Mokoid 程式碼。 Mokoid 提供一個 LedTest 範例程式，同時，LedTest 也是 Mokoid 專案目前所提供的第一個「近乎完整」的範例。請大家參考 apps/LedTest/src/com/mokoid/LedTest/ 裡的程式碼。Mokoid 專案的第二個範例，計畫是「MotorManager」，目前仍處於測試階段，預計在《台北場》演講時釋出。 Mokoid 的目的是提供「教學開發板」一套完整的 architect code 供實驗課程使用，或是搭配正課做原理教學，當然，首要目的是應用在自已的培訓課程上。主要的理念是「去除使用 dirty code...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[為了能在「<a href="http://www.jollen.org/blog/2010/01/android-framework-in-a-nuthsell-preview.html">Jollen 的 Android Framework in a Nutshell 演講</a>」上搭配範例做講解，因此「特製」了一個 LedManager 範例；此範例原來是「<a href="http://www.moko365.com/training/android-hal-development-and-practice">Android 框架與驅動程式整合: HAL 原理與實作訓練</a>」培訓課程的實作範例，目前計畫以此範例的部份內容做為演講材料。歡迎有意參加 Jollen 的 Android Framework in a Nutshell 演講的朋友，事先下載 Mokoid 程式碼。

Mokoid 提供一個 LedTest 範例程式，同時，LedTest 也是 Mokoid 專案目前所提供的第一個「近乎完整」的範例。請大家參考 apps/LedTest/src/com/mokoid/LedTest/ 裡的程式碼。Mokoid 專案的第二個範例，計畫是「MotorManager」，目前仍處於測試階段，預計在《台北場》演講時釋出。

Mokoid 的目的是提供「教學開發板」一套完整的 architect code 供實驗課程使用，或是搭配正課做原理教學，當然，首要目的是應用在自已的培訓課程上。主要的理念是「去除使用 dirty code 教學的風氣」，不過，可能需要不少時間來實踐這個理想。

Mokoid Project 網址：<a href="http://mokoid.googlecode.com">http://mokoid.googlecode.com</a>

]]>
      
   </content>
</entry>
<entry>
   <title>「Android Framework Introduction」講座</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/02/android-framework-foxconn.html" />
   <id>tag:www.jollen.org,2010:/blog//2.693</id>
   
   <published>2010-02-01T15:58:01Z</published>
   <updated>2010-02-01T22:48:45Z</updated>
   
   <summary>Android Framework 技術的重要性日漸提高，研究 Android Framework 架構或是內部結構成為一項重要的工作。明天（2/2）受邀至鴻海土城民生廠進行一場訓練課程，主題是「Android Framework Introduction」；議題雖然是「introduction」，但突然有個想法，希望能做更深入的 introduction。正好近期在整理研究資料，所以把抓出的議題也和大家分享。計畫介紹的技術主題（Features）如下： 1. Android Framework Features SystemServer &amp; ServerThread Main Thread android.app.Activity 與 android.app.Service Android Process 模式 ServiceManager 與 getSystemService API JNI &amp; Native Method Blocking &amp; Long Operations VMThread &amp; Thread Zygote...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Android Framework 技術的重要性日漸提高，研究 Android Framework 架構或是內部結構成為一項重要的工作。明天（2/2）受邀至鴻海土城民生廠進行一場訓練課程，主題是「Android Framework Introduction」；議題雖然是「introduction」，但突然有個想法，希望能做更深入的 introduction。正好近期在整理研究資料，所以把抓出的議題也和大家分享。計畫介紹的技術主題（Features）如下：

<strong>1. Android Framework Features</strong>

<ul><li>SystemServer & ServerThread</li>
<li>Main Thread</li>
<li>android.app.Activity 與 android.app.Service</li>
<li>Android Process 模式</li>
<li>ServiceManager 與 getSystemService API</li>
<li>JNI & Native Method</li>
<li>Blocking & Long Operations</li>
<li>VMThread & Thread</li>
<li>Zygote 與 Linux fork System Call</li></ul>

<strong>2. Android Framework Development</strong>

<ul><li>Manager API</li>
<li>Proxy Object</li>
<li>Remote Object</li>
<li>Remotable Object</li>
<li>IInterface & IServiceManager</li></ul>

原本構想中的 introduction 是以 Android 的架構圖為主，逐一介紹每一層的關係以並做 source code 的導讀；不過，後來想了一下，因為只有 3 個小時的時間，再加上大家對「概念」可能都已經有一定程度的了解了，所以再做這種描述性的簡介，似乎意義不大。

於是，改採介紹「Features」的方式，將 Android 重要的技術點做「點擊式」的說明。「明天過後」歡迎大家來函索取這次的講稿，待未來講義更加完善時，再放置到網路上分享。]]>
      
   </content>
</entry>
<entry>
   <title>「Jollen 的 Android Framework in a Nutshell 演講」講題規劃完畢</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/01/android-framework-in-a-nuthsell-preview.html" />
   <id>tag:www.jollen.org,2010:/blog//2.692</id>
   
   <published>2010-01-25T16:22:44Z</published>
   <updated>2010-01-25T22:35:35Z</updated>
   
   <summary>從去年就開始構思的「Jollen 的 Android Framework in a Nutshell」演講，終於在上週六正式完成講題規劃了。初版講稿也開始進入檢查階段，第一場演講預估在二月底或三月初舉行，詳細的時間與地點，稍後將發佈於演講活動官網 [Jollen&apos;s Android Framework in a Nutshell 演講]。 「In a Nutshell」是本演講的核心理念，也是規劃講稿時所依循的精神；關於堅果殼精神，可參考先前日記 [「Jollen 的 Android Framework in a Nutshell」演講] 的說明。 講題的規劃將以一個實例「揭開」Android 框架的黑盒子、將 Android 結構做展開的動作，並分別介紹每個層面的技術重點；希望藉由這個精心規劃的演講活動，能幫助對 Android 框架與系統底層有興趣的朋友，有效率地掌握技術重點。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[從去年就開始構思的「Jollen 的 Android Framework in a Nutshell」演講，終於在上週六正式完成講題規劃了。初版講稿也開始進入檢查階段，第一場演講預估在二月底或三月初舉行，詳細的時間與地點，稍後將發佈於演講活動官網 [<a href="http://www.jollen.org/androidframework/">Jollen's Android Framework in a Nutshell 演講</a>]。

<a href="/androidframework/"><img src="http://www.jollen.org/androidframework/banner.png" border="0" /></a>

「In a Nutshell」是本演講的核心理念，也是規劃講稿時所依循的精神；關於堅果殼精神，可參考先前日記 [<a href="http://www.jollen.org/blog/2010/01/jollen-android-in-a-nut-shell.html">「Jollen 的 Android Framework in a Nutshell」演講</a>] 的說明。

講題的規劃將以一個實例「揭開」Android 框架的黑盒子、將 Android 結構做展開的動作，並分別介紹每個層面的技術重點；希望藉由這個精心規劃的演講活動，能幫助對 Android 框架與系統底層有興趣的朋友，有效率地掌握技術重點。]]>
      
   </content>
</entry>
<entry>
   <title>OPhone SDN 徵文「JIL Mobile Widget: 我的第一堂课」</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/01/ophone-sdn-jil-mobile-widget.html" />
   <id>tag:www.jollen.org,2010:/blog//2.691</id>
   
   <published>2010-01-25T05:57:25Z</published>
   <updated>2010-01-25T12:05:38Z</updated>
   
   <summary>去年 [OPhone SDN] 舉辦了一個徵文活動，因為對 BAE 技術的高度興趣以及好感，特別撰文，以另外一種角度來表達 JIL Mobile Widget 技術的定位，希望以深入淺出方式，將這個實用的好技術介紹給大家。稿件有幸被接受，請大家不吝指教 [JIL Mobile Widget: 我的第一堂课]。BAE 與 JIL Mobile Widget 的關係，在文末也做了簡單說明。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Open Mobile Platform" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[去年 [<a href="http://www.ophonesdn.com/" target="_blank">OPhone SDN</a>] 舉辦了一個徵文活動，因為對 BAE 技術的高度興趣以及好感，特別撰文，以另外一種角度來表達 JIL Mobile Widget 技術的定位，希望以深入淺出方式，將這個實用的好技術介紹給大家。稿件有幸被接受，請大家不吝指教 [<a href="http://www.ophonesdn.com/article/show/184;jsessionid=D31E09EEC5BFDC720E04D1CE507099AC" target="_blank">JIL Mobile Widget: 我的第一堂课</a>]。BAE 與 JIL Mobile Widget 的關係，在文末也做了簡單說明。]]>
      
   </content>
</entry>
<entry>
   <title>首屆海峽Android技術及產業合作發展研討會：會後雜記</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/01/android-collaboration-beijing.html" />
   <id>tag:www.jollen.org,2010:/blog//2.690</id>
   
   <published>2010-01-25T05:43:48Z</published>
   <updated>2010-01-25T12:25:41Z</updated>
   
   <summary>這個月15日到北京參加「首屆海峽Android技術及產業合作發展研討會」，結果正值北京二十年來難得一見的大寒，白天的氣溫最低還來到了-10度C，整個城市都可以看到白雪，到小商店還買到了「結冰礦泉水」，實在是一個有趣的經驗。 關於這次會議的實況，在研討會官網以及媒體上，都有很詳細的報導，所以這裡僅補上一點會議雜記。這次的會議，下午場分做三個track（產業、技術與人才培養），我在技術與人才場各有一個session。在技術場部份，針對「Android對手機的技術趨勢與機會」做了演說，人才培養場則是討論有關創業機會的議題。 「Browser-based」是Android手機的技術趨勢之一，這是大家都不陌生的名詞，整合cloud computing到手機上，這也是一個關鍵技術。技術分會場中，我特別舉JIL的Mobile Widget技術做實例，介紹了這個技術帶來的優點，以及BAE將如何創造一個新的手機應用開發模式。 這次會議，根據估計，與會人數大約有500人。在會議的前幾天，正逢沸沸洋洋的Google事件，與一些朋友聊天時，不免談論到這個話題；不過，大家普遍認為這個事件並不影嚮Android的技術推展。以會議的討論氣氛來看，影響確實不大。 在「人才培養」分會場的部份，來自中正大學羅習五老師實驗室的「現場成果展」吸引不少人的目光，特別是「螢光棒」的創意應用，連媒體都特別來報導了。可見，「創意」是Android應用開發不能缺少的一個要素。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[這個月15日到北京參加「<a href="http://www.android-collaboration.com/" target="_blank">首屆海峽Android技術及產業合作發展研討會</a>」，結果正值北京二十年來難得一見的大寒，白天的氣溫最低還來到了-10度C，整個城市都可以看到白雪，到小商店還買到了「結冰礦泉水」，實在是一個有趣的經驗。

關於這次會議的實況，在研討會官網以及媒體上，都有很詳細的報導，所以這裡僅補上一點會議雜記。這次的會議，下午場分做三個track（產業、技術與人才培養），我在技術與人才場各有一個session。在技術場部份，針對「Android對手機的技術趨勢與機會」做了演說，人才培養場則是討論有關創業機會的議題。

「Browser-based」是Android手機的技術趨勢之一，這是大家都不陌生的名詞，整合cloud computing到手機上，這也是一個關鍵技術。技術分會場中，我特別舉JIL的Mobile Widget技術做實例，介紹了這個技術帶來的優點，以及BAE將如何創造一個新的手機應用開發模式。

這次會議，根據估計，與會人數大約有500人。在會議的前幾天，正逢沸沸洋洋的Google事件，與一些朋友聊天時，不免談論到這個話題；不過，大家普遍認為這個事件並不影嚮Android的技術推展。以會議的討論氣氛來看，影響確實不大。

<img alt="android-beijing.jpg" src="http://www.jollen.org/blog/2010/01/25/android-beijing.jpg" width="464" height="337" />

在「人才培養」分會場的部份，來自中正大學羅習五老師實驗室的「現場成果展」吸引不少人的目光，特別是「螢光棒」的創意應用，連媒體都特別來報導了。可見，「創意」是Android應用開發不能缺少的一個要素。]]>
      
   </content>
</entry>
<entry>
   <title>「Jollen 的 Android Framework in a Nutshell」演講</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/01/jollen-android-in-a-nut-shell.html" />
   <id>tag:www.jollen.org,2010:/blog//2.688</id>
   
   <published>2010-01-03T10:54:11Z</published>
   <updated>2010-01-03T14:43:48Z</updated>
   
   <summary>在堅果殼裡「In a nut shell」是一句英文片語，表示「簡單地說」的意思，與中文的「總而言之」有異曲同工之妙。如果上網搜尋，還可以找到這個片語來源：知名的長篇史詩「伊利亞德（Iliad）」曾被製作成體積迷你的手抄版本，正因為這個迷你的手抄版本小到能放進堅果殼裡（in a nut shell），因此這個片語就被引申為「簡單地說」之意。 知名的電腦書出版商O&apos;reilly就出版了一系列的「in a nut shell」。這個系列書藉的特色正如其名「簡潔、不托泥帶水」，「一頁抵十頁、一部抵十部」或許能說明堅果殼書的特色；意思是說，別人100頁的篇幅，往往堅果殼只需要10頁就足矣。事實上，這應該不誇張，因為現在很多書就喜歡拉篇幅、撐厚度；有些「用來佔地盤」的系列著作就更不用提了。不過，我們不該是以這種評論的角度，把堅果殼書跟其它書拿來做比較；因為，要出版一本著作，也不是簡單的事情，任何書都有它的參考價值、還有作者日以夜繼的心血在裡面，這些心血都應該被尊重。這樣的形容，單純為了說明「堅果殼書」的特色。 「寫一本堅果殼書。」是我很早的目標，雖然過去也寫了許多書，但都還達不到我想像中的堅果殼書標準。希望有朝一日能達成這個目標。 前天的日記曾提到，去年利用了七個月的時間在做「巡迴」，不過這是平常工作之餘的活動；「研究」佔了我日常工作大約50%-60%的時間，透過課程巡迴與演講，除了可以分享部份研究心得外，也有助於調整後續的研究進度。在這七個月的時間裡，大致上都把Android Framework的內部設計以及原理做了研究以及整理，對於整體框架的實作，也準備了一份簡報，希望可以用「堅果殼」的精神，化繁為簡，用一種簡而易懂的方式，將複雜的Android框架設計放進堅果殼裡。 有鑑於此，今年希望規劃大約3場演講，親身說法，為大家說明堅果殼裡的內容。 如何把龐大的Android框架，簡單表達，儘量簡化而保持原始精神，確實是一大挑戰，但也很有趣。希望「Jollen 的 Android Framework in a Nutshell」演講，能成功挑戰這個難題。目前正在規劃第1場堅果殼演講，歡迎大家提供意見供活動小組參考。活動時間將另行公佈，期望與大家交流，並不吝指教。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      在堅果殼裡「In a nut shell」是一句英文片語，表示「簡單地說」的意思，與中文的「總而言之」有異曲同工之妙。如果上網搜尋，還可以找到這個片語來源：知名的長篇史詩「伊利亞德（Iliad）」曾被製作成體積迷你的手抄版本，正因為這個迷你的手抄版本小到能放進堅果殼裡（in a nut shell），因此這個片語就被引申為「簡單地說」之意。

知名的電腦書出版商O&apos;reilly就出版了一系列的「in a nut shell」。這個系列書藉的特色正如其名「簡潔、不托泥帶水」，「一頁抵十頁、一部抵十部」或許能說明堅果殼書的特色；意思是說，別人100頁的篇幅，往往堅果殼只需要10頁就足矣。事實上，這應該不誇張，因為現在很多書就喜歡拉篇幅、撐厚度；有些「用來佔地盤」的系列著作就更不用提了。不過，我們不該是以這種評論的角度，把堅果殼書跟其它書拿來做比較；因為，要出版一本著作，也不是簡單的事情，任何書都有它的參考價值、還有作者日以夜繼的心血在裡面，這些心血都應該被尊重。這樣的形容，單純為了說明「堅果殼書」的特色。

「寫一本堅果殼書。」是我很早的目標，雖然過去也寫了許多書，但都還達不到我想像中的堅果殼書標準。希望有朝一日能達成這個目標。

前天的日記曾提到，去年利用了七個月的時間在做「巡迴」，不過這是平常工作之餘的活動；「研究」佔了我日常工作大約50%-60%的時間，透過課程巡迴與演講，除了可以分享部份研究心得外，也有助於調整後續的研究進度。在這七個月的時間裡，大致上都把Android Framework的內部設計以及原理做了研究以及整理，對於整體框架的實作，也準備了一份簡報，希望可以用「堅果殼」的精神，化繁為簡，用一種簡而易懂的方式，將複雜的Android框架設計放進堅果殼裡。

有鑑於此，今年希望規劃大約3場演講，親身說法，為大家說明堅果殼裡的內容。

如何把龐大的Android框架，簡單表達，儘量簡化而保持原始精神，確實是一大挑戰，但也很有趣。希望「Jollen 的 Android Framework in a Nutshell」演講，能成功挑戰這個難題。目前正在規劃第1場堅果殼演講，歡迎大家提供意見供活動小組參考。活動時間將另行公佈，期望與大家交流，並不吝指教。

      
   </content>
</entry>
<entry>
   <title>Android 的 HAL 技術, #8: 實作 HAL Stub</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/01/android-hal-stub-design-implement.html" />
   <id>tag:www.jollen.org,2010:/blog//2.687</id>
   
   <published>2010-01-02T15:31:08Z</published>
   <updated>2010-01-02T13:49:39Z</updated>
   
   <summary>承日記「Android 的 HAL 技術, #6: 小結 HAL stub 實作步驟」與「Android 的 HAL 技術, #7: 取得 Proxy Object」。在了解基本的觀念，以及架構上的設計後，接著就可以開始實作 HAL Stub 了。以下是 LED Stub 的實作範例，將程式碼儲存為 led.c： static struct hw_module_methods_t led_module_methods = { open: led_device_open }; 　 const struct led_module_t HAL_MODULE_INFO_SYM = { common:...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[承日記「<a href="http://www.jollen.org/blog/2009/12/android-hal-stub-implementation.html">Android 的 HAL 技術, #6: 小結 HAL stub 實作步驟</a>」與「<a href="http://www.jollen.org/blog/2009/12/android-hal-get-proxy-object.html">Android 的 HAL 技術, #7: 取得 Proxy Object</a>」。在了解基本的觀念，以及架構上的設計後，接著就可以開始實作 HAL Stub 了。以下是 LED Stub 的實作範例，將程式碼儲存為 led.c：

<pre>static struct hw_module_methods_t led_module_methods = {
    open: led_device_open
};
　
const struct led_module_t HAL_MODULE_INFO_SYM = {
    common: {
        tag: HARDWARE_MODULE_TAG,
        version_major: 1,
        version_minor: 0,
        id: LED_HARDWARE_MODULE_ID,
        name: "Simple LED module",
        author: "The Mokoid Open Source Project",
        methods: &led_module_methods,
    }
　
    /* supporting APIs go here */
};</pre>

這段程式碼實作了圖1的設計， led_module_t 是 Stub 的主體結構（或稱為主類別），其符號名稱須取名為 HAL_MODULE_INFO_SYM，不可更改。任何的 Stub 主類別名稱都須命名為 HAL_MODULE_INFO_SYM。

<a href="http://www.jollen.org/blog/2010/01/02/hw_module_methods_t.gif" target="_blank"><img src="http://www.jollen.org/blog/2010/01/02/hw_module_methods_t.gif" width="480" border="0" /></a>
圖1：LED Stub的設計(OOD)

幾個重要的欄位如下：

<ul><li>tag：須指定為 HARDWARE_MODULE_TAG</li>
<li>id：指定為 HAL Stub 的 module ID，我們的範例為”LED”</li>
<li>methods：struct hw_module_methods_t，為 HAL 所定義的「method」</li>
<li>struct hw_module_methods_t 是由 HAL 定義的標準介面，目前的 AOSP（Android Open Source Project）實作裡包含一個”open”介面</li>
</ul>

"Open" 是一個介面（interface），這意味著 HAL Stub 必須實作此介面，這個部份更是 HAL 的重點。]]>
      
   </content>
</entry>
<entry>
   <title>二零一零新年快樂：新希望與期許！</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2010/01/happy-new-year-2010.html" />
   <id>tag:www.jollen.org,2010:/blog//2.686</id>
   
   <published>2010-01-01T07:14:36Z</published>
   <updated>2010-01-01T05:32:26Z</updated>
   
   <summary>新的一年，祝福大家心想事成。開放源碼(Open Source)與開放平臺(Open Devices)是相當有意思的二個主題，今年，二零一零年，希望可以認識更多志同道合的朋友；也祝福大家，技術進步、研究豐碩。 今年，需要投注更多心力到Android相關的技術研究工作，以及產品規劃。去年，確實是頗為有趣的一年，自已也投入了相當多時間在技術研究、廠商交流以及教育訓練工作上。七個月多的時間，不斷巡迴台北、上海、深圳、北京四大城市，在這些城市進行Android以及Embedded Linux的培訓工作，其間，也和許多技術人員，以及廠商有許多交流，甚致深入的合作。 這段過程中，令人感受最深的，便是「快速成長」四個大字。 「二零零九年，大陸總計賣出一千三百萬輛台汽車。」有一天在前往北京首都國際機場的出租車上，所聽到的一段新聞。大陸目前約有一百家汽車廠，一般消費者，從下訂到取車，可能需要長達三個月的時間。在一些主要城市，整條路上的汽車經銷商，甚致沒有一家有「現貨」可供銷售。 若以每年中國經濟成長率超越美國約5%來計算，中國的GDP在二零二零年，將超過美國。以每年8%來計算，到時生產總額也將再翻一番。今年，二零一零年，中國也要做好GDP超越日本的準備。不過，畢竟經濟這件事也不是做為技術工作者的我，能通盤了解的，除了平日讀讀新聞、看看發佈數據外，還是專注在技術本業上更實際一些，所以，在這裡分享一個技術工作上的看法，供大家參考指教。 有關BAE的應用，今年可能得到大幅度的份額增長。BAE的全名是Browser based Application Engine。這並非很新潮的技術，在另外二大手機作業系統：Windows Mobile與Symbian上，也都有這樣的應用。BAE其實不只是在手持裝置上，在Web Service或是個人電腦上，也都能看到它的踪跡。 重視開放平臺的BAE應用，把它加入產品設計與規劃的要項，是過去我給一家廠商提出的建議。過去，Android Market是個棘手問題，但現在開始，情況會有所改變。這是獨立應用軟體開發商或獨立品牌的好機會。Android Market的發展看起來將有很大的突破； 目前，在我所參與的一個技術工作上，已經將資源的分配由框架與底層的驅動程式，部份轉換到應用(Applications)的開發與研究工作上，就是希望在應用開發上加重比重。 上述提到的BAE技術，因為改變應用軟體開發的模式，也要多加的重視。 去年十二月，在教育部嵌入式軟體聯盟的一場開放手機研討會上，我邀請了北京的eoeAndroid社群做了一次遠端視訊連線，為現場同學做了一些Android方面的介紹。「社群是開放平臺的靈魂。」因為Android技術，出現了許多技術社群，「熱情」是他們的共通點。從eoeAndrod的談話中，可以感受到這點，以及技術研究的精神「自身投入、明確務實」。台灣的0xlab也是一個典範，我們看見了追求技術卓越的熱情與貢獻，還有務實的精神。 因為Android的出現，eoeAndroid團隊一些人辭去他們原本的工作，一起為建立社群而努力。在周遭所認識的朋友裡，他們並不是唯一有這種堅定決心的工作者。 回顧過去的工作，深刻感受到不同城市間的工作文化、技術發展重點或是想法，都有很不一樣的特色；技術研究是個有趣的工作，給自已的期許是，當一個稱職的執行者，努力並有效率地完成專案。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      新的一年，祝福大家心想事成。開放源碼(Open Source)與開放平臺(Open Devices)是相當有意思的二個主題，今年，二零一零年，希望可以認識更多志同道合的朋友；也祝福大家，技術進步、研究豐碩。

今年，需要投注更多心力到Android相關的技術研究工作，以及產品規劃。去年，確實是頗為有趣的一年，自已也投入了相當多時間在技術研究、廠商交流以及教育訓練工作上。七個月多的時間，不斷巡迴台北、上海、深圳、北京四大城市，在這些城市進行Android以及Embedded Linux的培訓工作，其間，也和許多技術人員，以及廠商有許多交流，甚致深入的合作。

這段過程中，令人感受最深的，便是「快速成長」四個大字。

「二零零九年，大陸總計賣出一千三百萬輛台汽車。」有一天在前往北京首都國際機場的出租車上，所聽到的一段新聞。大陸目前約有一百家汽車廠，一般消費者，從下訂到取車，可能需要長達三個月的時間。在一些主要城市，整條路上的汽車經銷商，甚致沒有一家有「現貨」可供銷售。

若以每年中國經濟成長率超越美國約5%來計算，中國的GDP在二零二零年，將超過美國。以每年8%來計算，到時生產總額也將再翻一番。今年，二零一零年，中國也要做好GDP超越日本的準備。不過，畢竟經濟這件事也不是做為技術工作者的我，能通盤了解的，除了平日讀讀新聞、看看發佈數據外，還是專注在技術本業上更實際一些，所以，在這裡分享一個技術工作上的看法，供大家參考指教。

有關BAE的應用，今年可能得到大幅度的份額增長。BAE的全名是Browser based Application Engine。這並非很新潮的技術，在另外二大手機作業系統：Windows Mobile與Symbian上，也都有這樣的應用。BAE其實不只是在手持裝置上，在Web Service或是個人電腦上，也都能看到它的踪跡。

重視開放平臺的BAE應用，把它加入產品設計與規劃的要項，是過去我給一家廠商提出的建議。過去，Android Market是個棘手問題，但現在開始，情況會有所改變。這是獨立應用軟體開發商或獨立品牌的好機會。Android Market的發展看起來將有很大的突破； 目前，在我所參與的一個技術工作上，已經將資源的分配由框架與底層的驅動程式，部份轉換到應用(Applications)的開發與研究工作上，就是希望在應用開發上加重比重。

上述提到的BAE技術，因為改變應用軟體開發的模式，也要多加的重視。

去年十二月，在教育部嵌入式軟體聯盟的一場開放手機研討會上，我邀請了北京的eoeAndroid社群做了一次遠端視訊連線，為現場同學做了一些Android方面的介紹。「社群是開放平臺的靈魂。」因為Android技術，出現了許多技術社群，「熱情」是他們的共通點。從eoeAndrod的談話中，可以感受到這點，以及技術研究的精神「自身投入、明確務實」。台灣的0xlab也是一個典範，我們看見了追求技術卓越的熱情與貢獻，還有務實的精神。

因為Android的出現，eoeAndroid團隊一些人辭去他們原本的工作，一起為建立社群而努力。在周遭所認識的朋友裡，他們並不是唯一有這種堅定決心的工作者。 回顧過去的工作，深刻感受到不同城市間的工作文化、技術發展重點或是想法，都有很不一樣的特色；技術研究是個有趣的工作，給自已的期許是，當一個稱職的執行者，努力並有效率地完成專案。
      
   </content>
</entry>
<entry>
   <title>Android 的 HAL 技術, #7: 取得 Proxy Object</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/12/android-hal-get-proxy-object.html" />
   <id>tag:www.jollen.org,2009:/blog//2.685</id>
   
   <published>2009-12-26T15:36:55Z</published>
   <updated>2009-12-26T14:15:51Z</updated>
   
   <summary>延續上一則日記的介紹，在完成HAL Stub的實作後，緊接著的工作就是撰寫Native Service。 談了許多「Android Service」以及「HAL Stub」，這裡再補充一點。Android作業系統啟動時，會執行一個process稱為servicemanager。Servicemanager process負責管理、提供並保存「Android Service」。Android Service為Java層，因此接下來會透過JNI來呼叫C/C++層的Native Service。 廣義來說，Native Service也提供Runtime的功能，即Core Library層。Runtime的重要工作之一為「取得HAL Stub所提供的API」，因此這是撰寫完整Native Service的前哨站。 什麼是 Proxy Object？ Native Service呼叫HAL的hw_get_module() API取得stub物件，即HAL_MODULE_INFO_SYM。 HAL會去尋找HAL Stub檔案，HAL Stub是以*.so檔的形式存在，並佈署於/system/lib/hw目錄下。HAL會根據module ID以及”ro.product.board”去尋找相對應的*.so檔，以我們的LED範例來說，HAL會回傳回led_module_t結構的物件（an instance of led_module_t class）給Native Service。 我們把HAL回傳給Native Service的資料稱為「Stub Object」或是「Proxy Object」，即先前所提及的「代理人」觀念。Native Service透過代理人與 Linux 驅動程式溝通。這個過程的觀念如圖1所示。 圖1：取得Proxy Object hw_get_module()，這是HAL所提供的API，也是實作HAL...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[延續上一則日記的介紹，在完成HAL Stub的實作後，緊接著的工作就是撰寫Native Service。

談了許多「Android Service」以及「HAL Stub」，這裡再補充一點。Android作業系統啟動時，會執行一個process稱為servicemanager。Servicemanager process負責管理、提供並保存「Android Service」。Android Service為Java層，因此接下來會透過JNI來呼叫C/C++層的Native Service。

廣義來說，Native Service也提供Runtime的功能，即Core Library層。Runtime的重要工作之一為「取得HAL Stub所提供的API」，因此這是撰寫完整Native Service的前哨站。

<strong>什麼是 Proxy Object？</strong>

Native Service呼叫HAL的hw_get_module() API取得stub物件，即HAL_MODULE_INFO_SYM。

HAL會去尋找HAL Stub檔案，HAL Stub是以*.so檔的形式存在，並佈署於/system/lib/hw目錄下。HAL會根據module ID以及”ro.product.board”去尋找相對應的*.so檔，以我們的LED範例來說，HAL會回傳回led_module_t結構的物件（an instance of led_module_t class）給Native Service。

我們把HAL回傳給Native Service的資料稱為「Stub Object」或是「Proxy Object」，即先前所提及的「代理人」觀念。Native Service透過代理人與 Linux 驅動程式溝通。這個過程的觀念如圖1所示。

<img src="http://www.jollen.org/blog/2009/12/26/hal-get-proxy-object.gif" width="480" />
圖1：取得Proxy Object

hw_get_module()，這是HAL所提供的API，也是實作HAL Stub最重要的一個API，不過另人驚奇的地方是，這也是目前AOSP裡HAL層所提供的唯一一個API。
]]>
      
   </content>
</entry>
<entry>
   <title>Android 的 HAL 技術, #6: 小結 HAL stub 實作步驟</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/12/android-hal-stub-implementation.html" />
   <id>tag:www.jollen.org,2009:/blog//2.684</id>
   
   <published>2009-12-04T14:49:08Z</published>
   <updated>2009-12-26T13:38:06Z</updated>
   
   <summary>在討論了不少基本概念後，在這裡小結一下 HAL stub 的實作步驟。HAL stub 的起頭是「繼承 HAL 的 struct hw_module_t」，這是 HAL stub 的設計理念，除了讓架構的條理分明外，也容易做後續擴充與維護。以下改用實用上的習慣用語，小結一下 HAL stub 實作步驟，並提供一段例。 HAL Stub 實作步驟(Implementation) 1. 設計自已的wrapper data structure * 編寫led.h * 定義 struct led_module_t * 框架提供的 struct hw_module_t 必須放在第一個 field、並取名為 common * 請參考 hardware/hardware.h 2....</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[在討論了不少基本概念後，在這裡小結一下 HAL stub 的實作步驟。HAL stub 的起頭是「繼承 HAL 的 struct hw_module_t」，這是 HAL stub 的設計理念，除了讓架構的條理分明外，也容易做後續擴充與維護。以下改用實用上的習慣用語，小結一下 HAL stub 實作步驟，並提供一段例。

<strong>HAL Stub 實作步驟(Implementation)
</strong>

1. 設計自已的wrapper data structure

* 編寫led.h
* 定義 struct led_module_t
* 框架提供的 struct hw_module_t 必須放在第一個 field、並取名為 common
* 請參考 hardware/hardware.h

2. led_module_t的意義

宣告初始化時期(new object)的 supporting API、在 constructor 裡會使用到。

3. 定義 led_control_device_t

宣告控制時期的 supporting API、在 Manager API 裡會使用到。設計上的細節在後續文章再做整理。

4. 每個 HAL stub 都要宣告 module ID

5. 宣告 Stub operations 並實作 callback functions

Stub 的 operations 結構符號名稱須取名為 HAL_MODULE_INFO_SYM、此符號名不可更改。

<strong>範例：led.h</strong>

<pre>#include &lt;hardware/hardware.h&gt;
   
#include &lt;fcntl.h&gt;
#include &lt;errno.h&gt;
   
#include &lt;cutils/log.h&gt;
#include &lt;cutils/atomic.h&gt;
   
/*****************************************************************************/
   
struct led_module_t {
   struct hw_module_t common;
};
   
struct led_control_device_t {
   struct hw_device_t common;
   /* supporting control APIs go here */
   int (*set_on)(struct led_control_device_t *dev, int32_t led);
   int (*set_off)(struct led_control_device_t *dev, int32_t led);
};
   
/*****************************************************************************/
   
#define LED_HARDWARE_MODULE_ID "led"</pre>
   
實作上的細節在這裡不再多做說明，關於設計上的細節將另行整理。
]]>
      
   </content>
</entry>
<entry>
   <title>Android 的 HAL 技術, #5: 繼承 HAL 的 struct hw_module_t</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/12/android-hal-derived-c-language.html" />
   <id>tag:www.jollen.org,2009:/blog//2.683</id>
   
   <published>2009-12-01T14:09:14Z</published>
   <updated>2009-12-01T13:20:22Z</updated>
   
   <summary><![CDATA[撰寫 HAL stub 除了要具備系統程式（systems software）的觀念外（這是基礎），「思考方式的改變」也是重要的一堂課。 思考方式哪裡不同？ 實作 HAL stub 的首要工作是「繼承 struct hw_module_t 抽象型別」。Class（類別）屬於一種抽象型號（ADT）。 首先，引入最重要的標頭檔（header file）： #include &lt;hardware/hardware.h&gt; 接著，再定義一個「MODULE ID」。這個 mdoule ID 將會被 HAL 層用來尋找 HAL stub。我們舉最簡單的裝置類型「LED」來做為範例： #define LED_HARDWARE_MODULE_ID "led" 繼承 HAL 的 struct hw_module_t 抽象型別（即 base class 的概念），並取名為 struct led_module_t（即...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[撰寫 HAL stub 除了要具備系統程式（systems software）的觀念外（這是基礎），「思考方式的改變」也是重要的一堂課。

<strong>思考方式哪裡不同？</strong>

實作 HAL stub 的首要工作是「繼承 struct hw_module_t 抽象型別」。Class（類別）屬於一種抽象型號（ADT）。

首先，引入最重要的標頭檔（header file）：

<blockquote>#include &lt;hardware/hardware.h&gt;</blockquote>

接著，再定義一個「MODULE ID」。這個 mdoule ID 將會被 HAL 層用來尋找 HAL stub。我們舉最簡單的裝置類型「LED」來做為範例：

<blockquote>#define LED_HARDWARE_MODULE_ID "led"
</blockquote>
繼承 HAL 的 struct hw_module_t 抽象型別（即 base class 的概念），並取名為 struct <strong>led</strong>_module_t（即 derived class）：

<blockquote><pre>struct led_module_t {
   struct hw_module_t common;
};</pre></blockquote>

以資料結構的角度來看，這裡的做法只是宣告了一個抽象資料型別（Abstract Data Type），以提升程式碼的結構化特性。但是，這裡需要以架構的角度來解釋，「Android HAL規定不要直接使用struct hw_module_t」，原文的意思是要我們做類別繼承。

<strong>實作繼承</strong>

在C語言裡實作繼承的方式，大致如下：

1. 宣告一個 data structure 將原始的基本結構包裝起來
2. 將原始的基本結構放在第一個 field

因此，可以思考如下：

<blockquote><pre>struct led_module_t {
   struct hw_module_t common;
   　
   /* Place attributes here. */
　
   /* Place methods here. */
};</pre></blockquote>

唯一，這裡的實作在OO特性上，缺乏像是public與private的封裝性。但這裡的重心是，以OO的方式思考，會如何改變過去的 C 程式寫作習慣？最明顯的地方是，<strong>程式碼的寫作風格有了很大的改變</strong>。]]>
      
   </content>
</entry>
<entry>
   <title>HAL stub的商業價值與想法</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/11/hal-proprietary_software.html" />
   <id>tag:www.jollen.org,2009:/blog//2.682</id>
   
   <published>2009-11-29T06:20:17Z</published>
   <updated>2009-11-29T05:32:12Z</updated>
   
   <summary>HAL stub是與硬體關係最密切的軟體 HAL stub因為是以獨立的*.so檔形式，佈署於/system/lib/hw目錄下，同時，執行時期（runtime）是以提供操作（provide operations）的方式來運作，所以可以達到HAL的目的之一，即界面（interface）的設計。 再加上HAL stub是與硬體關係最密切的軟體，所以讓我們有了不同的思考。 Android分支(branch)工廠 定義好界面再實作stub，這樣的架構讓stub，也就是*.so檔，可以元件化（component）。HAL以物件導向的思考方式設計與實作。元件可以抽換或重用，再配合過去提到的「Android分支建立」觀念，「HAL stub 服務工廠」的想法便油然而生。 提供HAL(與*.so)代工服務與解決方案 由驅動程式專業公司進行設計與開發，即軟體服務的一種想法，基於： 1. HAL stub軟體可封閉源碼，因此也較利於商業模式推展 2. 提供關鍵IC零組件封閉原始碼的HAL stub軟體 (Proprietary software) 3. 不但是「軟硬整合」，也是Android綁定硬體平臺的一種策略 當然，想法往往都是「有感而發」，現實面能不能執行又是一回事了。 ;-)...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<strong>HAL stub是與硬體關係最密切的軟體</strong>

HAL stub因為是以獨立的*.so檔形式，佈署於/system/lib/hw目錄下，同時，執行時期（runtime）是以提供操作（provide operations）的方式來運作，所以可以達到HAL的目的之一，即界面（interface）的設計。

再加上HAL stub是與硬體關係最密切的軟體，所以讓我們有了不同的思考。

<strong>Android分支(branch)工廠</strong>

定義好界面再實作stub，這樣的架構讓stub，也就是*.so檔，可以元件化（component）。HAL以物件導向的思考方式設計與實作。元件可以抽換或重用，再配合過去提到的「Android分支建立」觀念，「HAL stub 服務工廠」的想法便油然而生。

<strong>提供HAL(與*.so)代工服務與解決方案</strong>

由驅動程式專業公司進行設計與開發，即軟體服務的一種想法，基於：

1. HAL stub軟體可封閉源碼，因此也較利於商業模式推展
2. 提供關鍵IC零組件封閉原始碼的HAL stub軟體 (Proprietary software)
3. 不但是「軟硬整合」，也是Android綁定硬體平臺的一種策略

當然，想法往往都是「有感而發」，現實面能不能執行又是一回事了。   ;-)]]>
      
   </content>
</entry>
<entry>
   <title>Android 的 HAL 技術, #4: Android Service 與 HAL Stub</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/11/android-hal-android-service-hal.html" />
   <id>tag:www.jollen.org,2009:/blog//2.681</id>
   
   <published>2009-11-28T13:56:57Z</published>
   <updated>2009-11-28T12:29:37Z</updated>
   
   <summary>目前為止，我們提了「HAL Stub」的觀念，了解到 stub 是一種代理人的觀念，架構設計上，採取「provide operations」與「callback」機制，而不是採用「module」即 library 的 direct function call 做法。 接著，又提到「採取Service架構的方式」。在講解HAL stub的實作細節前，需要大略了解一下Android Service與HAL stub的關係；因為，架構設計上是「透過Android Service取得HAL stub提供的operations」。 取得HAL stub operations的程式碼實際上是實作在Native Service裡，相關的實作細節留待後續再做說明。 Android Service與HAL stub的關係 應用程式（Application）使用了Manager API，Manager API經由Android Service來到Native Service層，最後Native Service層再引用（invoke）HAL stub。這個過程，總共經過了以下3個介面，如下圖。 1. 這是一個 remote interface，應用程式與Android Service在不同的 process 上執行。 2. 這是...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[目前為止，我們提了「HAL Stub」的觀念，了解到 stub 是一種代理人的觀念，架構設計上，採取「provide operations」與「callback」機制，而不是採用「module」即 library 的 direct function call 做法。

接著，又提到「採取Service架構的方式」。在講解HAL stub的實作細節前，需要大略了解一下Android Service與HAL stub的關係；因為，架構設計上是「透過Android Service取得HAL stub提供的operations」。

取得HAL stub operations的程式碼實際上是實作在Native Service裡，相關的實作細節留待後續再做說明。

<strong>Android Service與HAL stub的關係</strong>

應用程式（Application）使用了Manager API，Manager API經由Android Service來到Native Service層，最後Native Service層再引用（invoke）HAL stub。這個過程，總共經過了以下3個介面，如下圖。

<img alt="android-service-hal.png" src="http://www.jollen.org/blog/2009/11/28/android-service-hal.png" width="423" height="329" />

1. 這是一個 remote interface，應用程式與Android Service在不同的 process 上執行。

2. 這是 Java native interface，實作上透過 JNI table 來對應 native method 與 native function。

3. 理論上，這是 HAL 層，實作上則是使用 HAL API 先取得 stub operations，再由 native service callback stub。
]]>
      
   </content>
</entry>
<entry>
   <title>Android 的 HAL 技術, #3: 小探Android Service與Native Service</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/11/android-hal-android-native-service.html" />
   <id>tag:www.jollen.org,2009:/blog//2.680</id>
   
   <published>2009-11-26T17:59:51Z</published>
   <updated>2009-11-27T11:47:16Z</updated>
   
   <summary>前二篇教學提到「採用Service架構整合HAL的做法」。這裡再針對HAL如何採用Service架構與框架整合做一個概念的介紹。 Android的Service分為二種：Android Service與Native Service。 Android Service Android Service又稱為Java Service，是實作在框架層（framework）裡的「Server」。這裡所講的「Service」是System Service，又稱為Server，與應用程式設計上所討論的Service（android.app.Service）不同。Android Service以Java撰寫。 Native Service Native Service則是實作在Runtime層裡的Server。架構設計上，我們有二個選擇，一個是實作Android Service、再透過JNI與HAL stub溝通；另一個選擇是，跳過Android Service，讓Application（Manager API）直接與Native Service溝通。 未來的Android發展趨勢，應會以第二種做法為主，即Manager API直接與Native Service溝通，以達到更好的效能表現。 延伸閱讀 * 2009.10.14: Android 的 HAL 技術, #2: 採用Service架構方式 * 2009.10.08: Android 的 HAL 技術, #1: 簡介與發展現況...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[前二篇教學提到「採用Service架構整合HAL的做法」。這裡再針對HAL如何採用Service架構與框架整合做一個概念的介紹。

Android的Service分為二種：Android Service與Native Service。

<strong>Android Service</strong>

Android Service又稱為Java Service，是實作在框架層（framework）裡的「Server」。這裡所講的「Service」是System Service，又稱為Server，與應用程式設計上所討論的Service（android.app.Service）不同。Android Service以Java撰寫。

<strong>Native Service</strong>

Native Service則是實作在Runtime層裡的Server。架構設計上，我們有二個選擇，一個是實作Android Service、再透過JNI與HAL stub溝通；另一個選擇是，跳過Android Service，讓Application（Manager API）直接與Native Service溝通。

未來的Android發展趨勢，應會以第二種做法為主，即Manager API直接與Native Service溝通，以達到更好的效能表現。

<strong>延伸閱讀</strong>

* 2009.10.14: <a href="http://www.jollen.org/blog/2009/10/android-hal-service-introduction.html">Android 的 HAL 技術, #2: 採用Service架構方式</a>
* 2009.10.08: <a href="http://www.jollen.org/blog/2009/10/android-hal-status-report.html">Android 的 HAL 技術, #1: 簡介與發展現況</a>]]>
      
   </content>
</entry>
<entry>
   <title>Symbian釋出microkernel</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/10/symbian-release-microkernel.html" />
   <id>tag:www.jollen.org,2009:/blog//2.679</id>
   
   <published>2009-10-25T14:28:48Z</published>
   <updated>2009-10-26T08:05:44Z</updated>
   
   <summary>今天重要事，與開放手機有關，但不是Android的新聞，「Symbian」幾天前發佈的新聞稿指出「EPL RELEASE OF MICROKERNEL DEMONSTRATES PROGRESS TOWARDS OPEN SOURCE GOAL」。 自從Nokia收購Symbian其餘股權後，便開始計畫將Symbian開放、成為一個開放手機平臺，經過一段時間，Symbian Foundation幾天前達成一個重要的里程碑。如上述新聞稿所述，Symbian的microkernel（EKA2）以EPL（Eclipse Public License）釋出部份套件的原始碼，其中包含了Hardware Services套件。 開發者現在可以由[developer.symbian.org]下載原始碼，並且可使用模擬器（Qemu）進行試驗。 一個比較有趣的地方是，在眾多的FOSS授權裡，Symbian Foundation選擇以EPL授權釋出原始程式碼。EPL與GPLv2或v3授權都是不相容的，其中一點是，只有該軟體的擁有人（owner）或是已經得到了owner的許可，其他人（指contributors）才能將程式碼放到其它FOSS授權的軟體裡使用。也就是說，我們不能自已把EKA2的程式碼，放進Linux kernel或BSD kernel裡使用。此外，貢獻者（contributors）也不能暱名發佈程式碼，在EPL的條款裡，貢獻者需要具名。 另外一個EPL與現有其它FOSS授權不同的地方是「衍生著作（derivative work）」的定義。EPL不以程式庫的連結（linking）來定義衍生著作，而是以美國著作權法上的說明來定義。也就是，以獨立形式（例如module）實做了一個EPL軟體上所沒有的功能時，這個module就不算是一個衍生著作。 是否為衍生著作關係到授權條款，只要是衍生著作都必須是EPL授權。也就是，自已設計的獨立模組可以隨意授權。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Open Mobile Platform" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[今天重要事，與開放手機有關，但不是Android的新聞，「Symbian」幾天前發佈的新聞稿指出「<a href="http://symbian.org/media/news/pr2009_10.php">EPL RELEASE OF MICROKERNEL DEMONSTRATES PROGRESS TOWARDS OPEN SOURCE GOAL</a>」。

自從Nokia收購Symbian其餘股權後，便開始計畫將Symbian開放、成為一個開放手機平臺，經過一段時間，Symbian Foundation幾天前達成一個重要的里程碑。如上述新聞稿所述，Symbian的microkernel（EKA2）以EPL（Eclipse Public License）釋出部份套件的原始碼，其中包含了Hardware Services套件。

開發者現在可以由[<a href="http://developer.symbian.org/wiki/index.php/Category:Kernel_&_Hardware_Services">developer.symbian.org</a>]下載原始碼，並且可使用模擬器（Qemu）進行試驗。

一個比較有趣的地方是，在眾多的FOSS授權裡，Symbian Foundation選擇以EPL授權釋出原始程式碼。EPL與GPLv2或v3授權都是不相容的，其中一點是，只有該軟體的擁有人（owner）或是已經得到了owner的許可，其他人（指contributors）才能將程式碼放到其它FOSS授權的軟體裡使用。也就是說，我們不能自已把EKA2的程式碼，放進Linux kernel或BSD kernel裡使用。此外，貢獻者（contributors）也不能暱名發佈程式碼，在EPL的條款裡，貢獻者需要具名。

另外一個EPL與現有其它FOSS授權不同的地方是「衍生著作（derivative work）」的定義。EPL不以程式庫的連結（linking）來定義衍生著作，而是以美國著作權法上的說明來定義。也就是，以獨立形式（例如module）實做了一個EPL軟體上所沒有的功能時，這個module就不算是一個衍生著作。

是否為衍生著作關係到授權條款，只要是衍生著作都必須是EPL授權。也就是，自已設計的獨立模組可以隨意授權。


]]>
      
   </content>
</entry>
<entry>
   <title>Android 的 HAL 技術, #2: 採用Service架構方式</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/10/android-hal-service-introduction.html" />
   <id>tag:www.jollen.org,2009:/blog//2.678</id>
   
   <published>2009-10-14T10:17:29Z</published>
   <updated>2009-10-14T08:15:51Z</updated>
   
   <summary>在上一篇日記裡，我們介紹了Android HAL的大概念。接下來，將慢慢地進行細部的分析與研究。首先，我們先針對HAL的現況先做討論，後續再針對HAL的設計提出觀念。 圖1：採用Service架構與不採用Service架構 如圖1，應用程式存取驅動程式的過程，可區分為以下二種： 採用Service架構方式 不採用Service架構方式 採用Service架構方式是比較標準的做法，即圖上藍色線的部份；紅色線的部份為非Service架構式的做法。先前，在「Android 驅動開發關鍵技術：HAL及移植要領」演講中最後所提出的一個LED範例，即是一種非架構式的做法，簡報上有一段範例程式碼，歡迎下載參考。 Android HAL Introduction: libhardware and its legacyView more documents from Jollen Chen. 採取Service架構的方式，是建議的做法，當然因為這是標準架構，也應該採用。 Service在Android框架裡的角色是「存取底層硬體」，往上層的話，可以和應用程式溝通。因此，採用標準的Service做法，好處是在資料存取（data communication）的處理較為系統化。這方面，Android提供了標準的處理架構，後續再進行討論。 圖上的「core libraries」即是Service程式碼的實作，也就是，Android應用程式透過JNI（Dalvik）來到Service這一層，再透過Service載入*.so檔；而非標準做法則是讓應用程式直接透過JNI來載入*.so檔。 不使用Service架構 紅色的過程，因為不使用Service架構，因此「框架整合」的工作量比較小，甚致大部份的實作都不需要改動框架本身。這樣的做法，就有點像是「跳過framework」的方式；相對的，此時應用程式開發者需要考慮的設計議題就比較多。 例如，當遇到block operation時，是否需要獨立的Java thread來處理？...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[在上一篇日記裡，我們介紹了Android HAL的大概念。接下來，將慢慢地進行細部的分析與研究。首先，我們先針對HAL的現況先做討論，後續再針對HAL的設計提出觀念。

<img alt="HAL-service-jni.png" src="http://www.jollen.org/blog/2009/10/14/HAL-service-jni.png" width="415" height="549" />
圖1：採用Service架構與不採用Service架構

如圖1，應用程式存取驅動程式的過程，可區分為以下二種：

<ul><li>採用Service架構方式</li>
<li>不採用Service架構方式</li>
</ul>

採用Service架構方式是比較標準的做法，即圖上藍色線的部份；紅色線的部份為非Service架構式的做法。先前，在「Android 驅動開發關鍵技術：HAL及移植要領」演講中最後所提出的一個LED範例，即是一種非架構式的做法，簡報上有一段範例程式碼，歡迎下載參考。

<div style="width:425px;text-align:left" id="__ss_2173827"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/jollen/android-hal-introduction-libhardware-and-its-legacy" title="Android HAL Introduction: libhardware and its legacy">Android HAL Introduction: libhardware and its legacy</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=android-os-driver-hal-r2-091009031110-phpapp01&stripped_title=android-hal-introduction-libhardware-and-its-legacy" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=android-os-driver-hal-r2-091009031110-phpapp01&stripped_title=android-hal-introduction-libhardware-and-its-legacy" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">documents</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/jollen">Jollen Chen</a>.</div></div>

採取Service架構的方式，是建議的做法，當然因為這是標準架構，也應該採用。

Service在Android框架裡的角色是「存取底層硬體」，往上層的話，可以和應用程式溝通。因此，採用標準的Service做法，好處是在資料存取（data communication）的處理較為系統化。這方面，Android提供了標準的處理架構，後續再進行討論。

圖上的「core libraries」即是Service程式碼的實作，也就是，Android應用程式透過JNI（Dalvik）來到Service這一層，再透過Service載入*.so檔；而非標準做法則是讓應用程式直接透過JNI來載入*.so檔。

<strong>不使用Service架構</strong>

紅色的過程，因為不使用Service架構，因此「框架整合」的工作量比較小，甚致大部份的實作都不需要改動框架本身。這樣的做法，就有點像是「跳過framework」的方式；相對的，此時應用程式開發者需要考慮的設計議題就比較多。

例如，當遇到block operation時，是否需要獨立的Java thread來處理？]]>
      
   </content>
</entry>
<entry>
   <title>Android 的 HAL 技術, #1: 簡介與發展現況</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/10/android-hal-status-report.html" />
   <id>tag:www.jollen.org,2009:/blog//2.677</id>
   
   <published>2009-10-07T18:05:19Z</published>
   <updated>2009-10-08T10:45:21Z</updated>
   
   <summary>Android 的 HAL（硬體抽像層）是 Google 因應廠商「希望不公開源碼」的要求下，所推出的新觀念，其架構如下圖。雖然 HAL 現在的「抽象程度」還不足，現階段實作還不是全面符合 HAL 的架構規劃，不過也確實給了我們很好的思考空間。 圖1：Android HAL 架構規劃 這是 Patrick Brady (Google) 在2008 Google I/O 所發表的演講「Anatomy &amp; Physiology of an Android」中，所提出的 Android HAL 架構圖。從這張架構圖我們知道，HAL 的目的是為了把 Android framework 與 Linux kernel 完整「隔開」。讓 Android 不至過度依賴 Linux kernel，有點像是「kernel independent」的意思，讓...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Android 的 HAL（硬體抽像層）是 Google 因應廠商「希望不公開源碼」的要求下，所推出的新觀念，其架構如下圖。雖然 HAL 現在的「抽象程度」還不足，現階段實作還不是全面符合 HAL 的架構規劃，不過也確實給了我們很好的思考空間。

<img alt="android-hal.jpg" src="http://www.jollen.org/blog/2009/10/08/android-hal.jpg" width="500" height="378" />
圖1：Android HAL 架構規劃

這是 Patrick Brady (Google) 在2008 Google I/O 所發表的演講「<a href="http://sites.google.com/site/io/anatomy--physiology-of-an-android">Anatomy & Physiology of an Android</a>」中，所提出的 Android HAL 架構圖。從這張架構圖我們知道，HAL 的目的是為了把 Android framework 與 Linux kernel 完整「隔開」。讓 Android 不至過度依賴 Linux kernel，有點像是「kernel independent」的意思，讓 Android framework 的開發能在不考量驅動程式的前提下進行發展。

在 Android 原始碼裡，HAL 主要的實作儲存於以下目錄：

1. libhardware_legacy/ - 過去的實作、採取程式庫模組的觀念進行
2. libhardware/ - 新版的實作、調整為 HAL stub 的觀念
3. ril/ - Radio Interface Layer

在 HAL 的架構實作成熟前（即圖1的規劃），我們先就目前 HAL 現況做一個簡單的分析。另外，目前 Android 的 HAL 實作，仍舊散佈在不同的地方，例如 Camera、WiFi 等，因此上述的目錄並不包含所有的 HAL 程式碼。

<strong>HAL 的過去</strong>

<img alt="android-hal-libhardware_legacy.png" src="http://www.jollen.org/blog/2009/10/08/android-hal-libhardware_legacy.png" width="330" height="264" />
圖2：Android HAL / libhardware_legacy

過去的 libhardware_legacy 作法，比較是傳統的「module」方式，也就是將 *.so 檔案當做「shared library」來使用，在 runtime（JNI 部份）以 direct function call 使用 HAL module。透過直接函數呼叫的方式，來操作驅動程式。

當然，應用程式也可以不需要透過 JNI 的方式進行，直接以載入 *.so 檔（dlopen）的做法呼叫 *.so 裡的符號（symbol）也是一種方式。

<strong>HAL 的現實狀況</strong>

<img alt="android-hal-libhardware.png" src="http://www.jollen.org/blog/2009/10/08/android-hal-libhardware.png" width="328" height="313" />
圖3：Android HAL / libhardware

現在的 libhardware 作法，就有「stub」的味道了。HAL stub 是一種代理人（proxy）的概念，stub 雖然仍是以 *.so 檔的形式存在，但 HAL 已經將 *.so 檔隱藏起來了。Stub 向 HAL「提供」操作函數（operations），而 runtime 則是向 HAL 取得特定模組（stub）的 operations，再 callback 這些操作函數。這種以 indirect function call 的實作架構，讓 HAL stub 變成是一種「包含」關係，即 HAL 裡包含了許許多多的 stub（代理人）。Runtime 只要說明「類型」，即 module ID，就可以取得操作函數。

<strong>HAL 的未來發展？</strong>

新的 HAL 做法，傾向全面採用 JNI 的方式進行。也就是，在 Android 的架構中，修改 Android runtime 實作（即「Core Library」），在取得 HAL 模組的 operations 後再做 callback 操作。將 HAL 模組完全放在 HAL 裡面。

]]>
      
   </content>
</entry>
<entry>
   <title>走入雲端的開發套件</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/10/embedded-cloud-computing.html" />
   <id>tag:www.jollen.org,2009:/blog//2.676</id>
   
   <published>2009-10-07T17:46:55Z</published>
   <updated>2009-10-07T15:05:07Z</updated>
   
   <summary>在 Linux for Devices 上的一則新聞「Embedded development kits link up to Amazon cloud」，開發板也趕流行，跑上雲端。 這是以 Debian Linux 為基礎的 Embedded Linux 開發套件，並且可以連接 Amazon 的 S3 cloud service。有趣的地方是，文中以「Embedded Cloud Computing」的方式來形容，令人有不同的發想空間。「Embedded Cloud Computing」是「連上雲端的嵌入式硬體模組」的概念。「自動化裝置」是一種嵌入式系統，讀了這篇新聞後，讓人有另外一種像想。 如果能把雲端服務，嵌入到一些自動化裝置裡，因為這類型的裝置通常不經由人類操作，所以等於進入了「設備自動連結雲端」的時代。自動化裝置可以主動將擷取的裝置，送上雲端、儲存、分析並加以應用。例如，設計一個可隨時發送座標的隨身模組。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[在 Linux for Devices 上的一則新聞「<a href="http://www.linuxfordevices.com/c/a/News/SSV-SSVECC-eSOMEK1ECC-and-eSOMEK1ECC/">Embedded development kits link up to Amazon cloud</a>」，開發板也趕流行，跑上雲端。

這是以 Debian Linux 為基礎的 Embedded Linux 開發套件，並且可以連接 Amazon 的 S3 cloud service。有趣的地方是，文中以「Embedded Cloud Computing」的方式來形容，令人有不同的發想空間。「Embedded Cloud Computing」是「連上雲端的嵌入式硬體模組」的概念。「自動化裝置」是一種嵌入式系統，讀了這篇新聞後，讓人有另外一種像想。

如果能把雲端服務，嵌入到一些自動化裝置裡，因為這類型的裝置通常不經由人類操作，所以等於進入了「設備自動連結雲端」的時代。自動化裝置可以主動將擷取的裝置，送上雲端、儲存、分析並加以應用。例如，設計一個可隨時發送座標的隨身模組。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#31: R.drawable 應用-如何使用NinePatch圖檔</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/09/jollen-android-programming-31.html" />
   <id>tag:www.jollen.org,2009:/blog//2.674</id>
   
   <published>2009-09-20T14:39:33Z</published>
   <updated>2009-09-20T12:30:10Z</updated>
   
   <summary><![CDATA[上一篇日記介紹了「如何製作NinePatch圖檔」，因此有讀者問到「如何寫程式」，因此特別補上這篇教學。 開始寫程式: HelloNinePatch 範例HelloNinePatch的實作方式如下。 Step 1. 建立一個新的Android專案，命名為HelloNinePatch。 Step 2. 將arrow.9.png托曳(drag)到HelloNinePatch專案裡的「res/drawable」目錄下。如圖1。 圖1: 將arrow.9.png放進res/drawable資料夾 Step 3. 修改UI（res/layout/main.xml），設計出上一篇教學(#30)裡的圖2畫面。main.xml的內容如下。 &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" &gt; &lt;Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="small world" android:textSize="12sp" android:background="@drawable/arrow" /&gt; &lt;Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="big world" android:textSize="24sp" android:background="@drawable/arrow" /&gt;...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[上一篇日記介紹了「如何製作NinePatch圖檔」，因此有讀者問到「如何寫程式」，因此特別補上這篇教學。

<strong>開始寫程式: HelloNinePatch</strong>

範例HelloNinePatch的實作方式如下。

Step 1. 建立一個新的Android專案，命名為HelloNinePatch。

Step 2. 將arrow.9.png托曳(drag)到HelloNinePatch專案裡的「res/drawable」目錄下。如圖1。

<img alt="ninepatch-res-1.png" src="http://www.jollen.org/blog/2009/09/20/ninepatch-res-1.png" width="244" height="208" />
圖1: 將arrow.9.png放進res/drawable資料夾

Step 3. 修改UI（res/layout/main.xml），設計出上一篇教學(#30)裡的圖2畫面。main.xml的內容如下。

<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    &gt;
&lt;Button
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="small world"
    android:textSize="12sp"
    android:background="@drawable/arrow"
    /&gt;
&lt;Button
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="big world"
    android:textSize="24sp"
    android:background="@drawable/arrow"
    /&gt;
&lt;Button
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="super world"
    android:textSize="48sp"
    android:background="@drawable/arrow"
    /&gt;
&lt;/LinearLayout&gt;</pre>

這裡的做法是，在UI上擺放Button元件，並設定Button上的文字及大小。透過「android:background」屬性的設定，我們將Button的背景設定為「@drawable/arrow」，即「drawable資源（drawable/目錄下）裡的arrow圖檔」，Android框架會去找到arrow.9.png檔案。

因為arrow.9.png是一張NinePatch圖檔，因此會隨著Button上的文字大小延展。

Step 4: 完成HellNinePatch

程式碼不需要做任何修改，直接執行HelloNinePatch專案即可。
]]>
      
   </content>
</entry>
<entry>
   <title>清華大學Android種子教學培訓課程: Day1 上課紀錄</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/09/nthu-android-training-day1.html" />
   <id>tag:www.jollen.org,2009:/blog//2.673</id>
   
   <published>2009-09-07T17:58:41Z</published>
   <updated>2009-09-07T15:12:06Z</updated>
   
   <summary> 第一天的「Android種子培訓課程」以應用開發為主軸，介紹了Android應用程式入門的課程。現場有許多大學的老師，因此在課程進行中，特別給了一些建議。針對Android應用程式入門教學來說，做「API走訪式」的教學比較無法切中正題，而且也讓課程顯得乏味。因此，我給了二點小建議： 1. Android應用的教學，以「應用程式的模式」為重心，因為Android應用程式的入門重點在於Activity/Service、R.java、XML layout、XML attributes、View（UI）、Intent等「模式」的觀念，所以最好不要採取API介紹式的教學方法 這裡的所提的「模式」即「撰寫程式」的方法。 2. 透過Android應用程式建立對框架（Framework）的基本認識。Android作業系統的一大重點在於「框架的設計」，而對應用程式進行較深度的分析，是了解框架設計的一個好方法。 例如，今天在課堂中所提到的「應用程式向框架取得（get）物件（object）」，而不是「應用程式自行建立物件（&quot;new&quot;一個object）」的觀念。另外一個觀念，則是「應用程式要避免建立物件」，這是Android Dev Guide提到的「為效能而設計」的第一個條文。 第二天的課程將會開始介紹Android開發平臺，並展示一些「Lab」範例。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<img alt="android-nthu-day1.png" src="http://www.jollen.org/blog/2009/09/08/android-nthu-day1.png" width="580" height="327" />

第一天的「Android種子培訓課程」以應用開發為主軸，介紹了Android應用程式入門的課程。現場有許多大學的老師，因此在課程進行中，特別給了一些建議。針對Android應用程式入門教學來說，做「API走訪式」的教學比較無法切中正題，而且也讓課程顯得乏味。因此，我給了二點小建議：

1. Android應用的教學，以「應用程式的模式」為重心，因為Android應用程式的入門重點在於Activity/Service、R.java、XML layout、XML attributes、View（UI）、Intent等「模式」的觀念，所以最好不要採取API介紹式的教學方法

這裡的所提的「模式」即「撰寫程式」的方法。

2. 透過Android應用程式建立對框架（Framework）的基本認識。Android作業系統的一大重點在於「框架的設計」，而對應用程式進行較深度的分析，是了解框架設計的一個好方法。

例如，今天在課堂中所提到的「應用程式向框架取得（get）物件（object）」，而不是「應用程式自行建立物件（"new"一個object）」的觀念。另外一個觀念，則是「應用程式要避免建立物件」，這是Android Dev Guide提到的「為效能而設計」的第一個條文。

第二天的課程將會開始介紹Android開發平臺，並展示一些「Lab」範例。]]>
      
   </content>
</entry>
<entry>
   <title>深耕校園、 清華大學Android種子教學培訓課程</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/08/android-campus-plan-taiwan.html" />
   <id>tag:www.jollen.org,2009:/blog//2.671</id>
   
   <published>2009-08-29T03:36:16Z</published>
   <updated>2009-08-29T02:30:43Z</updated>
   
   <summary>Android校園計畫 產學官三界過去在Android的發展做了很多腦力激盪的工作，這是一個很好的現象，有助於Android熱潮的延續，以及各界對Android作業系統的重視。提到Android研發能量的建立，最根本的治理方式是「深耕校園」。 因此，現階段要務是「深耕校園」。實際做法建議是「建立種子」。建立種子師資或種子學生，透過導入課程至大學課程的方式，讓大一與大二的學生「認識」並「開始接觸」Android作業系統；種子學生的建立，可以鎖定大三以上、研究生或是以實驗室為單位，做為培訓對象。這個階段的做法，可以建立採取「種子培訓營」的方式進行。 學生如果能被適當的訓練，就能將把創造力，或是想像力，轉換成「具體」的成果。一個實際的例子是，如果能訓練非資訊本科系的學生撰寫Android應用程式，學生才能有能力把想法轉換成「程式原型」、才能展現創意。因此「深耕校園」的目標應該是要更「普及」，而不是只導入本科系。 活動詳情可參閱嵌入式軟體聯盟網站，以下是課程資訊。希望藉由自已在教育訓練方面的經驗，貢獻棉薄之力。 課程簡介 本課程的目的是培訓大專校院之Android種子教學師資。課程針對Android系統，由底層框架、驅動程式、移植、到應用開發，做一完整的介紹，並利用OpenMoko FreeRunner手機為實驗平臺，實際動手實作。整個課程設計以符合業界實際需要為重點，藉由本課程之培訓，讓學校能充實Android研發能量，未來達到產學結合的效果。 時間：98年9月7日 (星期一) 至9月10日 (星期四) 地點：清華大學資訊電機館資工系3F 328室 資格：國內各大專校院教師或學生，對Android系統之教學及開發有濃厚興趣者 名額：40人 費用：NT$ 2,500 (含午餐、設備使用費、講義；報名後通知繳費) 主辦單位：教育部顧問室嵌入式軟體聯盟、清華大學電腦與通訊科技研發中心、清華大學資訊工程學系 協辦單位：Jollen’s Consulting、清華大學OpenLab 聯絡人： 吳少文小姐 Tel: 03-5742410 E-mail: swwu@mx.nthu.edu.tw...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<strong>Android校園計畫</strong>

產學官三界過去在Android的發展做了很多腦力激盪的工作，這是一個很好的現象，有助於Android熱潮的延續，以及各界對Android作業系統的重視。提到Android研發能量的建立，最根本的治理方式是「深耕校園」。

因此，現階段要務是「深耕校園」。實際做法建議是「建立種子」。建立種子師資或種子學生，透過導入課程至大學課程的方式，讓大一與大二的學生「認識」並「開始接觸」Android作業系統；種子學生的建立，可以鎖定大三以上、研究生或是以實驗室為單位，做為培訓對象。這個階段的做法，可以建立採取「種子培訓營」的方式進行。

學生如果能被適當的訓練，就能將把創造力，或是想像力，轉換成「具體」的成果。一個實際的例子是，如果能訓練非資訊本科系的學生撰寫Android應用程式，學生才能有能力把想法轉換成「程式原型」、才能展現創意。因此「深耕校園」的目標應該是要更「普及」，而不是只導入本科系。

活動詳情可參閱<a href="http://esw.cs.nthu.edu.tw/">嵌入式軟體聯盟網站</a>，以下是課程資訊。希望藉由自已在教育訓練方面的經驗，貢獻棉薄之力。

<strong>課程簡介</strong>
	
本課程的目的是培訓大專校院之Android種子教學師資。課程針對Android系統，由底層框架、驅動程式、移植、到應用開發，做一完整的介紹，並利用OpenMoko FreeRunner手機為實驗平臺，實際動手實作。整個課程設計以符合業界實際需要為重點，藉由本課程之培訓，讓學校能充實Android研發能量，未來達到產學結合的效果。

時間：98年9月7日 (星期一) 至9月10日 (星期四)
地點：清華大學資訊電機館資工系3F 328室
資格：國內各大專校院教師或學生，對Android系統之教學及開發有濃厚興趣者
名額：40人
費用：NT$ 2,500 (含午餐、設備使用費、講義；報名後通知繳費)
主辦單位：教育部顧問室嵌入式軟體聯盟、清華大學電腦與通訊科技研發中心、清華大學資訊工程學系
協辦單位：Jollen’s Consulting、清華大學OpenLab
聯絡人： 	吳少文小姐  Tel: 03-5742410  E-mail: swwu@mx.nthu.edu.tw

]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#30: R.drawable 應用-製作NinePatch圖檔</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/08/jollen-android-programming-30.html" />
   <id>tag:www.jollen.org,2009:/blog//2.670</id>
   
   <published>2009-08-22T15:05:27Z</published>
   <updated>2009-09-20T11:16:23Z</updated>
   
   <summary>什麼是NinePatch圖檔 NinePatch是一種「可延展」的PNG圖檔。NinePatch圖檔的用途是製作「可隨文字大小縮放」的圖片，如圖1。 圖1: 文字背景可隨著文字大小縮放 NinePatch是很有用的圖片格式，可做為widget的「背景圖」。如圖１的範例，其應用程式的設計如下： 文字部份使用TextView元件 使用TextView的XML attribute來設定文字大小 使用TextView的XML attribute來設定一張背景圖 使用NinePatch圖片做為背景圖，如此一來背景圖就可以隨著文字大小縮放 首先，第一個工作就是「製作NinePatch圖檔」，方式如下。 Step 1. 準備一張原始的PNG圖檔，如圖2。 圖2: 原始PNG圖檔（arrow.png） Step 2. 啟動Android提供的draw9patch工具，直接執行Android SDK tools/目錄下的draw9patch執行檔即可，如圖3。 圖3: Android SDK提供的draw9patch工具（點擊看原圖） Step 3. 開啟原始PNG圖檔，編輯圖檔，如圖4。 圖4: 開始編輯圖檔（點擊看原圖） 如何編輯NinePatch圖檔 NinePatch圖檔的製作方式是「繪製二條線」，分別在原始圖檔的上方與左方繪出二條「黑線」，黑線所交集的區域即為「可延展」區域。如下圖的粉紅色區域。 圖5: 定義延展區 「可延展區」是Android框架用來擺放文字的區域，換句話說，文字(TextView)只會被放置在粉紅色區域，並且擺放的原則是「對準粉紅區域的中心點」，即上下置中、左右也置中。非「可延展區」，即綠色部份，並不會隨著文字的大小縮放延展。所以： 1. 綠色區域是固定大小區域 2. 粉紅色區域是可延展區域、文字擺放於此 圖中的「二條黑線」是怎麼畫出來的呢？方式如下。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<strong>什麼是NinePatch圖檔</strong>

NinePatch是一種「可延展」的PNG圖檔。NinePatch圖檔的用途是製作「可隨文字大小縮放」的圖片，如圖1。

<img alt="ninepatch-1.png" src="http://www.jollen.org/blog/2009/08/22/ninepatch-1.png" width="320" height="480" />
圖1: 文字背景可隨著文字大小縮放

NinePatch是很有用的圖片格式，可做為widget的「背景圖」。如圖１的範例，其應用程式的設計如下：

<ul><li>文字部份使用TextView元件</li>
<li>使用TextView的XML attribute來設定文字大小</li>
<li>使用TextView的XML attribute來設定一張背景圖</li>
<li>使用NinePatch圖片做為背景圖，如此一來背景圖就可以隨著文字大小縮放</li></ul>

首先，第一個工作就是「製作NinePatch圖檔」，方式如下。

Step 1. 準備一張原始的PNG圖檔，如圖2。

<img alt="ninepatch-2.png" src="http://www.jollen.org/blog/2009/08/22/ninepatch-2.png" width="128" height="105" />
圖2: 原始PNG圖檔（arrow.png）

Step 2. 啟動Android提供的draw9patch工具，直接執行Android SDK tools/目錄下的draw9patch執行檔即可，如圖3。

<a href="http://www.jollen.org/blog/2009/08/22/ninepatch-3.png" target="_blank"><img alt="ninepatch-3.png" src="http://www.jollen.org/blog/2009/08/22/ninepatch-3.png" width="480" border="0" /></a>
圖3: Android SDK提供的draw9patch工具（點擊看原圖）

Step 3. 開啟原始PNG圖檔，編輯圖檔，如圖4。

<a href="http://www.jollen.org/blog/2009/08/22/ninepatch-4.png" target="_blank"><img alt="ninepatch-4.png" src="http://www.jollen.org/blog/2009/08/22/ninepatch-4.png" width="480" border="0" /></a>
圖4: 開始編輯圖檔（點擊看原圖）

<strong>如何編輯NinePatch圖檔</strong>

NinePatch圖檔的製作方式是「繪製二條線」，分別在原始圖檔的上方與左方繪出二條「黑線」，黑線所交集的區域即為「可延展」區域。如下圖的粉紅色區域。

<img alt="ninepatch-5.png" src="http://www.jollen.org/blog/2009/08/22/ninepatch-5.png" width="433" height="427" />
圖5: 定義延展區

「可延展區」是Android框架用來擺放文字的區域，換句話說，文字(TextView)只會被放置在粉紅色區域<strike>，並且擺放的原則是「對準粉紅區域的中心點」，即上下置中、左右也置中</strike>。非「可延展區」，即綠色部份，並不會隨著文字的大小<strike>縮放</strike>延展。所以：

1. 綠色區域是固定大小區域
2. 粉紅色區域是可延展區域、文字擺放於此

圖中的「二條黑線」是怎麼畫出來的呢？方式如下。

Step 4. 移動「Zoom」調整圖檔比例，讓「斑馬線」的大小能適中，如圖6。

<img alt="ninepatch-6.png" src="http://www.jollen.org/blog/2009/08/22/ninepatch-6.png" width="598" height="498" />
圖6: 調整比例

Step 7: 畫黑線

斑馬線是用來畫黑線的區域，怎麼畫黑線呢？用滑鼠點斑馬線就可以了。要怎麼刪除黑線上？按住「Shift」再點斑馬線即可。斑馬線很不好點，所以如果不是要特意訓練操作滑鼠的技巧以及考驗眼力，善用「Zoom」功能可以幫助黑線的繪製。

勾選「Show patches」選項，即可顯示粉紅色區域，如圖7。

<img alt="ninepatch-7.png" src="http://www.jollen.org/blog/2009/08/22/ninepatch-7.png" width="542" height="451" />
圖7: 即時顯示可延展區

在draw9patch的右邊也會有縮放的展示圖。

Step 8: 完成NinePatch圖檔

儲存完成的NinePatch圖檔，draw9patch會自動將圖檔的副檔名儲存為*.9.png。完成NinePatch圖檔後，就可以開始寫程式了。

* Update: 2009/9/20 - Android擺放文字於NinePatch圖檔上的原則「並非對準粉紅區域的中心點」，已刪除此句。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#29: HelloIntentWallpaper - 背景圖選擇器</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/08/jollen-android-programming-29.html" />
   <id>tag:www.jollen.org,2009:/blog//2.665</id>
   
   <published>2009-08-22T14:52:26Z</published>
   <updated>2009-08-22T12:03:12Z</updated>
   
   <summary>Android提供「SET_WALLPAPER」的內建Intent，當框架收到這個Intent時，就會啟動「背景圖選擇器」，讓我們選取新的背景圖。送出SET_WALLPAPER intent的程式寫法如下： Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER); startActivity(Intent.createChooser(intent, &quot;Select Wallpaper&quot;)); 根據Reference Guide的說明，SET_WALLPAPER會啟動一個內容選擇器，所以同時地，我們先呼叫createChooser()方法建立一個內容選擇器後，再送出Intent。 完整程式碼: HelloIntentWallpaper.java package com.moko.hellointentwallaper; 　 import com.moko.hellointentwallaper.R; 　 import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; 　 public class HelloIntentWallpaper extends Activity implements View.OnClickListener { /**...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Android提供「SET_WALLPAPER」的內建Intent，當框架收到這個Intent時，就會啟動「背景圖選擇器」，讓我們選取新的背景圖。送出SET_WALLPAPER intent的程式寫法如下：

<pre>        Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER);
        startActivity(Intent.createChooser(intent, "Select Wallpaper"));</pre>

根據Reference Guide的說明，SET_WALLPAPER會啟動一個內容選擇器，所以同時地，我們先呼叫createChooser()方法建立一個內容選擇器後，再送出Intent。

<strong>完整程式碼: HelloIntentWallpaper.java</strong>

<pre>package com.moko.hellointentwallaper;
　
import com.moko.hellointentwallaper.R;
　
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
　
public class HelloIntentWallpaper extends Activity implements View.OnClickListener {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        　
        Button button = (Button)findViewById(R.id.set_wallpaper);
        button.setOnClickListener(this);
    }
　
    public void onClick(View v) {
<strong>        Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER);
        startActivity(Intent.createChooser(intent, "Select Wallpaper"));</strong>
    }
}</pre>

<strong>UI設計: layout/main.xml</strong>

<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    &gt;
	&lt;TextView  
	    android:layout_width="fill_parent" 
	    android:layout_height="wrap_content" 
	    android:text="@string/hello"
	    /&gt;
    &lt;Button android:id="@+id/set_wallpaper"
        android:layout_width="wrap_content" android:layout_height="wrap_content" 
        android:text="@string/set_wallpaper"&gt;
        &lt;requestFocus /&gt;
    &lt;/Button&gt;
&lt;/LinearLayout&gt;</pre>

<strong>執行結果</strong>

<img alt="hellointentwallpaper-1.png" src="http://www.jollen.org/blog/2009/08/22/hellointentwallpaper-1.png" width="320" height="480" />
圖1: HelloIntentWallpaper主程式

<img alt="hellointentwallpaper-2.png" src="http://www.jollen.org/blog/2009/08/22/hellointentwallpaper-2.png" width="320" height="480" />
圖2: 「背景圖」選擇器]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#28: HelloIntentSelect - 內容選擇器(Content Chooser)</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/08/jollen-android-programming-28.html" />
   <id>tag:www.jollen.org,2009:/blog//2.664</id>
   
   <published>2009-08-07T15:13:25Z</published>
   <updated>2009-08-07T12:19:43Z</updated>
   
   <summary>上一篇教學提到如何利用Intent實作「自動撥放」程式。而另外一個較具代表性的Intent應用就是「內容選擇器」。例如，要怎麼實作一個音樂撥放機呢？先說明音樂撥放器HelloIntentSelect範例的使用情境如下： 1. 執行HelloIntentSelect後，出現一個「撥放音樂」的按鈕 2. 按下按鈕後，選擇一個音樂檔撥放 實作「選擇音樂檔」的做法是使用Intent的「chooser」觀念。程式做法如下： 1. 建立action為ACTION_GET_CONTENT的Intent： 　Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 2.設定Intent的mime type，例如：設定Intent的mime type為聲音檔案： 　intent.setType(&quot;audio/*&quot;); 3.建立內容選擇器並送出Intent： 　startActivity(Intent.createChooser(intent, &quot;Select music&quot;)); 以上的程式是根據Android的Reference Guide寫出來的。當Intent action為ACTION_GET_CONTENT時，表示要根據mime type來「取得內容」(get content)，因此呼叫setType()方法，來定義內容的mime type。 定義好mime type後，再呼叫createChooser()方法來產生能取得此mime type內容的「選擇器」，簡單說，就是一個「檔案選取程式」。 利用Android的Intent觀念，我們以不到十行的程式碼實作了一個音樂撥放器。 Action的屬性寫法與常數寫法 Intent的action寫法有二種。第一種寫法是屬性(attribute)寫法，例如第一個HelloIntentDialer範例： 　dial.setAction(&quot;android.intent.action.CALL&quot;); 在「android.intent.action」套件(package)裡，定義了action的屬性。第二種寫法是常數寫法，例如第二個HelloIntentSelect範例： 　Intent intent = new Intent(Intent.ACTION_GET_CONTENT);...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[上一篇教學提到如何利用Intent實作「自動撥放」程式。而另外一個較具代表性的Intent應用就是「內容選擇器」。例如，要怎麼實作一個音樂撥放機呢？先說明音樂撥放器HelloIntentSelect範例的使用情境如下：

1. 執行HelloIntentSelect後，出現一個「撥放音樂」的按鈕
2. 按下按鈕後，選擇一個音樂檔撥放

實作「選擇音樂檔」的做法是使用Intent的「chooser」觀念。程式做法如下：

1. 建立action為ACTION_GET_CONTENT的Intent：

　Intent intent = new Intent(Intent.ACTION_GET_CONTENT);

2.設定Intent的mime type，例如：設定Intent的mime type為聲音檔案：

　intent.setType("audio/*");

3.建立內容選擇器並送出Intent：

　startActivity(Intent.createChooser(intent, "Select music"));

以上的程式是根據Android的Reference Guide寫出來的。當Intent action為ACTION_GET_CONTENT時，表示要根據mime type來「取得內容」(get content)，因此呼叫setType()方法，來定義內容的mime type。

定義好mime type後，再呼叫createChooser()方法來產生能取得此mime type內容的「選擇器」，簡單說，就是一個「檔案選取程式」。

利用Android的Intent觀念，我們以不到十行的程式碼實作了一個音樂撥放器。

<strong>Action的屬性寫法與常數寫法</strong>

Intent的action寫法有二種。第一種寫法是屬性(attribute)寫法，例如第一個HelloIntentDialer範例：

　dial.setAction("android.intent.action.CALL");

在「android.intent.action」套件(package)裡，定義了action的屬性。第二種寫法是常數寫法，例如第二個HelloIntentSelect範例：

　Intent intent = new Intent(Intent.ACTION_GET_CONTENT);

在「Intent」類別(class)裡，定義了action的常數。在記憶的技巧上，可以用「xxx對於到ACTION_xxx」的方式記。例如：

CALL（android.intent.action.CALL）就是ACTION_CALL（Intent.ACTION_CALL）。

又如，所以當我們講「GET_CONTENT」時，指的就是android.intent.action.GET_CONTENT；同理，講ACTON_GET_CONTENT時，就是代表Intent.ACTION_GET_CONTNET。所以「GET_CONTENT」與「ACTION_GET_CONTNET」代表相同的Intent。

<img alt="hellointentselect-1.png" src="http://www.jollen.org/blog/2009/08/07/hellointentselect-1.png" width="320" height="480" />
圖1: HelloIntentSelect主程式

<img alt="hellointentselect-2.png" src="http://www.jollen.org/blog/2009/08/07/hellointentselect-2.png" width="320" height="480" />
圖2: 出現一個Content Chooser:「音樂選擇器」
]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#27: 使用ACTION_CALL實作自動撥號: HelloIntentDialer</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/08/jollen-android-programming-27.html" />
   <id>tag:www.jollen.org,2009:/blog//2.663</id>
   
   <published>2009-08-07T03:25:30Z</published>
   <updated>2009-08-07T00:31:20Z</updated>
   
   <summary>HelloIntentDialer是一個自動撥號程式，執行時會自動撥號到指定的電話。這樣的程式要怎麼寫呢？先看到HelloIntentDialer.java的完整程式如下： package com.moko.hellointentdialer; 　 import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; 　 public class HelloIntentDialer extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); 　 Intent dial =...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[HelloIntentDialer是一個自動撥號程式，執行時會自動撥號到指定的電話。這樣的程式要怎麼寫呢？先看到HelloIntentDialer.java的完整程式如下： 

<pre>package com.moko.hellointentdialer;
　
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
　
public class HelloIntentDialer extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        　
        Intent dial = new Intent();
        dial.setAction("android.intent.action.CALL");
        dial.setData(Uri.parse("tel:119"));
        startActivity(dial);        
    }
}</pre>

因為permission的關係，所以也要在AndroidManifest.xml裡加上「CALL_PHONE」的權限。AndroidManifest.xml的完整內容如下：

<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.moko.hellointentdialer"
      android:versionCode="1"
      android:versionName="1.0"&gt;
    &lt;application android:icon="@drawable/icon" android:label="@string/app_name">
        &lt;activity android:name=".HelloIntentDialer"
                  android:label="@string/app_name"&gt;
            &lt;intent-filter>
                &lt;action android:name="android.intent.action.MAIN" /&gt;
                &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
            &lt;/intent-filter&gt;
        &lt;/activity&gt;
    &lt;/application&gt;
    &lt;uses-sdk android:minSdkVersion="3" /&gt;
    &lt;uses-permission android:name="android.permission.CALL_PHONE" /&gt;
&lt;/manifest>&gt;</pre>

這個範例相當簡單，但足以說明Intent的核心精神了。程式說明：

1. 先產生一個Intent物件：

　Intent dial = new Intent();

2. 設定Intent的action為「android.intent.action.CALL」，這是一個內建的action：

　dial.setAction("android.intent.action.CALL");

內建action「CALL」需要附帶一筆資料，而資料的寫法是使用URI格式：

　dial.setData(Uri.parse("tel:119"));

4. 「CALL」是一個activity action，所以呼叫startActivity()向Intent送給框架：

　startActivity(dial);   

這個範例的概念並不難，「送出一個帶有內建action的Intent給框架，因為action為CALL，所以框架會去啟動撥號activity並打電話。」]]>
      
   </content>
</entry>
<entry>
   <title>CTimes 矽導論壇：從Android看小筆電的機會</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/08/android-netbook-opportunity.html" />
   <id>tag:www.jollen.org,2009:/blog//2.662</id>
   
   <published>2009-08-05T09:48:31Z</published>
   <updated>2009-08-05T07:15:46Z</updated>
   
   <summary>文／陳俊宏(Jollen Chen) Contact: jollen@jollen.org （原文刊載於零組件雜誌2009年5月份） 技術端須補缺口 產品端須達到實用性 社群開發者將Android移植到EeePC後，興起一股「Android小筆電」討論風潮。幾個月後，市場上刮起了一陣開發Android小筆電的新聞。現在，幾家品牌大廠，對Android小筆電市場更是磨刀霍霍。對於這陣Android小筆電的風潮要如何解讀？在此分享個人的觀察與想法，請不吝指教。 Android小筆電的概念是由開發者社群所帶來的。網路上的技術玩家，將 Android 移植到 EeePC 701，並將這個新概念放到YouTube上分享。隨後，網路上開始出現討論，社群網站也接著進行報導，經由社群的推波助瀾，主流媒體也開始進行報導，接著，就像現在我們所看到的現象，Android小筆電開始吸引廠商的注意，大家都認為這是一個有不錯商機的產品。對於Android小筆電產品的熱潮，廠商與使用者的期待與想像也是一個主因。從技面的角度來看，Android小筆電仍有使用介面（UI）上的疑慮。由於Android介面的設計預設對象為手機，因此在小筆電上的畫面表現較不理想，操作方面亦同。Android小筆電在技術端仍需填補一些缺口。 但是，我們不仿從另一個「非技術面」的角度來思考。基於「使用應用程式、上網」為概念的小筆電，看來仍是微軟作業系統的天下，Linux小筆電在市場上起不了大作用的原因是「使用習慣」的問題。因為，使用者免不了將Linux小筆電與微軟系統的小筆電拿來比較。Linux上有OpenOffice 辦公軟體，但微軟系統小筆電上有使用者更習慣的Office套裝軟體；Linux上有Thunderbird電子郵件軟體，但微軟系統小筆電有使用者更習慣的Outlook軟體；不論是上網、電子郵件還是即時通訊，Linux小筆電上的「應用程式」都讓使用者操作得很沒有安全感。 基於「網路服務」概念的Android平臺，因為與微軟系統的小筆電有很大的差異性，因此似乎存在不錯的機會。Android平臺不基於 Linux桌面技術，我們不能將OpenOffice軟體，或是Firefox瀏覽器安裝在Android小筆電上，正好能與現有的小筆電做出相當大的市場區隔。因此有一個很好機會是，我們可以讓使用者很自然地不將Android小筆電與微軟系統小筆電拿來做比較。差異性與區隔性，讓Android小筆電浮現市場價值。 總結來看，現階段Android小筆電仍處於技術玩票階段，要讓Android介面適用在小筆電產品上仍有一些技術距離；Android技術平臺與典型的Linux桌面環境截然不同，Linux或微軟的應用程式，無法「移植」到Android平臺上，但這個技術上的大不同，正好給了Android 小筆電「差異化」的想像空間。產品定位方面，把Android做為取代微軟系統的想法，反而讓Android小筆電失去差異性；應將Android平臺做為「產品使用區隔」的有效工具。未來Android若真的能開發出適合小筆電的版本，一定是個很酷產品。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      文／陳俊宏(Jollen Chen)
Contact: jollen@jollen.org
（原文刊載於零組件雜誌2009年5月份）

技術端須補缺口 產品端須達到實用性

社群開發者將Android移植到EeePC後，興起一股「Android小筆電」討論風潮。幾個月後，市場上刮起了一陣開發Android小筆電的新聞。現在，幾家品牌大廠，對Android小筆電市場更是磨刀霍霍。對於這陣Android小筆電的風潮要如何解讀？在此分享個人的觀察與想法，請不吝指教。

Android小筆電的概念是由開發者社群所帶來的。網路上的技術玩家，將 Android 移植到 EeePC 701，並將這個新概念放到YouTube上分享。隨後，網路上開始出現討論，社群網站也接著進行報導，經由社群的推波助瀾，主流媒體也開始進行報導，接著，就像現在我們所看到的現象，Android小筆電開始吸引廠商的注意，大家都認為這是一個有不錯商機的產品。對於Android小筆電產品的熱潮，廠商與使用者的期待與想像也是一個主因。從技面的角度來看，Android小筆電仍有使用介面（UI）上的疑慮。由於Android介面的設計預設對象為手機，因此在小筆電上的畫面表現較不理想，操作方面亦同。Android小筆電在技術端仍需填補一些缺口。

但是，我們不仿從另一個「非技術面」的角度來思考。基於「使用應用程式、上網」為概念的小筆電，看來仍是微軟作業系統的天下，Linux小筆電在市場上起不了大作用的原因是「使用習慣」的問題。因為，使用者免不了將Linux小筆電與微軟系統的小筆電拿來比較。Linux上有OpenOffice 辦公軟體，但微軟系統小筆電上有使用者更習慣的Office套裝軟體；Linux上有Thunderbird電子郵件軟體，但微軟系統小筆電有使用者更習慣的Outlook軟體；不論是上網、電子郵件還是即時通訊，Linux小筆電上的「應用程式」都讓使用者操作得很沒有安全感。

基於「網路服務」概念的Android平臺，因為與微軟系統的小筆電有很大的差異性，因此似乎存在不錯的機會。Android平臺不基於 Linux桌面技術，我們不能將OpenOffice軟體，或是Firefox瀏覽器安裝在Android小筆電上，正好能與現有的小筆電做出相當大的市場區隔。因此有一個很好機會是，我們可以讓使用者很自然地不將Android小筆電與微軟系統小筆電拿來做比較。差異性與區隔性，讓Android小筆電浮現市場價值。

總結來看，現階段Android小筆電仍處於技術玩票階段，要讓Android介面適用在小筆電產品上仍有一些技術距離；Android技術平臺與典型的Linux桌面環境截然不同，Linux或微軟的應用程式，無法「移植」到Android平臺上，但這個技術上的大不同，正好給了Android 小筆電「差異化」的想像空間。產品定位方面，把Android做為取代微軟系統的想法，反而讓Android小筆電失去差異性；應將Android平臺做為「產品使用區隔」的有效工具。未來Android若真的能開發出適合小筆電的版本，一定是個很酷產品。
      
   </content>
</entry>
<entry>
   <title>CTimes 矽導論壇：經營Android軟體設計服務、需要不同的思考</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/08/android-outsourcing-business-strategy.html" />
   <id>tag:www.jollen.org,2009:/blog//2.661</id>
   
   <published>2009-08-05T09:35:34Z</published>
   <updated>2009-08-05T07:09:40Z</updated>
   
   <summary>文／陳俊宏(Jollen Chen) Contact: jollen@jollen.org （原文刊載於零組件雜誌2009年8月份） 軟體委外設計服務 - 百年老店、全新感受 委外服務（outsourcing）在科技產業是一種普遍的商業模式，透過委外取得解決方案，以及後續服務是產品開發的一種做法，委外服務供應商透過「接案」的方式獲取利潤。特別是在軟體方面，有許多代表性的「軟體代工」廠，讓軟體代工成為委外服務的代表作。 隨著Android被大量關注以及採用，會有越來越多的「Android設計服務」公司出現，透過觀察，確實也有很多專門承接Android軟體專案的公司、小團隊或個人，這是不令人感到意外的現象。在討論Android設計服務前，不如先來思考一下近來當紅的線上軟體商店模式。 Android Market提供的商業模式是收取「安裝」費用，即使用者下載的拷貝(copy)數決定了軟體開發商的營收，雖然Android Market還沒有像App Store這樣成熟，但是「線上軟體商店」的模式幾乎已經被確立了，「應該要做market」的公司，也都宣佈他們的market方案了。這種賺取拷貝數的商業模式最簡單沒有負擔，可以說是比微型創業更小型的創業方式，唯一的考量的是流通在外的裝置(device)數量，因為裝置流通越多，軟體被下載的機會與次數越高。 再談到委外開發的模式，什麼樣的公司，會有「Android應用軟體委外設計」的需求？無疑是想要「bundle」特殊軟體在「產品」上的公司，希望有些軟體在機器出廠時就被安裝，在這樣的前提下，就有二個想法。第一，我們可以單純提供設計服務、交付成果，再由廠商預裝到裝置上，這時「安裝數量」與收費就沒有關係；第二，可以提供收取權利金的方式，安裝到裝置的數量，決定收費，等於收取拷貝數的費用。 對設計服務公司而言，採用以拷貝數為基礎的模式，是比較好的模式，但是這種模式能不能被廠商接受？衡量的依據之一是「解決問題」，或是「提供價值」。一項只能解決問題（技術難題）的服務，大體上只能以服務收費為主；而一個能提高產品價值的軟體，就能收取拷貝數的錢。在這裡所討論的是Android的設計服務，在其他領域，銷售「關鍵技術」是一個很好的商業模式。 Android應用軟體設計商，還要具備的一個思惟是，Android應用軟體是可以被安裝到「任何」的Android裝置上的；因此，為單一廠商或單一產品設計軟體，收取服務費用，還不如自已擁有(own)該軟體的所有權利，並透過market銷售，讓使用者安裝我們的軟體到不同的Android裝置。 但是，在線上軟體商店賣軟體也是辛苦的工作。一些應用軟體開發商，從線上軟體商店賺到的錢是相當微薄的，對人數較多的公司而言，market的模式還無法支撐營運。看來，現階段定位為Android應用軟體開發商的公司，除了採取最容易的「設計服務」外，要以拷貝數為商業模式的基礎，確實要有一些非常的策略才行了。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      文／陳俊宏(Jollen Chen)
Contact: jollen@jollen.org
（原文刊載於零組件雜誌2009年8月份）

軟體委外設計服務 - 百年老店、全新感受

委外服務（outsourcing）在科技產業是一種普遍的商業模式，透過委外取得解決方案，以及後續服務是產品開發的一種做法，委外服務供應商透過「接案」的方式獲取利潤。特別是在軟體方面，有許多代表性的「軟體代工」廠，讓軟體代工成為委外服務的代表作。

隨著Android被大量關注以及採用，會有越來越多的「Android設計服務」公司出現，透過觀察，確實也有很多專門承接Android軟體專案的公司、小團隊或個人，這是不令人感到意外的現象。在討論Android設計服務前，不如先來思考一下近來當紅的線上軟體商店模式。

Android Market提供的商業模式是收取「安裝」費用，即使用者下載的拷貝(copy)數決定了軟體開發商的營收，雖然Android Market還沒有像App Store這樣成熟，但是「線上軟體商店」的模式幾乎已經被確立了，「應該要做market」的公司，也都宣佈他們的market方案了。這種賺取拷貝數的商業模式最簡單沒有負擔，可以說是比微型創業更小型的創業方式，唯一的考量的是流通在外的裝置(device)數量，因為裝置流通越多，軟體被下載的機會與次數越高。

再談到委外開發的模式，什麼樣的公司，會有「Android應用軟體委外設計」的需求？無疑是想要「bundle」特殊軟體在「產品」上的公司，希望有些軟體在機器出廠時就被安裝，在這樣的前提下，就有二個想法。第一，我們可以單純提供設計服務、交付成果，再由廠商預裝到裝置上，這時「安裝數量」與收費就沒有關係；第二，可以提供收取權利金的方式，安裝到裝置的數量，決定收費，等於收取拷貝數的費用。

對設計服務公司而言，採用以拷貝數為基礎的模式，是比較好的模式，但是這種模式能不能被廠商接受？衡量的依據之一是「解決問題」，或是「提供價值」。一項只能解決問題（技術難題）的服務，大體上只能以服務收費為主；而一個能提高產品價值的軟體，就能收取拷貝數的錢。在這裡所討論的是Android的設計服務，在其他領域，銷售「關鍵技術」是一個很好的商業模式。

Android應用軟體設計商，還要具備的一個思惟是，Android應用軟體是可以被安裝到「任何」的Android裝置上的；因此，為單一廠商或單一產品設計軟體，收取服務費用，還不如自已擁有(own)該軟體的所有權利，並透過market銷售，讓使用者安裝我們的軟體到不同的Android裝置。

但是，在線上軟體商店賣軟體也是辛苦的工作。一些應用軟體開發商，從線上軟體商店賺到的錢是相當微薄的，對人數較多的公司而言，market的模式還無法支撐營運。看來，現階段定位為Android應用軟體開發商的公司，除了採取最容易的「設計服務」外，要以拷貝數為商業模式的基礎，確實要有一些非常的策略才行了。
      
   </content>
</entry>
<entry>
   <title>CTimes 矽導論壇：四個步驟、建立你的Android競爭力</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/08/android-product-4-steps.html" />
   <id>tag:www.jollen.org,2009:/blog//2.660</id>
   
   <published>2009-08-05T09:33:38Z</published>
   <updated>2009-08-05T07:17:04Z</updated>
   
   <summary>文／陳俊宏(Jollen Chen) Contact: jollen@jollen.org （原文刊載於零組件雜誌2009年7月份） 創建自有版本 打開你的競爭力 過去品牌商面臨的一個問題是沒有自已的軟體。所謂的「自已的軟體」並不是拿別人的軟體來使用，或是視取得的開放源碼軟體為自有軟體。Android是一個作業系統，微軟的Windows Mobile也是一個作業系統，他們二者的「本質」上有什麼不同？Windows Mobile是由微軟所「擁有」的軟體，無法「自由」取得；而Android是開放源碼的軟體，每個人都可以透過網路自由取得，但是你擁有它嗎？ 取得不代表擁有。建立自已的版本，能控制並掌握整個框架的開發，才叫做擁有。擁有了自已的Android軟體，你就能修改它，並做出任何你想要的版本，取得(get)與擁有(own)意義上有很大的不同。過去Linux以及開放源碼給人的迷思是，由於軟體能自由取得，並做修改，因此不需要付費購買微軟的產品。下載Linux核心與開源軟體，故事才正要開始，首先要面臨到的便是工程的部份。沒有自有的Linux技術團隊，只要假以他手，將專案外包，而工程化後的Linux系統，自已仍無法掌握，照著自已的意思儘情地修改。 如何擁有自已的軟體，以下是個人建議，請您指教。擁有自有Android軟體的第一個步驟是：建立Android進化版本、即自已的分支。將Android框架的原始(original)原始碼(source code)建立一個新分支，也就是自已名字的版本。Google所提供的Android作業系統是「原生版本」，而自有的分支則是「進化版本」。例如：調整Android框架的實作，以加入自有的特性(features)，讓自有的進化版與原生版有所差異。試想，當我的Android進化版可以提供更炫麗的操作介面(UI)時，使用原生版本的產品便失去了市場性。最佳典範就是 HTC Sense。HTC Sense是HTC手機的專用UI，針對Android手機，HTC Sense能提供更棒的使用性(usability)。 第二、建立商標。Android作業系統採用Apache授權(Linux kernel除外)，而不是較為普及的GPL授權，所以Android作業系統對於商標(trademark)的建立是相當有助益的。商標是企業的一項價值，商標代表「這是我的東西」。當有差異性的Android版本能關閉原始碼，並建立註冊商標時，代表的是一個重要的里程碑：「這是屬於我的Android版本」。最佳典範，一樣是HTC Sense(tm)。 第三、適度貢獻與關閉原始碼。Android作業系統是開放平臺，開放平臺技術開發講求貢獻。OHA聯盟也是如此。廠商要能持續對OHA聯盟有所貢獻，而提交Android框架的程式碼是一個做法。OHA聯盟發給會員的門票並非終身有效，因為仍有被趕出大門的例子。另外，基於自有版本提供一套SDK是非常不錯的做法，例如OMS SDK就是一個典範。 第四、建立應用程式。基於市場與產品建立應用程式，以搭配產品，這是Android作業系統帶來的絕佳機會。是否自創品牌，當然也是一個考量，端看應用程式的價值以及特殊性。進化版Android目前來看，可以有二個發展題目。第一是結合服務的客製化版本，例如：OMS針對China Mobile服務做大量的客製化。第二個是針對UI與使用性做客製化版本，例如上述的HTC Sense。 廠商欲採用Android作業系統，並開發產品，但若不思考如何建立自有的能力，以及創造自有的Android進化版本，是非常可惜的一件事情。最大的盲點在於「外包能解決所有問題」的思維；反之，專案外包(out sourcing)不會是Android能帶來的商業價值，解決方案(solution)才是。針對個人開發者的部份，Android作業系統給開發者(developers)最好的舞臺是Android Marketing，因為越多的拷貝數量(即下載數)代表軟體越有價值。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      文／陳俊宏(Jollen Chen)
Contact: jollen@jollen.org
（原文刊載於零組件雜誌2009年7月份）

創建自有版本 打開你的競爭力

過去品牌商面臨的一個問題是沒有自已的軟體。所謂的「自已的軟體」並不是拿別人的軟體來使用，或是視取得的開放源碼軟體為自有軟體。Android是一個作業系統，微軟的Windows Mobile也是一個作業系統，他們二者的「本質」上有什麼不同？Windows Mobile是由微軟所「擁有」的軟體，無法「自由」取得；而Android是開放源碼的軟體，每個人都可以透過網路自由取得，但是你擁有它嗎？

取得不代表擁有。建立自已的版本，能控制並掌握整個框架的開發，才叫做擁有。擁有了自已的Android軟體，你就能修改它，並做出任何你想要的版本，取得(get)與擁有(own)意義上有很大的不同。過去Linux以及開放源碼給人的迷思是，由於軟體能自由取得，並做修改，因此不需要付費購買微軟的產品。下載Linux核心與開源軟體，故事才正要開始，首先要面臨到的便是工程的部份。沒有自有的Linux技術團隊，只要假以他手，將專案外包，而工程化後的Linux系統，自已仍無法掌握，照著自已的意思儘情地修改。

如何擁有自已的軟體，以下是個人建議，請您指教。擁有自有Android軟體的第一個步驟是：建立Android進化版本、即自已的分支。將Android框架的原始(original)原始碼(source code)建立一個新分支，也就是自已名字的版本。Google所提供的Android作業系統是「原生版本」，而自有的分支則是「進化版本」。例如：調整Android框架的實作，以加入自有的特性(features)，讓自有的進化版與原生版有所差異。試想，當我的Android進化版可以提供更炫麗的操作介面(UI)時，使用原生版本的產品便失去了市場性。最佳典範就是 HTC Sense。HTC Sense是HTC手機的專用UI，針對Android手機，HTC Sense能提供更棒的使用性(usability)。

第二、建立商標。Android作業系統採用Apache授權(Linux kernel除外)，而不是較為普及的GPL授權，所以Android作業系統對於商標(trademark)的建立是相當有助益的。商標是企業的一項價值，商標代表「這是我的東西」。當有差異性的Android版本能關閉原始碼，並建立註冊商標時，代表的是一個重要的里程碑：「這是屬於我的Android版本」。最佳典範，一樣是HTC Sense(tm)。

第三、適度貢獻與關閉原始碼。Android作業系統是開放平臺，開放平臺技術開發講求貢獻。OHA聯盟也是如此。廠商要能持續對OHA聯盟有所貢獻，而提交Android框架的程式碼是一個做法。OHA聯盟發給會員的門票並非終身有效，因為仍有被趕出大門的例子。另外，基於自有版本提供一套SDK是非常不錯的做法，例如OMS SDK就是一個典範。

第四、建立應用程式。基於市場與產品建立應用程式，以搭配產品，這是Android作業系統帶來的絕佳機會。是否自創品牌，當然也是一個考量，端看應用程式的價值以及特殊性。進化版Android目前來看，可以有二個發展題目。第一是結合服務的客製化版本，例如：OMS針對China Mobile服務做大量的客製化。第二個是針對UI與使用性做客製化版本，例如上述的HTC Sense。

廠商欲採用Android作業系統，並開發產品，但若不思考如何建立自有的能力，以及創造自有的Android進化版本，是非常可惜的一件事情。最大的盲點在於「外包能解決所有問題」的思維；反之，專案外包(out sourcing)不會是Android能帶來的商業價值，解決方案(solution)才是。針對個人開發者的部份，Android作業系統給開發者(developers)最好的舞臺是Android Marketing，因為越多的拷貝數量(即下載數)代表軟體越有價值。
      
   </content>
</entry>
<entry>
   <title>CTimes 矽導論壇：Android產品開發的關鍵五力</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/08/android-product-5-power.html" />
   <id>tag:www.jollen.org,2009:/blog//2.659</id>
   
   <published>2009-08-05T09:28:49Z</published>
   <updated>2009-08-07T00:25:06Z</updated>
   
   <summary>文／陳俊宏 jollen@jollen.org （原文刊載於零組件雜誌2009年6月份） 開放平臺讓我們看見了新機會 關鍵能力培植才能掌握機會 Android手機產品開發的重要能力培植，是搭上Android商機列車的入場卷。在Android手機產品開發，以及技術養成方面，有哪些重要的關鍵能力呢？以下針對這段時間所做的觀察，以及個人的心得，提出五個重要的指標能力，請您不吝指教。 關鍵力一：界面設計。過去談智慧型手機時，大家都了很多的力道在UI設計上，主要的原因除了智慧型手機都是觸控式螢幕的規格外，也受到iPhone很大的影響。Android的「制式界面」比較沒有獨特之處，因此「客製界面」將成為Android手機以及其他Android產品的重要特色。採用OMS系統(Open Mobile System)的oPhone手機，就在UI設計上下了很大的功夫。 關鍵力二：工業設計。手機工業設計(ID)包含手機的體積以及外觀，由於「手機」的特點是「經常攜帶」、「高移動性」以及「時尚配件」，所以手機是否夠輕薄、易攜帶，會是消費者重要的考量點。此外，有些手機代表的是一種時尚配件，或是身份地位的象徵，因此在工業設計的能力也影響到手機的銷售。對Android手機來講，工業設計不但重要，甚致還要更高一層來搭配有特色的UI設計。 關鍵力三：底層技術能力。研究Android作業系統底層技術的目的之一為「培養Android移植技術的能力」。任何Android應用程式都需要底層的支援，才能順利運作在硬體平臺上，而這也正是Android產品開發的核心能力；Android產品開發階段，不但一個高品質的硬體，也需要將Android作業系統移植到該硬體上並進行調校，才能讓Android應用程式在產品上順利執行。 關鍵力四：軟硬整合。上述的「移植能力」並不等於「軟硬整合」的能力。移植的目的是為了讓Android作業系統能在目標裝置上順利執行，並且驅動程式部份也能正常運作。軟硬整合的工作則是希望透過驅動程式的支援，讓Android Framework能發揮硬體的特色，因此如何擴充framework並實作自已的Activity與Service，以及修改framework，將是技術面的關鍵。 關鍵力五：行銷溝通力。手機產業本身就是一個特殊的產業，除了通路行銷(channel marketing)以及電信通路(carrier)的做法外，直銷(direct sale)也會是Android新興品牌手機的一大機會。Android是人人可取得的開放手機作業系統，新的產品概念，可幫助新興品牌進入利基市場，而採取直接銷售，例如透過網路，將是利基品牌手機很有影響力的一個做法。在產品行銷方面，如何與社群(community)以及終端用戶(end-user)溝通，並精確傳遞產品概念，以及經營品牌形象，就成為非常重要的關鍵能力。 與技術面有關的關鍵力三，以及關鍵力四，說明了Android作業系統與過去的Linux手機平臺的不同之處。Android是一個很健全(strong）的Application Framework，framework的擴充與開發技術是重要的技術。以大方向來看，加入新的 library 時需要擴充 application framework。 Android framework 的實作，部份需要考量硬體的規格，例如: Surface Manager 需要考量是否有 GPU 或硬體加速。但 Android application 建立一個 Surface holder時，若是將 Surface 的類型設定為 SURFACE_TYPE_HARDWARE，就必須針對硬體加速與 DMA 做移植工作。這個例子舉Android基本技術能力的重要性。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      文／陳俊宏
jollen@jollen.org
（原文刊載於零組件雜誌2009年6月份）

開放平臺讓我們看見了新機會 關鍵能力培植才能掌握機會

Android手機產品開發的重要能力培植，是搭上Android商機列車的入場卷。在Android手機產品開發，以及技術養成方面，有哪些重要的關鍵能力呢？以下針對這段時間所做的觀察，以及個人的心得，提出五個重要的指標能力，請您不吝指教。

關鍵力一：界面設計。過去談智慧型手機時，大家都了很多的力道在UI設計上，主要的原因除了智慧型手機都是觸控式螢幕的規格外，也受到iPhone很大的影響。Android的「制式界面」比較沒有獨特之處，因此「客製界面」將成為Android手機以及其他Android產品的重要特色。採用OMS系統(Open Mobile System)的oPhone手機，就在UI設計上下了很大的功夫。

關鍵力二：工業設計。手機工業設計(ID)包含手機的體積以及外觀，由於「手機」的特點是「經常攜帶」、「高移動性」以及「時尚配件」，所以手機是否夠輕薄、易攜帶，會是消費者重要的考量點。此外，有些手機代表的是一種時尚配件，或是身份地位的象徵，因此在工業設計的能力也影響到手機的銷售。對Android手機來講，工業設計不但重要，甚致還要更高一層來搭配有特色的UI設計。

關鍵力三：底層技術能力。研究Android作業系統底層技術的目的之一為「培養Android移植技術的能力」。任何Android應用程式都需要底層的支援，才能順利運作在硬體平臺上，而這也正是Android產品開發的核心能力；Android產品開發階段，不但一個高品質的硬體，也需要將Android作業系統移植到該硬體上並進行調校，才能讓Android應用程式在產品上順利執行。

關鍵力四：軟硬整合。上述的「移植能力」並不等於「軟硬整合」的能力。移植的目的是為了讓Android作業系統能在目標裝置上順利執行，並且驅動程式部份也能正常運作。軟硬整合的工作則是希望透過驅動程式的支援，讓Android Framework能發揮硬體的特色，因此如何擴充framework並實作自已的Activity與Service，以及修改framework，將是技術面的關鍵。

關鍵力五：行銷溝通力。手機產業本身就是一個特殊的產業，除了通路行銷(channel marketing)以及電信通路(carrier)的做法外，直銷(direct sale)也會是Android新興品牌手機的一大機會。Android是人人可取得的開放手機作業系統，新的產品概念，可幫助新興品牌進入利基市場，而採取直接銷售，例如透過網路，將是利基品牌手機很有影響力的一個做法。在產品行銷方面，如何與社群(community)以及終端用戶(end-user)溝通，並精確傳遞產品概念，以及經營品牌形象，就成為非常重要的關鍵能力。

與技術面有關的關鍵力三，以及關鍵力四，說明了Android作業系統與過去的Linux手機平臺的不同之處。Android是一個很健全(strong）的Application Framework，framework的擴充與開發技術是重要的技術。以大方向來看，加入新的 library 時需要擴充 application framework。

Android framework 的實作，部份需要考量硬體的規格，例如: Surface Manager 需要考量是否有 GPU 或硬體加速。但 Android application 建立一個 Surface holder時，若是將 Surface 的類型設定為 SURFACE_TYPE_HARDWARE，就必須針對硬體加速與 DMA 做移植工作。這個例子舉Android基本技術能力的重要性。

界面設計(UI)、工業設計(ID)、底層技術(Internals)、軟硬整合(Integration)與行銷溝通力(Communications)，共五個關鍵能力。UI與ID是比較抽象的能力，需要天生好手或是有經驗的設計師來協助；底層技術與軟硬整合，是比較具體的能力，可以採用培訓來初步形成，並透過實務經驗來加強，或是採取伙夥合作(partnership)的方式來補足；最後的行銷溝通力，則是一半抽象一半具體，具體的部份是行銷方面有一些標準方法與工具，抽象部份是如何有創意的利用這些標準方法與工具，來傳達正確的產品訊息給消費者。
      
   </content>
</entry>
<entry>
   <title>Android的Launcher研究：客製化桌面UI</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/07/android-os-launcher-app.html" />
   <id>tag:www.jollen.org,2009:/blog//2.656</id>
   
   <published>2009-07-16T19:13:34Z</published>
   <updated>2009-08-05T07:00:52Z</updated>
   
   <summary>前言 能取得Android OS原始碼，並修改裡頭的內容，有時候也頗有樂趣。最近和幾位朋友聊到「Android框架的改造」，以及如何吸引對Android框架技術有興趣的同好一起交流的議題；我個人認為，一開始如果能丟出一個比較有樂趣的議題，或許可以有拋磚引玉的效果。 上週在北京進行Android培訓課程時，與eoeAndroid社群也進行了想法的交流，由於大家都體認到Android底層技術的重要性及其價值，而且eoeAndroid社群裡也有許多技術好手，所以就和eoeAndroid的創辦人靳岩兄有了一個共同主持研究Android底層技術「同好小組」的想法，希望能透過社群的方式，集合大家的智慧，一起把底層技術研究清楚。 因為要讓大家能有焦點，所以「發題」很重要，這個工作就由落在我身上了。由於第一次希望題目能簡單，並且有趣一點，至少要能達到發球的效果，吸引大家開始關心Android底層技術，所以原則是：希望能用最簡單的方式、讓大家體驗修改底層的樂趣。 題目說明: Launcher 第一次的題目是「Launcher」的修改。 Launcher就是Android的應用程式啟動器，Launcher的功能還包含：桌面的切換、應用程式快捷(shortcut)功能、背景圖(Wallpaper)功能等等。因此，修改Launcher可以改變一些很深層的UI功能。 在Android的桌面最下方，有一個圖示，按下後可以拉出應用程式圖示清單，這是Launcher提供的功能。這一次，因為我們覺得這個Launcher的圖示太製式化了，越看越不好看，所以想要修改一下，換張圖，要怎麼做到呢？ 範例展示 例如，圖1是原始的圖示；圖2是修改後的圖示。 圖1: 原始圖示 圖2: 幫Launcher妝扮一下 實作說明 1/4: 取得Android原始碼與EeePC移植 這個功能並不難做，事實上，完全不用寫程式。只要把圖檔重做就可以了。只不過前提是，要知道： 1. 如何取得Android OS原始程式碼 2. 如何編譯Android OS 最簡單的做法是： 1. 下載Android原始碼後、取得EeePC的移植(product) 2. 編譯「TARGET_PRODUCT」為eee_701 3. 由於Launcher都是用Java語法寫成的，所以不會有架構(ARM/x86/...)的問題，編譯後可以取得Launcher.apk；APK套件是不分處理器平臺的 先學會如何由Android原始碼編譯出eee_701的image，才有辦法繼續進行。 實作說明 2/4: 修改圖檔 在Android原始碼的 packages/apps/ 目錄裡，存放了Android內建的應用程式原始碼，Launcher是Android的一個應用程式，所以從這裡找到它的原始碼，並進行修改工程。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<strong>前言</strong>

能取得Android OS原始碼，並修改裡頭的內容，有時候也頗有樂趣。最近和幾位朋友聊到「Android框架的改造」，以及如何吸引對Android框架技術有興趣的同好一起交流的議題；我個人認為，一開始如果能丟出一個比較有樂趣的議題，或許可以有拋磚引玉的效果。

上週在北京進行Android培訓課程時，與eoeAndroid社群也進行了想法的交流，由於大家都體認到Android底層技術的重要性及其價值，而且eoeAndroid社群裡也有許多技術好手，所以就和eoeAndroid的創辦人靳岩兄有了一個共同主持研究Android底層技術「同好小組」的想法，希望能透過社群的方式，集合大家的智慧，一起把底層技術研究清楚。

因為要讓大家能有焦點，所以「發題」很重要，這個工作就由落在我身上了。由於第一次希望題目能簡單，並且有趣一點，至少要能達到發球的效果，吸引大家開始關心Android底層技術，所以原則是：希望能用最簡單的方式、讓大家體驗修改底層的樂趣。

<strong>題目說明: Launcher</strong>

第一次的題目是「Launcher」的修改。

Launcher就是Android的應用程式啟動器，Launcher的功能還包含：桌面的切換、應用程式快捷(shortcut)功能、背景圖(Wallpaper)功能等等。因此，修改Launcher可以改變一些很深層的UI功能。

在Android的桌面最下方，有一個圖示，按下後可以拉出應用程式圖示清單，這是Launcher提供的功能。這一次，因為我們覺得這個Launcher的圖示太製式化了，越看越不好看，所以想要修改一下，換張圖，要怎麼做到呢？

<strong>範例展示</strong>

例如，圖1是原始的圖示；圖2是修改後的圖示。

<img alt="launcher-1.png" src="http://www.jollen.org/blog/2009/07/17/launcher-1.png" width="320" height="480" />
圖1: 原始圖示

<img alt="launcher-2.png" src="http://www.jollen.org/blog/2009/07/17/launcher-2.png" width="320" height="480" />
圖2: 幫Launcher妝扮一下

<strong>實作說明 1/4: 取得Android原始碼與EeePC移植</strong>

這個功能並不難做，事實上，完全不用寫程式。只要把圖檔重做就可以了。只不過前提是，要知道：

1. 如何取得Android OS原始程式碼
2. 如何編譯Android OS

最簡單的做法是：

1. 下載Android原始碼後、取得EeePC的移植(product)
2. 編譯「TARGET_PRODUCT」為eee_701
3. 由於Launcher都是用Java語法寫成的，所以不會有架構(ARM/x86/...)的問題，編譯後可以取得Launcher.apk；APK套件是不分處理器平臺的

先學會如何由Android原始碼編譯出eee_701的image，才有辦法繼續進行。

<strong>實作說明 2/4: 修改圖檔</strong>

在Android原始碼的 packages/apps/ 目錄裡，存放了Android內建的應用程式原始碼，Launcher是Android的一個應用程式，所以從這裡找到它的原始碼，並進行修改工程。

切換到以下目錄：

&lt;android source&gt;/packages/apps/Launcher/

接著要修改src/目錄下的內容，還是res/目錄下的內容呢？圖檔屬於Android的「resource」，因此當然是到res/目錄下找到我們要的圖檔。

切換到以下目錄：

&lt;android source&gt;/packages/apps/Launcher/res/

又看到了一大堆目錄，圖檔的部份存放於：

<ul><li>drawable-land/ - landscope 模式的圖檔</li>
<li>drawable-port/ - portrait 模式的圖檔</li></ul>

我們先改一下portrait模式的圖檔。找到drawable-port/tray_handle_normal.png檔案如下：

<img alt="tray_handle_normal-1.png" src="http://www.jollen.org/blog/2009/07/17/tray_handle_normal-1.png" width="320" height="56" />

就是它了，換掉，把圖檔換成這個：

<img alt="tray_handle_normal-2.png" src="http://www.jollen.org/blog/2009/07/17/tray_handle_normal-2.png" width="320" height="56" />

換好後重編Android即可。一行程式都不用改。

<strong>實作說明 3/4: 安裝Launcher.apk</strong>

重編Android原始碼，接著可以在out/target/product/&lt;product name&gt;/system/app/找到Launcher.apk套件。把Launcher.apk安裝到AVD(Android 模擬器)裡做測試，方法如下：

1. 先啟動一個AVD
2. 執行adb將Launcher.apk手動安裝到AVD裡，指令如下：

$ adb install -r &lt;your-path&gt;/Launcher.apk 

成功後可看到以下畫面：

<pre>338 KB/s (837376 bytes in 2.417s)
        pkg: /data/local/tmp/Launcher.apk
Success</pre>

<strong>實作說明 4/4: 重開機</strong>

已經完成了，直接重開即可。「重開」是把AVD重新啟動，不是把電腦重新開機 ;-)

<strong>應用與討論</strong>

歡迎大家上傳你的作品、或是貼圖與大家分享，方式是透過eoeAndroid社群的討論區：

<a href="http://www.eoeandroid.com/forumdisplay.php?fid=54">http://www.eoeandroid.com/forumdisplay.php?fid=54</a>

如果有更詳細的Launcher研究心得，或是希望能針對Launcher進行討論，歡迎至eoeAndroid的討論區發文。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#26: 強大的Intent機制</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/07/jollen-android-programming-26.html" />
   <id>tag:www.jollen.org,2009:/blog//2.654</id>
   
   <published>2009-07-16T04:27:36Z</published>
   <updated>2009-08-07T00:21:44Z</updated>
   
   <summary>什麼是Intent(意圖)？ 強大的事件處理「Intent」(意圖)是Android很強大的一種機制。 在 Android 應用程式框架中，有一個非常聰明的事件處理機制，稱之為「Intent」。Intent（意圖）的作用與事件(event)很像，但與傳統的事件處理仍然有些差異。傳統的事件處理，講求的是「處理者（handler）的觸發」，當一事件發生時，便callback讓事件的處理者，或是直接將該事件轉送（forward）給應用程式，由應用程式決定處理方式。 在「Intent」這樣的事件處理觀念裡，Android 試圖將事件解釋為「應用程式的意圖」或是「使用者的意圖」，並試著去解釋該意圖的目的，若 Android 系統本身能理解應用程式的意圖，便會「自行」去處理該意圖所應執行的工作。 Android的做法是，讓每個意圖（Intent）都帶有一個動作（action），並根據不同的動作去行動。 關於前述教學提到的Intent 在前面的教學裡，我們用到二次Intent如下： 1. 自行定義一個Intent、設定Service可接收此Intent，並透過「送出Intent給框架」的方式，請框架啟動該Service 2. 使用Android內部定義的動作「ACTION_VIEW」，來「檢視」(view)一個「URL」資料，當框架看到內部定義的ACTION_VIEW動作時，便「自行」處理該Intent；處理的方式是啟動WebView並連上網站 以前述的教學為例，使用內建的動作“ACTION_VIEW”就可以很容易做出一個「啟動瀏覽器(WebView類別)上網」的應用程式。 透過這二個例子我們知道，Intent的動作可以是自行定義與框架內部定義二種。Android框架的Intent有很多方便實用的「內建動作」，以下我們說明Android內建Intent的美麗之處。 Android內建的Intent Action Android的框架確實是讓每個Intent都包含了一個動作，就稱為action。 為了讓大家更容易了解Intent的基本觀念，我們採用「體驗」的方式來說明如何使用內建的Action。現在，我們列舉以下三個情境，並分別實作其範例： HelloIntentDialer: 啟動撥號器(dialer)並撥號 HelloIntentMusic: 使用者按下「Select Music」後，可以由音樂清單裡選擇音樂並撥放 HelloIntentWallpaper: 啟動Android內建的「背景圖選擇器」，讓使用者更換背景 第二個範例”HelloIntentMusic”其實是ApiDemo裡的範例，而且是很容易能了解Intent內涵的好程式。 除了action外，Intent還可以包含另外一項資訊「data」。 Intent的action指定這個Intent的「動作」是什麼，框架會依指定的動作進行處理；有些action可以附帶一筆資料，這個資料是以Uri的格式撰寫，在HelloIntentDialer的範例會再做說明。 內建的Intent有哪些呢？請參考Android Reference Guide中的Intent類別說明。上述三個範例分別使用以下三個action： 1. ACTION_CALL: 撥號 2. ACTION_GET_CONTENT:...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<strong>什麼是Intent(意圖)？</strong>

強大的事件處理「Intent」(意圖)是Android很強大的一種機制。

在 Android 應用程式框架中，有一個非常聰明的事件處理機制，稱之為「Intent」。Intent（意圖）的作用與事件(event)很像，但與傳統的事件處理仍然有些差異。傳統的事件處理，講求的是「處理者（handler）的觸發」，當一事件發生時，便callback讓事件的處理者，或是直接將該事件轉送（forward）給應用程式，由應用程式決定處理方式。

在「Intent」這樣的事件處理觀念裡，Android 試圖將事件解釋為「應用程式的意圖」或是「使用者的意圖」，並試著去解釋該意圖的目的，若 Android 系統本身能理解應用程式的意圖，便會「自行」去處理該意圖所應執行的工作。

Android的做法是，讓每個意圖（Intent）都帶有一個動作（action），並根據不同的動作去行動。

<strong>關於前述教學提到的Intent</strong>

在前面的教學裡，我們用到二次Intent如下：

1. 自行定義一個Intent、設定Service可接收此Intent，並透過「送出Intent給框架」的方式，請框架啟動該Service

2. 使用Android內部定義的動作「ACTION_VIEW」，來「檢視」(view)一個「URL」資料，當框架看到內部定義的ACTION_VIEW動作時，便「自行」處理該Intent；處理的方式是啟動WebView並連上網站

以前述的教學為例，使用內建的動作“ACTION_VIEW”就可以很容易做出一個「啟動瀏覽器(WebView類別)上網」的應用程式。

透過這二個例子我們知道，Intent的動作可以是自行定義與框架內部定義二種。Android框架的Intent有很多方便實用的「內建動作」，以下我們說明Android內建Intent的美麗之處。

<strong>Android內建的Intent Action</strong>

Android的框架確實是讓每個Intent都包含了一個動作，就稱為action。

為了讓大家更容易了解Intent的基本觀念，我們採用「體驗」的方式來說明如何使用內建的Action。現在，我們列舉以下三個情境，並分別實作其範例：

HelloIntentDialer: 啟動撥號器(dialer)並撥號
HelloIntentMusic: 使用者按下「Select Music」後，可以由音樂清單裡選擇音樂並撥放
HelloIntentWallpaper: 啟動Android內建的「背景圖選擇器」，讓使用者更換背景

第二個範例”HelloIntentMusic”其實是ApiDemo裡的範例，而且是很容易能了解Intent內涵的好程式。

除了action外，Intent還可以包含另外一項資訊「data」。

Intent的action指定這個Intent的「動作」是什麼，框架會依指定的動作進行處理；有些action可以附帶一筆資料，這個資料是以Uri的格式撰寫，在HelloIntentDialer的範例會再做說明。

內建的Intent有哪些呢？請參考Android Reference Guide中的Intent類別說明。上述三個範例分別使用以下三個action：

1. ACTION_CALL: 撥號
2. ACTION_GET_CONTENT: 啟動內容選取器
3. ACTION_SET_WALLPAPER: 設定Wallpaper

在進行範例講解前，可以先行閱讀Intent類別的說明。ACTION_CALL是一個內建的action，我們只要產生一個Intent物件，並定義其「action」為ACTION_CALL即可通知框架「打電話」。

Android內建的action是相當實用的應用開發機制，同時也是Android OS最具代表性的機制之一。Android內建的Intent action分為二種：

1. Activity Action: 啟動Activity的action
2. Broadcast Action: 透過廣撥器處理的action

第一種action是activity action，用途是通知框架啟動Activity，這裡提出的三個範例，都是使用activity action。Broadcast action將在Broadcast的教學裡再做說明。

* Update: 2009/08/07]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#25: HelloAppWidgetProvider.java 程式碼說明</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/07/jollen-android-programming-25.html" />
   <id>tag:www.jollen.org,2009:/blog//2.652</id>
   
   <published>2009-07-12T06:10:25Z</published>
   <updated>2009-08-05T07:00:52Z</updated>
   
   <summary>HelloAppWidgetProvider.java 程式碼說明 圖1: HelloAppWidgetProvider的設計 圖1是目前我們的HelloAppWidget範例設計，說明如下： onUpdate(): 收到ACTION_APPWIDGET_UPDATE廣撥時，框架會callback此method onDelete(): 收到ACTION_APPWIDGET_DELETE廣撥時，框架會callback此method AppWidgetManager: 管理App Widget的類別 先前，在AndroidManifest.xml裡我們讓HelloAppWidgetProider類別可以接收ACTION_APPWIDGET_UPDATE廣撥事件；ACTION_APPWIDGET_UPDATE是最主要的App Widget事件，當AppWidgetProvider被要求為App Widget提供”RemoteView”時，就會收到這個事件。 什麼是RemoteViews？ 什麼是RemoteView呢？先看一下框架的設計，如圖2。 簡單來說，「RemoteViews」就是表示UI的類別。res/layout/main.xml描述了應用程式的UI，UI裡當然包含許多組件(Widget)，而在先前的教學裡講到了一個觀念「Android應用程式的UI就是一個View tree」，view tree就是「View Hierarchy」。 總結來說，RemotViews是一個用來表示View Hierarchy的類別。透過RemoteViews可以找到UI裡的每一個組件。 圖2: RemoteView的設計（點擊看全圖） 程式說明: HelloAppWidgetProvider.java onUpdate()的程式實作： public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { final int N...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<strong>HelloAppWidgetProvider.java 程式碼說明</strong>

<img alt="HelloAppWidgetProvider.png" src="http://www.jollen.org/blog/2009/07/12/HelloAppWidgetProvider.png" width="638" height="333" />
圖1: HelloAppWidgetProvider的設計

圖1是目前我們的HelloAppWidget範例設計，說明如下：

<ul><li>onUpdate(): 收到ACTION_APPWIDGET_UPDATE廣撥時，框架會callback此method</li>
<li>onDelete(): 收到ACTION_APPWIDGET_DELETE廣撥時，框架會callback此method</li>
<li>AppWidgetManager: 管理App Widget的類別</li></ul>

先前，在AndroidManifest.xml裡我們讓HelloAppWidgetProider類別可以接收ACTION_APPWIDGET_UPDATE廣撥事件；ACTION_APPWIDGET_UPDATE是最主要的App Widget事件，當AppWidgetProvider被要求為App Widget提供”RemoteView”時，就會收到這個事件。

<strong>什麼是RemoteViews？</strong>

什麼是RemoteView呢？先看一下框架的設計，如圖2。

簡單來說，「RemoteViews」就是表示UI的類別。res/layout/main.xml描述了應用程式的UI，UI裡當然包含許多組件(Widget)，而在先前的教學裡講到了一個觀念「Android應用程式的UI就是一個View tree」，view tree就是「View Hierarchy」。

總結來說，RemotViews是一個用來表示View Hierarchy的類別。透過RemoteViews可以找到UI裡的每一個組件。

<a href="http://www.jollen.org/blog/2009/07/12/RemoteViews.png"><img alt="RemoteViews.png" src="http://www.jollen.org/blog/2009/07/12/RemoteViews.png" width="933" height="1021" border="0" /></a>
圖2: RemoteView的設計（點擊看全圖）

<strong>程式說明: HelloAppWidgetProvider.java</strong>

onUpdate()的程式實作：

<blockquote><pre>    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        final int N = appWidgetIds.length;
        for (int i=0; i&lt;N; i++) {
            int appWidgetId = appWidgetIds[i];
            updateAppWidget(context, appWidgetManager, appWidgetId);
        }
    }</pre></blockquote>

說明如下：

1. onUpdate()負責更新「已經安裝」在桌面上的App Widget內容，因此我們實作一個updateAppWidget()來進行真正更新的工作

2. onUpdate()的第二個參數為AppWidgetManager，這是一個「管理AppWidgetProvider」的類別，我們必須透過框架callback本方法時回傳給我們的AppWidgetProvider物件，來更新桌面上的App Widget

3. onUpdate()的第三個參數appWidgetIds陣列，存放需要更新的App Widget ID；框架會將需要更新的App Widget之ID回傳給onUpdate()，程式必須負責「更新每一個需要更新的App Widget。」

更新App Widget的方式是透過AppWidgetManager來完成，程式實作：

<blockquote><pre>    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
    	CharSequence text;
    	      
    	text = "www.jollen.org";
    	        
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.main);
        views.setTextViewText(R.id.appwidget_text, text);
        
        appWidgetManager.updateAppWidget(appWidgetId, views);
    }
}</pre></blockquote>

說明如下：

1. 透過UI layout取得自已的「View Hierarchy」(UI)，以前面介紹的RemoteViews物件表示

2. 如圖2，呼叫RemoteView的setTextViewText()方法，修改UI裡的「R.id.appwidget_text」組件，變更文字內容

3. 呼叫AppWidgetProvider的updateAppWidget()方法，更新我們所指定的App Widget，將其UI更新為RemoteView的UI

4. updateAppWidget()的第二個參數為RemoteView，即說明1.取得的UI，說明2.修改了此UI裡的”R.id.appwidget_text”組件，最後透過App Widget Manager更新App Widget的UI]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#24: AndroidManifest.xml-加入App Widget的程式資訊</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/07/jollen-android-programming-24.html" />
   <id>tag:www.jollen.org,2009:/blog//2.651</id>
   
   <published>2009-07-11T15:57:29Z</published>
   <updated>2009-08-05T07:00:52Z</updated>
   
   <summary><![CDATA[AndroidManifest.xml-加入App Widget的程式資訊 AndroidManifest.xml檔案的用途在前面的教學裡介紹過了。以下是其完整內容： &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.moko.hellowidget" android:versionCode="1" android:versionName="1.0"&gt; &lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt; &lt;receiver android:name=".HelloAppWidgetProvider"&gt; &lt;meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget_provider" /&gt; &lt;intent-filter&gt; &lt;action android:name="android.appwidget.action.APPWIDGET_UPDATE" /&gt; &lt;/intent-filter&gt; &lt;/receiver&gt; &lt;/application&gt; &lt;uses-sdk android:minSdkVersion="3" /&gt; &lt;/manifest&gt; 說明如下： 1. 在&lt;application&gt;裡加入&lt;receiver&gt;標籤，指定android:name屬性為主要的provider類別，即”HelloAppWidgetProvider”，請注意，「.」表示後面的字串為一個「類別名稱」，不要忽略了這個重要的小數點 2. 在&lt;receiver&gt;裡加入&lt;meta-data>標籤，指定android:resource屬性為App Widget的資源檔名稱，以我們的範例來說，就是「@xml/appwidget_provider」，即「xml目錄下的appwidget_provider.xml檔案」 3. 在&lt;receiver&gt;裡加入&lt;intent-filter&gt;標籤，讓我們的App Widget可以接收APPWIDGET_UPDATE事件(event)...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<strong>AndroidManifest.xml-加入App Widget的程式資訊</strong>

AndroidManifest.xml檔案的用途在前面的教學裡介紹過了。以下是其完整內容：

<blockquote><pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.moko.hellowidget"
      android:versionCode="1"
      android:versionName="1.0"&gt;
    &lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt;
<strong>        &lt;receiver android:name=".HelloAppWidgetProvider"&gt;
            &lt;meta-data android:name="android.appwidget.provider"
                    android:resource="@xml/appwidget_provider" /&gt;
            &lt;intent-filter&gt;
                &lt;action android:name="android.appwidget.action.APPWIDGET_UPDATE" /&gt;
            &lt;/intent-filter&gt;
        &lt;/receiver&gt;</strong>
    &lt;/application&gt;
    &lt;uses-sdk android:minSdkVersion="3" /&gt;
&lt;/manifest&gt;</pre></blockquote>

說明如下：

1. 在&lt;application&gt;裡加入&lt;receiver&gt;標籤，指定android:name屬性為主要的provider類別，即”HelloAppWidgetProvider”，請注意，「.」表示後面的字串為一個「類別名稱」，不要忽略了這個重要的小數點

2. 在&lt;receiver&gt;裡加入&lt;meta-data>標籤，指定android:resource屬性為App Widget的資源檔名稱，以我們的範例來說，就是「@xml/appwidget_provider」，即「xml目錄下的appwidget_provider.xml檔案」

3. 在&lt;receiver&gt;裡加入&lt;intent-filter&gt;標籤，讓我們的App Widget可以接收APPWIDGET_UPDATE事件(event)

一個很簡單的App Widget完成了。接下來，就是針對HelloAppWidgetProvider.java程式碼做細部說明。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#23: HelloAppWidgetProvider.java-實作App Widget供應者</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/07/jollen-android-programming-23.html" />
   <id>tag:www.jollen.org,2009:/blog//2.650</id>
   
   <published>2009-07-11T15:54:34Z</published>
   <updated>2009-08-05T07:00:52Z</updated>
   
   <summary>HelloAppWidgetProvider.java-實作App Widget供應者 程式碼已經在前面的教學裡展示過了，當時只提到一個很基本的重點：使用AppWidgetProvider類別。在這裡，我們先說明設計的部份，才能了解程式如何實作。程式碼的說明稍後再做補充。 圖1：設計App Widget 從圖1的設計裡可以知道(配合查詢Android Reference文件)，當程式繼承了AppWidgetProvidr類別後，也繼承了二個主要的method： onUpdate() onDelete() App Widget使用AppWidgetProvider類別，即App Widget的「供應者」，供應什麼東西給誰呢？可以想像成是，我們的應用程式，供應App Widget給Android桌面。 到目前為止，我們知道只需要AppWidgetProvider即可實成一個很陽春的App Widget。而完整的App Widget應該包含三個單元(unit)： 1. Provider：此處說明的「供應者」 2. Configure：App Widget的設定單元，用途是提供一個「介面」供使用者輸入資料 3. Receiver：繼承自BroadcastReceiver的單元，即廣播接收器，用來接收Android框架所送出的事件(event) 在後續的教學裡，我們會繼續說明configure與receiver單元的觀念與實作。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<strong>HelloAppWidgetProvider.java-實作App Widget供應者</strong>

程式碼已經在前面的教學裡展示過了，當時只提到一個很基本的重點：使用AppWidgetProvider類別。在這裡，我們先說明設計的部份，才能了解程式如何實作。程式碼的說明稍後再做補充。

<img alt="AppWidgetProvider.png" src="http://www.jollen.org/blog/2009/07/11/AppWidgetProvider.png" width="798" height="822" />
圖1：設計App Widget

從圖1的設計裡可以知道(配合查詢Android Reference文件)，當程式繼承了AppWidgetProvidr類別後，也繼承了二個主要的method：

<ul><li>onUpdate()</li>
<li>onDelete()</li></ul>

App Widget使用AppWidgetProvider類別，即App Widget的「供應者」，供應什麼東西給誰呢？可以想像成是，我們的應用程式，供應App Widget給Android桌面。

到目前為止，我們知道只需要AppWidgetProvider即可實成一個很陽春的App Widget。而完整的App Widget應該包含三個單元(unit)：

1. Provider：此處說明的「供應者」
2. Configure：App Widget的設定單元，用途是提供一個「介面」供使用者輸入資料
3. Receiver：繼承自BroadcastReceiver的單元，即廣播接收器，用來接收Android框架所送出的事件(event)

在後續的教學裡，我們會繼續說明configure與receiver單元的觀念與實作。
]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#22: main.xml-描述App Widget的UI</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/07/jollen-android-programming-22.html" />
   <id>tag:www.jollen.org,2009:/blog//2.649</id>
   
   <published>2009-07-11T15:52:53Z</published>
   <updated>2009-08-05T07:00:52Z</updated>
   
   <summary><![CDATA[main.xml-描述App Widget的UI 這個檔案在前面的教學裡介紹過了，它的主要用途是描述UI。我們想要設計一個能嵌進桌面，並顯示文字的App Widget，因此必須使用Android的TextView類別。 以下是main.xml的完整內容： &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" &gt; &lt;TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/appwidget_text" android:textColor="#ff000000" /&gt; &lt;/LinearLayout&gt; 我們的App Widget使用LinearLayout來安排佈局，而UI為一個TextView物件。在這裡，我們將此TextView物件的id定義為”appwidget_text”。...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<strong>main.xml-描述App Widget的UI</strong>

這個檔案在前面的教學裡介紹過了，它的主要用途是描述UI。我們想要設計一個能嵌進桌面，並顯示文字的App Widget，因此必須使用Android的TextView類別。

以下是main.xml的完整內容：

<blockquote><pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    &gt;
&lt;TextView  
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/appwidget_text"
    android:textColor="#ff000000"
    /&gt;
&lt;/LinearLayout&gt;</pre></blockquote>

我們的App Widget使用LinearLayout來安排佈局，而UI為一個TextView物件。在這裡，我們將此TextView物件的id定義為”appwidget_text”。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#21: appwidget_provider.xml-描述App Widget屬性的資源檔</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/07/jollen-android-programming-21.html" />
   <id>tag:www.jollen.org,2009:/blog//2.648</id>
   
   <published>2009-07-11T15:46:12Z</published>
   <updated>2009-08-05T07:00:52Z</updated>
   
   <summary><![CDATA[以下分別說明HelloAppWidget的實作，以及技術重點。 appwidget_provider.xml-描述App Widget屬性的資源檔 這個檔案主要描述App Widget的幾個屬性： 長度(width) 高度(height) 更新頻率 UI layout檔 以下是appwidget_provider.xml的完整內容： &lt;?xml version="1.0" encoding="utf-8"?> &lt;appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="85dp" android:minHeight="30dp" android:updatePeriodMillis="3000" android:initialLayout="@layout/main" &gt; &lt;/appwidget-provider&gt; 說明如下： 1. &lt;appwidget-provider&gt;標籤定義App Widget的屬性 2. android:minWidth定義寬度 3. android:minHeight屬性定義長度 4. android:updatePeriodMillis定義App Widget的更新頻率，Android框架每隔這段時間，會callback AppWidgetProvider類別的onUpdate()事件；此屬性的時間單位為1/1000秒，以上述的定義來說，等於3秒鐘的時間(3000/1000=3) 5. android:initialLayout屬性指定此App Widget的UI layout定義檔，”@”符號在Android的XML定義檔案，代表「目錄」之意，因此”@layout/main”表示「layout目錄下的main.xml檔案」 以上共四項屬性，是App Widget最基本的屬性，必須良好定義。其中android:updatePeriodMillis屬性可省略，代表不更新App...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[以下分別說明HelloAppWidget的實作，以及技術重點。

<strong>appwidget_provider.xml-描述App Widget屬性的資源檔</strong>

這個檔案主要描述App Widget的幾個屬性：

<ul><li>長度(width)</li>
<li>高度(height)</li>
<li>更新頻率</li>
<li>UI layout檔</li></ul>

以下是appwidget_provider.xml的完整內容：

<blockquote><pre>&lt;?xml version="1.0" encoding="utf-8"?>
   
&lt;appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="85dp"
    android:minHeight="30dp"
    android:updatePeriodMillis="3000"
    android:initialLayout="@layout/main"
    &gt;
&lt;/appwidget-provider&gt;</pre></blockquote>

說明如下：

1. &lt;appwidget-provider&gt;標籤定義App Widget的屬性
2. android:minWidth定義寬度
3. android:minHeight屬性定義長度
4. android:updatePeriodMillis定義App Widget的更新頻率，Android框架每隔這段時間，會callback AppWidgetProvider類別的onUpdate()事件；此屬性的時間單位為1/1000秒，以上述的定義來說，等於3秒鐘的時間(3000/1000=3)
5. android:initialLayout屬性指定此App Widget的UI layout定義檔，”@”符號在Android的XML定義檔案，代表「目錄」之意，因此”@layout/main”表示「layout目錄下的main.xml檔案」

以上共四項屬性，是App Widget最基本的屬性，必須良好定義。其中android:updatePeriodMillis屬性可省略，代表不更新App Widget，即Android框架將不callback appWidgetProvider類別的onUpdate()事件。

onUpdate()事件負責更新App Widget的顯示內容。

設計App Widget的第一件工作，就是定義它的大小，以及更新頻率。由於手機的螢幕比較小，再加上桌面的空間有限，因此就要很小心定義App Widget的長度以及寬度。

在Android的Dev Guide文件裡，有一個App Widget設計原則的章節，描述了App Widget的標準大小；當然，這只是建議，我們可以任意定義App Widget的大小，因此不依照Google提供的設計原則也不會有什麼問題。但是，若是能遵循設計原則的指示，桌面的空間安排會較有效率，桌面的整體呈現也會比較美觀。

App Widget的設計需要考量螢幕的方向，若是直向顯示(portrait)，則App Widget的大小建議如下：

<a href="http://www.jollen.org/blog/2009/07/11/portrait_sizes.png"><img alt="portrait_sizes.png" src="http://www.jollen.org/blog/2009/07/11/portrait_sizes.png" width="939" height="566" border="0" /></a>
(圖片來源：Android Dev Guide；點擊看全圖)

橫向顯示(landscape)的設計建議如下：

<a href="http://www.jollen.org/blog/2009/07/11/landscape_sizes.png"><img alt="landscape_sizes.png" src="http://www.jollen.org/blog/2009/07/11/landscape_sizes.png" width="1003" height="484" border="0" /></a>
(圖片來源：Android Dev Guide；點擊看全圖)

在後面的教學裡，我們會再詳細說明App Widget的美工設計原則。

接下來要接著進行的工作，即是在”@layout/”裡建立main.xml檔案，以描述App Widget的UI。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#20: 如何設計一個小型的App Widget？</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/07/jollen-android-programming-20.html" />
   <id>tag:www.jollen.org,2009:/blog//2.647</id>
   
   <published>2009-07-10T10:00:56Z</published>
   <updated>2009-08-05T07:00:52Z</updated>
   
   <summary><![CDATA[Android的ApiDemo範例庫提供了一個很不錯的App Widget範例；不過，對初學者來說，這個範例可能稍嫌繁瑣。在這裡另外提供一個HelloAppWidget範例如下： /* 範例：HelloAppWidget.java */ package com.moko.hellowidget; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.widget.RemoteViews; public class HelloAppWidgetProvider extends AppWidgetProvider { public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { final int N = appWidgetIds.length; for (int i=0; i&lt;N; i++)...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Android的ApiDemo範例庫提供了一個很不錯的App Widget範例；不過，對初學者來說，這個範例可能稍嫌繁瑣。在這裡另外提供一個HelloAppWidget範例如下：

<blockquote><pre>/* 範例：HelloAppWidget.java */
package com.moko.hellowidget;
  
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.widget.RemoteViews;
  
public class HelloAppWidgetProvider extends AppWidgetProvider {
  
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        final int N = appWidgetIds.length;
        for (int i=0; i&lt;N; i++) {
            int appWidgetId = appWidgetIds[i];
            updateAppWidget(context, appWidgetManager, appWidgetId);
        }
    }
      
    public void onDeleted(Context context, int[] appWidgetIds) {
    }
  
    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
            int appWidgetId) {
    	CharSequence text;
      	
    	text = "www.jollen.org";
      	
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.main);
        views.setTextViewText(R.id.appwidget_text, text);
  
        appWidgetManager.updateAppWidget(appWidgetId, views);
    }
}</pre></blockquote>

一個很簡單的App Widget就是只需要這麼幾行程式碼，HelloAppWidget範例就是先前的App Widget操作示範使用的範例，HelloAppWidget會在桌面嵌進一個TextView組件，並顯示”www.jollen.org”字串。

由此範例可以了解，App Widget使用到Android提供的AppWidgetProvider類別，建議可以先行快速瀏覽Android Reference文件，以了解此類別的大略用法。

<strong>App Widget的設計流程</strong>

設計一個App Widget的流程，並不是由寫程式開始，所以上述的範例程式，並不是首要的重點。實作一個App Widget的過程，用到了過去教學裡的所有觀念，因此對以下的流程述描有不了解的地方，可以再回頭覆習過去的教學。

App Widget設計流程：

1. 規劃App Widget的大小以及更新時間，在res/xml/裡新增一份XML文件，命名為appwidget_provider.xml
2. 規劃App Widget的UI，修改res/layout/main.xml
3. 撰寫App Widget主程式，如上例
4. 編輯AndroidManifest.xml，設定App Widget可接受App Widget的更新事件：android.appwidget.action.APPWIDGET_UPDATE

換個角度來看，設計一個陽春版的App Widget至少需要以下4個檔案：

<ul><li>res/xml/appwidget_provider.xml</li>
<li>res/layout/main.xml</li>
<li>src/<package name>/HelloAppWidgetProvider.java</li>
<li>AndroidManifest.xml</li></ul>

有了設計流程後，接下來一一說明每個步驟的實作，以及技術重點。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#19: 什麼是App Widget？</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/07/jollen-android-programming-19.html" />
   <id>tag:www.jollen.org,2009:/blog//2.646</id>
   
   <published>2009-07-10T09:46:00Z</published>
   <updated>2009-08-05T07:00:52Z</updated>
   
   <summary>App Widget是Cupcake(Android 1.5)所提供的一個功能，這是一個很實用而且能有很大創意想像空間的功能。什麼是App Widget呢？請看底下的操作示範。 在Android桌面長壓約3秒，出現一個選單，如圖1。 圖1：新增項目至桌面 2. 選擇「Widget」，加入”HelloWidget” 圖2：加入自行設計的Widget 桌面上出現了一個「Widget」 圖3：在Android桌面上出現我們自已設計的App Widget 圖4：加入了音樂撥放器App Widget至桌面 這就是App Widget的應用，可以將一個小塊程式(program piece)嵌入到桌面上。App Widget也是一種UI組件，先前所介紹的TextView、WebView等也泛稱為Widget，二者在應用上的差異該怎麼思考呢？以下是幾點看法： 1. App Widget是有生命的UI組件，他會自動更新本身的內容 2. Widget是沒有生命的UI組件，它不會自我更新，只能等待使用者的操作 3. 應用上，App Widget能提供不斷更新的內容，很適合用來設計天氣、時鐘、新聞等主動式應用程式 4. Widget應用上只用來製作UI，而UI因為只能等待使用者來操作，所以過去我們所撰寫的Android應用程式都是屬於被動式應用程式 讓App Widget能「主動」更新自身內容的方法是透過一個「時間觸發裝置」，Android框架會根據我們設定的時間間隔，不斷地callback我們的App Widget。後續將再說明App Widget的做法，並解釋這個部份。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[App Widget是Cupcake(Android 1.5)所提供的一個功能，這是一個很實用而且能有很大創意想像空間的功能。什麼是App Widget呢？請看底下的操作示範。

在Android桌面長壓約3秒，出現一個選單，如圖1。

<img alt="app-widget" src="http://www.jollen.org/blog/2009/07/10/app-widget-1.png"  />
圖1：新增項目至桌面

2. 選擇「Widget」，加入”HelloWidget”

<img alt="app-widget" src="http://www.jollen.org/blog/2009/07/10/app-widget-2.png"  />
圖2：加入自行設計的Widget

桌面上出現了一個「Widget」

<img alt="app-widget" src="http://www.jollen.org/blog/2009/07/10/app-widget-3.png"  />
圖3：在Android桌面上出現我們自已設計的App Widget

<img alt="app-widget" src="http://www.jollen.org/blog/2009/07/10/app-widget-4.png"  />
圖4：加入了音樂撥放器App Widget至桌面

這就是App Widget的應用，可以將一個小塊程式(program piece)嵌入到桌面上。App Widget也是一種UI組件，先前所介紹的TextView、WebView等也泛稱為Widget，二者在應用上的差異該怎麼思考呢？以下是幾點看法：

1. App Widget是有生命的UI組件，他會自動更新本身的內容
2. Widget是沒有生命的UI組件，它不會自我更新，只能等待使用者的操作
3. 應用上，App Widget能提供不斷更新的內容，很適合用來設計天氣、時鐘、新聞等主動式應用程式
4. Widget應用上只用來製作UI，而UI因為只能等待使用者來操作，所以過去我們所撰寫的Android應用程式都是屬於被動式應用程式

讓App Widget能「主動」更新自身內容的方法是透過一個「時間觸發裝置」，Android框架會根據我們設定的時間間隔，不斷地callback我們的App Widget。後續將再說明App Widget的做法，並解釋這個部份。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#18: 佈景（Theme）初體驗</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/06/jollen-android-programming-18.html" />
   <id>tag:www.jollen.org,2009:/blog//2.643</id>
   
   <published>2009-06-21T05:30:00Z</published>
   <updated>2009-08-05T07:00:52Z</updated>
   
   <summary><![CDATA[上一節提到佈景（theme）是可以大範圍套用的UI美化功能，其套用範圍為「整個螢幕」，從程式碼的角度來看，佈景可以套用到以下二個範圍： 整個應用程式（application） 整個activity 接下來，我們以一個很簡單的例子，來說明如何套用佈景到application。在一些應用，我們可能不想要顯示視窗標題（title），怎麼做出這個功能呢？利用佈景設定的方式即可達成。以下是實作方法。 在styles.xml裡加入以下內容： &lt;?xml version="1.0" encoding="utf-8"?> &lt;resources> &lt;style name="myTheme"> &lt;item name="android:windowNoTitle">true &lt;/style> &lt;/resources> 修改AndroidManifest.xml，在標籤裡加上「theme」屬性： &lt;?xml version="1.0" encoding="utf-8"?> &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.moko.hellotheme" android:versionCode="1" android:versionName="1.0.0"> &lt;application android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@style/myTheme"> &lt;activity android:name=".HelloTheme" android:label="@string/app_name"> &lt;intent-filter> &lt;action android:name="android.intent.action.MAIN" /> &lt;category android:name="android.intent.category.LAUNCHER" /> &lt;/intent-filter> &lt;/activity>...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[上一節提到佈景（theme）是可以大範圍套用的UI美化功能，其套用範圍為「整個螢幕」，從程式碼的角度來看，佈景可以套用到以下二個範圍：

<ul><li>整個應用程式（application）</li>
<li>整個activity</li>
</ul>

接下來，我們以一個很簡單的例子，來說明如何套用佈景到application。在一些應用，我們可能不想要顯示視窗標題（title），怎麼做出這個功能呢？利用佈景設定的方式即可達成。以下是實作方法。

在styles.xml裡加入以下內容：

<pre>&lt;?xml version="1.0" encoding="utf-8"?>
&lt;resources>
    &lt;style name="myTheme">
    	&lt;item name="android:windowNoTitle">true</item>        
    &lt;/style> 
&lt;/resources></pre>

修改AndroidManifest.xml，在<application>標籤裡加上「theme」屬性：

<pre>&lt;?xml version="1.0" encoding="utf-8"?>
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.moko.hellotheme"
      android:versionCode="1"
      android:versionName="1.0.0">
    &lt;application android:icon="@drawable/icon" android:label="@string/app_name"
    	<strong>android:theme="@style/myTheme"</strong>>
        &lt;activity android:name=".HelloTheme"
                  android:label="@string/app_name">
            &lt;intent-filter>
                &lt;action android:name="android.intent.action.MAIN" />
                &lt;category android:name="android.intent.category.LAUNCHER" />
            &lt;/intent-filter>
        &lt;/activity>
    &lt;/application>
&lt;/manifest></pre>

執行結果：

<img alt="theme-1.png" src="http://www.jollen.org/blog/2009/06/21/theme-1.png" width="320" height="480" />
圖1: HelloTheme的執行結果

在這個範例裡，我們並沒有修改任何的程式碼，其原理是透過佈景設定的方法。定義佈景的方式與定義樣式（styles）相同，同樣是在styles.xml裡以&lt;item>標籤來定義。

以下是使用HelloTheme的說明：

1. &lt;item>的name屬性為android:windowNoTitle時，表示定義是否要顯示視窗標題，在此設定為true，表示不要有視窗標題
2. 在&lt;application>標籤裡加上theme屬性，將佈景套用到應用程式

佈景除了能套用到應用程式外，也能套用到activity。如何套用佈景到activity呢？只要在&lt;activity>裡加入theme屬性即可，做法與&lt;application>相同。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#17: 樣式設計（Styles）初體驗</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/06/jollen-android-programming-17.html" />
   <id>tag:www.jollen.org,2009:/blog//2.642</id>
   
   <published>2009-06-20T07:20:45Z</published>
   <updated>2009-08-05T07:00:52Z</updated>
   
   <summary><![CDATA[在這篇教學裡，我們將用一個非常簡單的範例來初步體驗Android的「styles」功能。 什麼是樣式（Styles）？ Android的樣式設計（style）是一個很重要的功能，因為它可以讓應用程式裡的元件（widget）「長」得跟別人很不一樣。樣式設計的使用規定如下： 在Android專案裡以XML資源檔來定義「樣式」 一個Android專案可以定義多個樣式 讓widget套用其中一個樣式 Android的styles功能，主要的對象是widget，樣式是為了套用到widget上；另外Android還提供佈景（theme）功能，可以做更大範圍的套用。 如何定義樣式 定義樣式的方式如下： 1. 在Android專案的「res/values」資料夾裡建立styles.xml樣式定義檔。如圖1。 圖1: 建立styles.xml 2.在styles.xml裡定義樣式，以下是一個範例： &lt;?xml version="1.0" encoding="utf-8"?> &lt;resources> &lt;style name="myText"> &lt;item name="android:textSize">18sp&lt;/item> &lt;item name="android:textColor">#880&lt;/item> &lt;/style> &lt;/resources> styles.xml的寫法說明如下： 1. 在 &lt;resource>標籤裡定義資源項目， &lt;style>標籤用來定義樣式資源 2. &lt;style>的name屬性定義此樣式的名字，widget使用此名字以套用樣式 3. &lt;item>標籤定義此樣式的內容 4. &lt;item>的name屬性為android:textSize時，表示定義此樣式的字體大小，在此設定字體大小為18sp 5. &lt;item>的name屬性為android:textColor時，表示定義此樣式的字體顏色，在此設定字體顏色為#880（RGB） 6....]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[在這篇教學裡，我們將用一個非常簡單的範例來初步體驗Android的「styles」功能。

<strong>什麼是樣式（Styles）？</strong>

Android的樣式設計（style）是一個很重要的功能，因為它可以讓應用程式裡的元件（widget）「長」得跟別人很不一樣。樣式設計的使用規定如下：

<ul><li>在Android專案裡以XML資源檔來定義「樣式」</li>
<li>一個Android專案可以定義多個樣式</li>
<li>讓widget套用其中一個樣式</li>
</ul>

Android的styles功能，主要的對象是widget，樣式是為了套用到widget上；另外Android還提供佈景（theme）功能，可以做更大範圍的套用。

<strong>如何定義樣式</strong>

定義樣式的方式如下：

1. 在Android專案的「res/values」資料夾裡建立styles.xml樣式定義檔。如圖1。

<img alt="styles-1.png" src="http://www.jollen.org/blog/2009/06/20/styles-1.png" width="525" height="592" />
圖1: 建立styles.xml

2.在styles.xml裡定義樣式，以下是一個範例：

<blockquote><pre>&lt;?xml version="1.0" encoding="utf-8"?>
&lt;resources>
    &lt;style name="myText">
        &lt;item name="android:textSize">18sp&lt;/item>
        &lt;item name="android:textColor">#880&lt;/item>
    &lt;/style>
&lt;/resources></pre></blockquote>

styles.xml的寫法說明如下：

1. 在 &lt;resource>標籤裡定義資源項目， &lt;style>標籤用來定義樣式資源
2.  &lt;style>的name屬性定義此樣式的名字，widget使用此名字以套用樣式
3.  &lt;item>標籤定義此樣式的內容
4.  &lt;item>的name屬性為android:textSize時，表示定義此樣式的字體大小，在此設定字體大小為18sp
5.  &lt;item>的name屬性為android:textColor時，表示定義此樣式的字體顏色，在此設定字體顏色為#880（RGB）
6. 更多的樣式屬性，請參考Android Reference

定義好樣式後，就可以讓widget套用樣式。

<strong>Widget如何套用樣式</strong>

如何讓widget套用上述定義的「myText」樣式，方法很簡單。還記得UI layout檔main.xml嗎？只要在widget的項目裡，加上style屬性，並指定樣式名稱即可。以下是HelloStyles範例：

<blockquote> <pre>&lt;?xml version="1.0" encoding="utf-8"?>
 &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
 &lt;TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Hello, this is HelloStyles."
<strong>    style="@style/myText"</strong>
    />
 &lt;/LinearLayout></pre></blockquote>

「@style/myText」表示要指定一個style的名稱，此名稱為myText。

執行結果：

<img alt="styles-2.png" src="http://www.jollen.org/blog/2009/06/20/styles-2.png" width="320" height="480" />
圖2: HelloStyles的執行畫面]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#16: Event Listener的用法: 以Click Listener為例</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/06/jollen-android-programming-16.html" />
   <id>tag:www.jollen.org,2009:/blog//2.641</id>
   
   <published>2009-06-18T15:18:30Z</published>
   <updated>2009-08-05T07:00:53Z</updated>
   
   <summary>Event Listener的用法: 以Click Listener為例 以Android所提供的View.OnClickListener來說明程式實作方法。一個較為良好的實作方法是在我們的Acitivty類別裡實作View.OnClickListener介面，即： import android.view.View; public class HelloClickListener extends Activity implements View.OnClickListener { ... } 每一個View都可以註冊一個event listener，當Android框架收到「click」事件後，便回呼event listener的callback method。以Button類別（按鈕元件）為例，當我們想要處理使用者觸控按鈕的事件時，就要呼叫Button類別的setOnClickListener()方法來註冊click listener。上述的實作方方法是，直接在我們的Activity類別HelloClickListener裡實作View.OnClickListener，因此上述Button類別的click listener為「this」。 上述的實作觀念，可用圖1來表示。 圖1: HelloClickListener類別實作View.OnClickListener介面 註冊click listener的程式碼如下： public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button button = (Button)findViewById(R.id.btn); button.setOnClickListener(this);...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<strong>Event Listener的用法: 以Click Listener為例</strong>

以Android所提供的View.OnClickListener來說明程式實作方法。一個較為良好的實作方法是在我們的Acitivty類別裡實作View.OnClickListener介面，即：

<pre>import android.view.View;
  
public class HelloClickListener extends Activity implements View.OnClickListener {
   ...
}</pre>

每一個View都可以註冊一個event listener，當Android框架收到「click」事件後，便回呼event listener的callback method。以Button類別（按鈕元件）為例，當我們想要處理使用者觸控按鈕的事件時，就要呼叫Button類別的setOnClickListener()方法來註冊click listener。上述的實作方方法是，直接在我們的Activity類別HelloClickListener裡實作View.OnClickListener，因此上述Button類別的click listener為「this」。

上述的實作觀念，可用圖1來表示。

<img alt="HelloClickListener.png" src="http://www.jollen.org/blog/2009/06/18/HelloClickListener.png" width="385" height="393" />
圖1: HelloClickListener類別實作View.OnClickListener介面

註冊click listener的程式碼如下：

<pre>   public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Button button = (Button)findViewById(R.id.btn);
        button.setOnClickListener(this);
    }</pre>

在onCreate()裡先找到Button元件，它的click listener為this為，接著在我們的Activity類別裡實作onClick()。onClick()方法的程式碼如下，我們以Toast類別來回應訊息給使用者：

<pre>   public void onClick(View v) {
        Toast.makeText(
                this,
                "Yes.",
                Toast.LENGTH_LONG).show();  
    }</pre>

<strong>完整程式碼: HelloClickListener.java</strong>

<pre>package com.moko.helloclicklistener;
   
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import android.view.View;
   
public class HelloClickListener extends Activity <strong>implements View.OnClickListener</strong> {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Button button = (Button)findViewById(R.id.btn);
        button.setOnClickListener(this);
    }
    
<strong>    public void onClick(View v) {
        Toast.makeText(
                this,
                "Yes.",
                Toast.LENGTH_LONG).show();  
    }</strong>
}</pre>

<strong>執行結果</strong>

<img alt="clicklistener-1.png" src="http://www.jollen.org/blog/2009/06/18/clicklistener-1.png" width="320" height="480" />
圖2: HelloClickListener的執行結果

當使用者觸碰畫面上的按鈕時，便以Toast類別在畫面上顯示「Yes」。

]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#15: 什麼是事件監聽器(Event Listener)？</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/06/jollen-android-programming-15.html" />
   <id>tag:www.jollen.org,2009:/blog//2.640</id>
   
   <published>2009-06-18T15:15:37Z</published>
   <updated>2009-08-05T07:00:53Z</updated>
   
   <summary>學會產生基本的UI後，接著就要學習UI的事件處理(UI Events)，才能讓UI與使用者「互動」。 什麼是事件監聽器(Event Listener) UI的使用者事件處理，即View如何處理使用者的操作，是一個重要的課題。View是重要的類別，它是與使用者互動的前線；在Android框架的設計中，以事件監聽器（event listener）的方式來處理UI的使用者事件。 Android框架提供了非常良好的UI事件處理機制。先前的教學提到，View是繪製UI的類別，每個View物件都可以向Android框架註冊一個事件監聽器。每個事件監聽器都包含一個回呼函數（callback method）， 這個回呼函數（callback method）主要的工作就是回應或處理使用者的操作。 Event Listener: 以Click Listener為例 以「使用者觸碰（touch）」的動作來說，當View要處理使用者觸碰的事件時，就要向Android框架註冊View.OnClickListener事件監聽器；當「touch」事件發生時，Android框架便回呼事件監聽器裡的回呼函數。 View.OnClickListener是click listener，故名思意，這是UI的「Click動作監聽器」；當使用者對View進行Click操作時（即觸控畫面上的UI元件），Android框架便會回呼這個View.OnClickListener的回呼函數。 View.OnClickListerner的回呼函數為OnClick()。 這裡所提到的監聽器泛指event listener，主要用來「監聽」使用者的各種動作。除了View.OnClickListener外，Android框架還有以下的event listener（及其callback method）： View.OnLongClickListener: onLongClick() View.OnFocusChangeListener: onFocusChange() View.OnKeyListener: onKey() View.OnTouchListener: onTouch() View.OnCreateContextMenuListener: onCreateContextMenu() 另外一種處理UI事件的機制為事件處理器（event handler），event handler與event listener是不一樣的二種處理機制。在自訂Android component的教學裡，再介紹這個部份。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[學會產生基本的UI後，接著就要學習UI的事件處理(UI Events)，才能讓UI與使用者「互動」。

<strong>什麼是事件監聽器(Event Listener)</strong>

UI的使用者事件處理，即View如何處理使用者的操作，是一個重要的課題。View是重要的類別，它是與使用者互動的前線；在Android框架的設計中，以事件監聽器（event listener）的方式來處理UI的使用者事件。

Android框架提供了非常良好的UI事件處理機制。先前的教學提到，View是繪製UI的類別，每個View物件都可以向Android框架註冊一個事件監聽器。每個事件監聽器都包含一個回呼函數（callback method），

這個回呼函數（callback method）主要的工作就是回應或處理使用者的操作。

<strong>Event Listener: 以Click Listener為例</strong>

以「使用者觸碰（touch）」的動作來說，當View要處理使用者觸碰的事件時，就要向Android框架註冊View.OnClickListener事件監聽器；當「touch」事件發生時，Android框架便回呼事件監聽器裡的回呼函數。

View.OnClickListener是click listener，故名思意，這是UI的「Click動作監聽器」；當使用者對View進行Click操作時（即觸控畫面上的UI元件），Android框架便會回呼這個View.OnClickListener的回呼函數。

View.OnClickListerner的回呼函數為OnClick()。

這裡所提到的監聽器泛指event listener，主要用來「監聽」使用者的各種動作。除了View.OnClickListener外，Android框架還有以下的event listener（及其callback method）：

<ul><li>View.OnLongClickListener: onLongClick()</li>
<li>View.OnFocusChangeListener: onFocusChange()</li>
<li>View.OnKeyListener: onKey()</li>
<li>View.OnTouchListener: onTouch()</li>
<li>View.OnCreateContextMenuListener: onCreateContextMenu()</li>
</ul>

另外一種處理UI事件的機制為事件處理器（event handler），event handler與event listener是不一樣的二種處理機制。在自訂Android component的教學裡，再介紹這個部份。]]>
      
   </content>
</entry>
<entry>
   <title>Garmin-Asus的nuvifone G60改用Android作業系統</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/06/garmin-asus-nuvifone-g60-android.html" />
   <id>tag:www.jollen.org,2009:/blog//2.639</id>
   
   <published>2009-06-17T02:46:29Z</published>
   <updated>2009-08-05T07:00:53Z</updated>
   
   <summary>CNET ASIA上的一則報導[Android to replace Garmin-Asus&apos; current Linux platform]指出，Garmin-Asus的nuvifone G60將改採Android作業系統。 (圖片來源：CNET) 2009年二月，Garmin與Asus正式宣佈策略聯盟，並以「Garmin-Asus」雙品牌策略進行行銷。nuvifone G60是Garmin-Asus雙品牌行銷策略下的第一個產物，nuvifone G60則是以導航功能為主軸的手機。 根據報導指出，Garmin-Asus現有的Linux平臺將只使用在G60裝置上，未來的裝置會採用Windows Mobile或者是Android作業系統。 如同Garmin的PND產品都是採用Linux作業系統一樣，原本nuvifone G60也計畫採用Linux作業系統，不久前，在engadget上的報導也出現實機照片；但是，隨著CNET這則報導的出現，整個開發計畫是否有了改變，頗令人好奇。 Android原本就對Google Map有很好的支援，再加上nuvifone G60是以導航以及地圖應用為主的手機，若是改採Android作業系統，也是一個合理的做法。 * Update: 2009/6/19...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[CNET ASIA上的一則報導[<a href="http://asia.cnet.com/crave/2009/06/16/android-to-replace-garmin-asus-current-linux-platform/" target="_blank">Android to replace Garmin-Asus' current Linux platform</a>]指出，<strike>Garmin-Asus的nuvifone G60將改採Android作業系統</strike>。

<img alt="nuvifone-g60.jpg" src="http://www.jollen.org/blog/2009/06/17/nuvifone-g60.jpg" width="500" height="375" />
(圖片來源：CNET)

2009年二月，Garmin與Asus正式宣佈策略聯盟，並以「Garmin-Asus」雙品牌策略進行行銷。nuvifone G60是Garmin-Asus雙品牌行銷策略下的第一個產物，nuvifone G60則是以導航功能為主軸的手機。

<font color="#ff0000">根據報導指出，Garmin-Asus現有的Linux平臺將只使用在G60裝置上，未來的裝置會採用Windows Mobile或者是Android作業系統。</font>

<strike>如同Garmin的PND產品都是採用Linux作業系統一樣，原本nuvifone G60也計畫採用Linux作業系統，</strike>不久前，在<a href="http://chinese.engadget.com/2009/05/26/garmin-asus-nuvifone-g60-hands-on/" target="_blank">engadget</a>上的報導也出現實機照片<strike>；但是，隨著CNET這則報導的出現，整個開發計畫是否有了改變，頗令人好奇。</strike>

<strike>Android原本就對Google Map有很好的支援，再加上nuvifone G60是以導航以及地圖應用為主的手機，若是改採Android作業系統，也是一個合理的做法。</strike>

* Update: 2009/6/19
]]>
      
   </content>
</entry>
<entry>
   <title>Linux 2.6.30 釋出</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/06/linux-2-6-30-announced.html" />
   <id>tag:www.jollen.org,2009:/blog//2.638</id>
   
   <published>2009-06-16T02:56:10Z</published>
   <updated>2009-08-05T07:00:53Z</updated>
   
   <summary>Linux 2.6.30於2009年6月9日釋出，Linux kernel的發展進入了Linux 2.6.3x的時代。最近一年的 Linux 2.6核心發展有相當重大的進展，除了幾個知名大廠不斷貢獻程式碼外，新產品的開發，也帶動Linux kernel的快速發展。 Linux 2.6.30加入了新的filesystem： 1. NILFS2 一種log-structured filesystem，由John K. Ousterhout與Fred Douglis於1988年提出的設計，主要針對high write throughput的應用。 2. POHMELFS (Parallel Optimized Host Message Exchange Layered File System) 一個分散式平行處理的檔案系統，在讀寫操作方面，根據[POHMELFS]官方的數據指出，POHMELFS的效能比NFS還好。 3. DST（Distributed STorage） 一個具高效能與可信賴的網路儲存檔案系統。 4. EXOFS（Object-Based Storage Devices） 支援OSD protocol的檔案系統。 5....</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Linux Device Drivers &amp; Kernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Linux 2.6.30於2009年6月9日釋出，Linux kernel的發展進入了Linux 2.6.3x的時代。最近一年的 Linux 2.6核心發展有相當重大的進展，除了幾個知名大廠不斷貢獻程式碼外，新產品的開發，也帶動Linux kernel的快速發展。

Linux 2.6.30加入了新的filesystem：

1. NILFS2

一種log-structured filesystem，由John K. Ousterhout與Fred Douglis於1988年提出的設計，主要針對high write throughput的應用。

2. POHMELFS (Parallel Optimized Host Message Exchange Layered File System)

一個分散式平行處理的檔案系統，在讀寫操作方面，根據[<a href="http://www.ioremap.net/projects/pohmelfs" target="_blank">POHMELFS</a>]官方的<a href="http://www.ioremap.net/node/134" target="_blank">數據</a>指出，POHMELFS的效能比NFS還好。

3. DST（Distributed STorage）

一個具高效能與可信賴的網路儲存檔案系統。

4. EXOFS（Object-Based Storage Devices）

支援OSD protocol的檔案系統。

5. FS-Cache

這是一個網路檔案系統（networking filesystem）的cache layer，FS-Cache可以將網路檔案系統的資料 cache 在磁碟裡。

<strong>其他更新</strong>

另外，Intel也貢獻了fastboot（快速開機）程式碼，過去kernel在開機時花費許多時間在處理 I/O 上，例如：儲存裝置的I/O，由Intel貢獻的fastboot以asynchronous function call的觀念解決此問題。其原理在kernel/async.c裡的註解有很清楚的說明：

<pre>14 /*
15
16 Goals and Theory of Operation
17
18 The primary goal of this feature is to reduce the kernel boot time,
19 by doing various independent hardware delays and discovery operations
20 decoupled and not strictly serialized.
21
22 More specifically, the asynchronous function call concept allows
23 certain operations (primarily during system boot) to happen
24 asynchronously, out of order, while these operations still
25 have their externally visible parts happen sequentially and in-order.
26 (not unlike how out-of-order CPUs retire their instructions in order)
27
28 Key to the asynchronous function call implementation is the concept of
29 a "sequence cookie" (which, although it has an abstracted type, can be
30 thought of as a monotonically incrementing number).
31
32 The async core will assign each scheduled event such a sequence cookie and
33 pass this to the called functions.
34
35 The asynchronously called function should before doing a globally visible
36 operation, such as registering device numbers, call the
37 async_synchronize_cookie() function and pass in its own cookie. The
38 async_synchronize_cookie() function will make sure that all asynchronous
39 operations that were scheduled prior to the operation corresponding with the
40 cookie have completed.
41
42 Subsystem/driver initialization code that scheduled asynchronous probe
43 functions, but which shares global resources with other drivers/subsystems
44 that do not use the asynchronous call feature, need to do a full
45 synchronization with the async_synchronize_full() function, before returning
46 from their init function. This is to maintain strict ordering between the
47 asynchronous and synchronous parts of the kernel.
48
49 */</pre>

關於 fastboot 的做法，在LWN上的一篇文章[<a href="http://lwn.net/Articles/314808" target="_blank">An asynchronous function call infrastructure</a>]有很不錯的介紹。

Red Hat也貢獻了二個新的system call：preadv()與pwritev()。其他更多Linux 2.6.30的變更，可參考[<a href="http://kernelnewbies.org/LinuxChanges" target="_blank">kernelnewbies</a>]上的說明。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#14: 什麼是對話盒 (Dialog)？如何建立對話盒？</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/06/jollen-android-programming-14.html" />
   <id>tag:www.jollen.org,2009:/blog//2.637</id>
   
   <published>2009-06-10T06:56:50Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary>最少的元件、最舒適的介面 自從有了圖形化應用程式之後，對話盒（dialog）一直是元老級的元件（widget）；智慧型手機開始流行後，對話盒仍然是手機介面的重要圖形元件。 在Apple的iPhone問世後，觸控螢幕（touch screen）一直是智慧型手機的標準規格，因此傳統的滑鼠點擊（click）式介面，並不完全適合手指觸控的操作方式，再加上手機觸控螢幕尺吋較小，因此手機應用程式的介面設計，已經與傳統的桌面環境相當不同。 Android的元件庫考量了小尺吋的觸控螢幕，在基本元件的設計上，Android也為使用者做了很體貼的考量。以Android手機應用程式來說，經常使用的元件已經不再像過去的點擊式系統那麼多又複雜；以使用性的角度來看，常被使用的元件如下： * 選單（Menu） * 對話盒（Dialog） * 快顯訊息（Toast） 使用以上三個元件，以及其「變化形」，就能建構一個好用的應用程式介面；再加上Android針對上述的手機操作特性，對其元件庫做了很好的使用設計，因此使用很少的元件，也能提供使用者一個舒適好用的操作介面。 何謂對話盒？ 對話盒，故名其思，是一個讓應用程式與使用者「對話」的元件。應用程式透過對話盒與使用者進行下述的對話： * 詢問問題：使用者回答 Yes/No * 詢問偏好：使用者選擇自已偏好的項目，可以是單選，也可以是複選 * 說明狀態：讓使用者知道應用程式目前的狀態，例如：顯示「處理中」、「載入中」等訊息 Android提供的對話盒物件為android.app.Dialog，實作上繼承自Dialog的AlertDialog物件是最基本的對話盒物件。使用AlertDialog對話盒，可以詢問使用者問題，也可以詢問使用者偏好。接下來介紹AlertDialog對話盒的設計方法。 建立AlertDialog對話盒 延續「HelloMenu」範例，現在我們想要加入以下的使用情境： * 使用者按下Menu鍵 * 使用者觸壓 “New Message” 選項 * 出現對話盒、詢問使用者 “Yes/No” 由以上的使用情境來看，應該在onOptionsItemSelected()裡判斷到R.id.new_message項目時，在UI上建立一個對話盒。以下是修改後的onOptionsItemSelected()完整程式碼，完整範例名稱為HelloAlertDialog： public boolean onOptionsItemSelected(MenuItem item) {...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<strong>最少的元件、最舒適的介面</strong>

自從有了圖形化應用程式之後，對話盒（dialog）一直是元老級的元件（widget）；智慧型手機開始流行後，對話盒仍然是手機介面的重要圖形元件。

在Apple的iPhone問世後，觸控螢幕（touch screen）一直是智慧型手機的標準規格，因此傳統的滑鼠點擊（click）式介面，並不完全適合手指觸控的操作方式，再加上手機觸控螢幕尺吋較小，因此手機應用程式的介面設計，已經與傳統的桌面環境相當不同。

Android的元件庫考量了小尺吋的觸控螢幕，在基本元件的設計上，Android也為使用者做了很體貼的考量。以Android手機應用程式來說，經常使用的元件已經不再像過去的點擊式系統那麼多又複雜；以使用性的角度來看，常被使用的元件如下：

* 選單（Menu）
* 對話盒（Dialog）
* 快顯訊息（Toast）

使用以上三個元件，以及其「變化形」，就能建構一個好用的應用程式介面；再加上Android針對上述的手機操作特性，對其元件庫做了很好的使用設計，因此使用很少的元件，也能提供使用者一個舒適好用的操作介面。

<strong>何謂對話盒？</strong>

對話盒，故名其思，是一個讓應用程式與使用者「對話」的元件。應用程式透過對話盒與使用者進行下述的對話：

* 詢問問題：使用者回答 Yes/No
* 詢問偏好：使用者選擇自已偏好的項目，可以是單選，也可以是複選
* 說明狀態：讓使用者知道應用程式目前的狀態，例如：顯示「處理中」、「載入中」等訊息

Android提供的對話盒物件為android.app.Dialog，實作上繼承自Dialog的AlertDialog物件是最基本的對話盒物件。使用AlertDialog對話盒，可以詢問使用者問題，也可以詢問使用者偏好。接下來介紹AlertDialog對話盒的設計方法。

<strong>建立AlertDialog對話盒</strong>

延續「HelloMenu」範例，現在我們想要加入以下的使用情境：

* 使用者按下Menu鍵
* 使用者觸壓 “New Message” 選項
* 出現對話盒、詢問使用者 “Yes/No”

由以上的使用情境來看，應該在onOptionsItemSelected()裡判斷到R.id.new_message項目時，在UI上建立一個對話盒。以下是修改後的onOptionsItemSelected()完整程式碼，完整範例名稱為HelloAlertDialog：

<pre>public boolean onOptionsItemSelected(MenuItem item) {
    	int item_id = item.getItemId();
    	
    	switch (item_id){
    		case R.id.new_message: 
	    	        AlertDialog.Builder builder = new AlertDialog.Builder(this);
	    	        
	    	        builder.setMessage("Also post your message to Twitter?");
	    	        builder.setCancelable(false);
	    	        
	    	        builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
	    	        	public void onClick(DialogInterface dialog, int id) {
	    	        	}
	    	        });
	    	        
	    	        builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
	    	        	public void onClick(DialogInterface dialog, int id) {
	    	        	}
	    	        });   
	    	        
	    	        AlertDialog alert = builder.create();
	    	        alert.show();
    			break;
    		case R.id.quit: 
                Toast.makeText(
                        this,
                        "Going to quit.",
                        Toast.LENGTH_LONG).show();    			
    			break;
    		default: return false;
    	}
    	return true;
 }</pre>

<img alt="dialog-1.png" src="http://www.jollen.org/blog/2009/06/10/dialog-1.png" width="300" height="433" />
圖1: Android的AlertDialog對話盒

產生AlertDialog物件的說明：

1. 產生AlertDialog.builder物件（dialog builder），這是一個用來建立對話盒內容的產生器物件

2. 設定dialog builder的顯示訊息-builder.setMessage()

3. 設定對話盒能不能被「取消」-builder.setCancelable()

4. 利用dialog builder在對話盒裡產生二個按鈕「Yes與No」-builder.setPositiveButton()與builder.setNegativeButton()
使用dialog builder來建立AlertDialog物件，AlertDialog是真正的對話盒物件-builder.create()

5. 將AlertDialog顯示在UI上-alert.show()

產生「Yes按鈕」的程式如下：

<pre>builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
	public void onClick(DialogInterface dialog, int id) {
		}
});</pre>

呼叫builder.setPositiveButton()方法建立一個「正面（Yes）」的按鈕，參數說明如下：

1. 第一個參數：顯示在按鈕上的文字
2. 第二個參數：指定 click listener

每一個按鈕都需要一個click listener，當使用者觸壓按鈕時，click listener便被回呼。android.content.DialogInterface類別提供click listener物件。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#13: 快顯訊息 android.widget.Toast</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/06/jollen-android-programming-13.html" />
   <id>tag:www.jollen.org,2009:/blog//2.636</id>
   
   <published>2009-06-03T16:20:03Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary>Toast是Android提供「快顯訊息」類別，使用時請import以下套件： import android.widget.Toast; 這是一個很好用的類別，特別是在初步建立Android應用程式的控制或行為時，可以輔助我們進行初步的測試工作。 配合上述的選單範例，我們將onOptionsItemSelected()回呼函數實作修改如下： public boolean onOptionsItemSelected(MenuItem item) { int item_id = item.getItemId(); switch (item_id){ case R.id.new_message: Toast.makeText( this, &quot;Please enter your message.&quot; + &quot; Your message is at max 255 characters.&quot;, Toast.LENGTH_LONG).show(); break; case R.id.quit: Toast.makeText( this, &quot;Going...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>Toast是Android提供「快顯訊息」類別，使用時請import以下套件：</p>

<blockquote><pre>import android.widget.Toast;</pre></blockquote>

<p>這是一個很好用的類別，特別是在初步建立Android應用程式的控制或行為時，可以輔助我們進行初步的測試工作。</p>

<p>配合上述的選單範例，我們將onOptionsItemSelected()回呼函數實作修改如下：</p>

<blockquote><pre>    public boolean onOptionsItemSelected(MenuItem item) {
    	int item_id = item.getItemId();
    	
    	switch (item_id){
    		case R.id.new_message: 
                Toast.makeText(
                        this,
                        "Please enter your message."
                                + " Your message is at max 255 characters.",
                        Toast.LENGTH_LONG).show();
    			break;
    		case R.id.quit: 
                Toast.makeText(
                        this,
                        "Going to quit.",
                        Toast.LENGTH_LONG).show();    			
    			break;
    		default: return false;
    	}</pre></blockquote>
    	
<p>此範例以Toast快顯訊息類別來顯示簡短訊息，以驗證上一個選單範例的功能是否正常。</p>

<img alt="toast-1.png" src="http://www.jollen.org/blog/2009/06/04/toast-1.png" width="354" height="679" />]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#12: 如何建立選單 Menu</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/06/jollen-android-programming-12.html" />
   <id>tag:www.jollen.org,2009:/blog//2.635</id>
   
   <published>2009-06-03T09:21:32Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary><![CDATA[Android應用程式的UI可以使用XML來定義，這個部份在前面的教學裡介紹過。要定義Android應用程式的選單，我們同樣可以使用XML來做描述，請看以下的說明。 建立 Menu 步驟 1. 建立選單的XML檔 在Android專案的res/目錄下新增一個menu/子目錄，然後建立options_menu.xml文件。 圖1: 建立menu/目錄 圖2: 建立options_menu.xml文件 2. 以XML定義選單內容 在options_menu.xml檔案裡，定義我們想要的選單內容。以下是一個範例： &lt;menu xmlns:android="http://schemas.android.com/apk/res/android"> &lt;item android:id="@+id/new_message" android:title="New Message" /> &lt;item android:id="@+id/quit" android:title="Quit" /> &lt;/menu> 3. 將選單加入應用程式 要如何在應用程式啟動時加入我們定義好的選單呢？在onCreateOptionsMenu()事件裡以MenuInflater類別將定義好的選單加入應用程式： public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.options_menu, menu);...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>Android應用程式的UI可以使用XML來定義，這個部份在前面的教學裡介紹過。要定義Android應用程式的選單，我們同樣可以使用XML來做描述，請看以下的說明。</p>

<strong>建立 Menu 步驟</strong>

<p>1. 建立選單的XML檔</p>

<p>在Android專案的res/目錄下新增一個menu/子目錄，然後建立options_menu.xml文件。</p>
<img alt="menu-1.png" src="http://www.jollen.org/blog/2009/06/03/menu-1.png" width="589" height="674" />
<p>圖1: 建立menu/目錄</p>

<img alt="menu-2.png" src="http://www.jollen.org/blog/2009/06/03/menu-2.png" width="525" height="592" />
<p>圖2: 建立options_menu.xml文件</p>

<p>2. 以XML定義選單內容</p>

<p>在options_menu.xml檔案裡，定義我們想要的選單內容。以下是一個範例：</p>

<blockquote><pre>&lt;menu xmlns:android="http://schemas.android.com/apk/res/android">
    &lt;item android:id="@+id/new_message"
          android:title="New Message" />
    &lt;item android:id="@+id/quit"
          android:title="Quit" />
&lt;/menu></pre></blockquote>

<p>3. 將選單加入應用程式</p>

<p>要如何在應用程式啟動時加入我們定義好的選單呢？在onCreateOptionsMenu()事件裡以MenuInflater類別將定義好的選單加入應用程式：</p>

<blockquote><pre>public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);
    return true;
}</pre></blockquote>

<p>在這個範例裡，我們使用到二個類別：Menu與MenuInflater，因此記得import這二個套件：</p>

<blockquote><pre>import android.view.Menu;
import android.view.MenuInflater;</pre></blockquote>

<strong>執行結果</strong>

<p>按下手機上的Menu鍵後，出現我們所設計的選單，如圖3。</p>

<img alt="menu-3.png" src="http://www.jollen.org/blog/2009/06/03/menu-3.png" width="900" height="752" />
<p>圖3: HelloMenu範例的選單畫面</p>

<strong>處理選單</strong>

<p>最後一個問題是，當使用者觸壓選單上的選項時，Android應用程式要如何處理？方法是透過onOptionsItemSelected()事件：</p>

<blockquote><pre>    public boolean onOptionsItemSelected(MenuItem item) {
    	return true;
    }</pre></blockquote>

<p>當此事件被回呼時，Android框架傳入被觸壓的選項物件，其類別為MenuItem；請import此套件：</p>

<blockquote><pre>import android.view.MenuItem;</pre></blockquote>

<p>前述的教學提到，Android應用程式編譯時，會自動產生R類別，即描述UI的類別。我們所定義的選單UI也會被放到R類別裡，如下：</p>

<blockquote><pre>package com.moko.hellomenu;

public final class R {
    public static final class attr {
    }
    public static final class drawable {
        public static final int icon=0x7f020000;
    }
<strong>    public static final class id {
        public static final int new_message=0x7f060000;
        public static final int quit=0x7f060001;
    }</strong>
    public static final class layout {
        public static final int main=0x7f030000;
    }
    public static final class menu {
        public static final int options_menu=0x7f050000;
    }
    public static final class string {
        public static final int app_name=0x7f040001;
        public static final int hello=0x7f040000;
    }
}</pre></blockquote>

<p>以下是處理MenuItem的程式範例：</p>

<blockquote><pre>    public boolean onOptionsItemSelected(MenuItem item) {
    	int item_id = item.getItemId();
    	
    	switch (item_id){
    		case R.id.new_message: break;
    		case R.id.quit: break;
    		default: return false;
    	}
    	return true;
    }</pre></blockquote>

<p>呼叫MenuItem的getItemId()方法，可取得該選項的ID，如此一來便能得知使用者所觸壓的選項。</p>

<strong>完整程式列表</strong>

<blockquote><pre>/* 範例檔名：HelloMenu.java */
package com.moko.hellomenu;

import android.app.Activity;
import android.os.Bundle;
<strong>import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;</strong>

public class HelloMenu extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    
<strong>    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.options_menu, menu);
        return true;
    }</strong>
    
    public boolean onOptionsItemSelected(MenuItem item) {
    	int item_id = item.getItemId();
    	
    	switch (item_id){
    		case R.id.new_message: break;
    		case R.id.quit: break;
    		default: return false;
    	}
    	return true;
    }
}</pre></blockquote>]]>
      
   </content>
</entry>
<entry>
   <title>「Android Porting Highlights」簡報上線</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/05/android-porting-highlights.html" />
   <id>tag:www.jollen.org,2009:/blog//2.625</id>
   
   <published>2009-05-22T02:55:37Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary>上週受邀至「首屆亞太區 Android 技術大會」發表演說，由於大會希望能多著重在技術層面的主題，因此整理了過去研究 Android/FreeRunner 的一些資料，並將「重點」部份做了一次概念性的說明。Android 的分支（branch）是以「產品」的概念做維護，因此若在目前 Cupcake 能支援的平臺（architecture）上做移植的話，是一個較簡單的工作，只需要在 vendor/ 裡新增自已的 product 並修改 AndroidBoard.mk、AndroidProducts.mk 以及 BoardConfig.mk 即可完成一個 Board/Product 的新分支。 關於底層的部份，以 armv4（如 s3c2443）的 architecture 為例，將重要的工作項目做了整理式的說明。在此提供簡報電子檔下載 [Android Porting Highlights]。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[上週受邀至「首屆亞太區 Android 技術大會」發表演說，由於大會希望能多著重在技術層面的主題，因此整理了過去研究 Android/FreeRunner 的一些資料，並將「重點」部份做了一次概念性的說明。Android 的分支（branch）是以「產品」的概念做維護，因此若在目前 Cupcake 能支援的平臺（architecture）上做移植的話，是一個較簡單的工作，只需要在 vendor/ 裡新增自已的 product 並修改 AndroidBoard.mk、AndroidProducts.mk 以及 BoardConfig.mk 即可完成一個 Board/Product 的新分支。

關於底層的部份，以 armv4（如 s3c2443）的 architecture 為例，將重要的工作項目做了整理式的說明。在此提供簡報電子檔下載 [<a href="http://www.jollen.org/slides/apac-android-porting-r2.pdf">Android Porting Highlights</a>]。]]>
      
   </content>
</entry>
<entry>
   <title>中國移動 OPhone 現身：採用 OMS 系統的 Android 手機（實機附圖）</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/05/china-mobile-ophone-oms.html" />
   <id>tag:www.jollen.org,2009:/blog//2.623</id>
   
   <published>2009-05-19T14:57:08Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary>中國版的 Android 系統 OMS 現身 (China&apos;s Android OS，OMS - Open Mobile System)。 日前一則新聞 [大陸OPhone商機 台商幕後推手] 以及 [中移動5月中下旬發佈Ophone手機 主介面已可上網流覽] 報導了中國移動（China Mobile）所推出的 OPhone 手機，採用 OMS 作業系統。本週在北京與 OMS（Open Mobile System）的開發商「播思通讯（BORQS）」人員餐敘，OMS 的開發者也拿出了 OMS 的參考設計（reference design）實機讓現場朋友實機操作。 OMS 採用的正是 Google 的 Android 作業系統，如同上述報導所提，OMS 是 BORQS 與...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[中國版的 Android 系統 OMS 現身 (China's Android OS，OMS - Open Mobile System)。

日前一則新聞 [<a href="http://news.chinatimes.com/CMoney/News/News-Page-content/0,4993,11050701+122009051000204,00.html" target="_blank">大陸OPhone商機 台商幕後推手</a>] 以及 [<a href="http://news.cnyes.com/stock/dspnewsS.asp?fi=\NEWSBASE\20090511\WEB782&vi=32214&date=20090511&time=10:54:45&pagetype=usastock&subtype=home&cls=usastock_totalnews" target="_blank">中移動5月中下旬發佈Ophone手機 主介面已可上網流覽</a>] 報導了中國移動（China Mobile）所推出的 OPhone 手機，採用 OMS 作業系統。本週在北京與 OMS（Open Mobile System）的開發商「<a href="http://www.borqs.com" target="_blank">播思通讯（BORQS）</a>」人員餐敘，OMS 的開發者也拿出了 OMS 的參考設計（reference design）實機讓現場朋友實機操作。

OMS 採用的正是 Google 的 Android 作業系統，如同上述報導所提，OMS 是 BORQS 與 Google 共同合作開發的中國版 Android 作業系統。OMS 專門針對中國移動做了許多客製化的應用程式。由於機會難得，因此特別拍了一些照片，在這裡跟大家分享。另外也看到了另外一支「很快就要上市」的 Android 手機，同樣也是採用 OMS 系統，但礙於一些因素，無法多做說明，當然也沒辦法照像了。

<img alt="China Mobile OPhone" src="http://www.jollen.org/blog/2009/05/19/china-mobile-ophone-1.jpg" />
主畫面的部份比 G1 還美觀，整體 UI 給我的感覺很不錯。

<img alt="China Mobile OPhone" src="http://www.jollen.org/blog/2009/05/19/china-mobile-ophone-2.jpg" />
看得出來 OMS 在介面設計上下了一些工夫。

<img alt="China Mobile OPhone" src="http://www.jollen.org/blog/2009/05/19/china-mobile-ophone-3.jpg" />
最特別的地方是 OMS 有「桌面切換」的功能，整體操作性做得不錯。

<img alt="China Mobile OPhone" src="http://www.jollen.org/blog/2009/05/19/china-mobile-ophone-4.jpg" />
某一個選單 UI。

<img alt="China Mobile OPhone" src="http://www.jollen.org/blog/2009/05/19/china-mobile-ophone-5.jpg" />
找了一下，果然沒錯，有導航功能！

<img alt="China Mobile OPhone" src="http://www.jollen.org/blog/2009/05/19/china-mobile-ophone-6.jpg" />
找到了手機電視功能。

<img alt="China Mobile OPhone" src="http://www.jollen.org/blog/2009/05/19/china-mobile-ophone-7.jpg" />
訊息雖然微弱，不過畫面還挺流暢的。

<img alt="China Mobile OPhone" src="http://www.jollen.org/blog/2009/05/19/china-mobile-ophone-8.jpg" />
音樂撥放器。

<img alt="China Mobile OPhone" src="http://www.jollen.org/blog/2009/05/19/china-mobile-ophone-9.jpg" />
雖然是參考設計，不過外觀（ID）做得算不錯。

用過 T-Mobile G1 以及 OPhone 後，總結來看，OPhone 的介面給我的感覺更好：

1. 操作性流暢許多
2. 多桌面（主屏）切換功能比 G1 更加好用
3. 觀看手機電視時畫面非常流暢、介面佈署（UI layout）還不錯 
4. 整體的視覺效果更華麗、畫面更美觀

隨著越來越多的 OPhone 新聞出現，這款由中國自主開發的「O1」頗令人期待，這是 Android 作業系統繼「G1」後，最令人期待的另一個事件。

OPhone 的出現，還代表了一件重要的事情。過去電信營運商，並不掌握手機軟體平臺的技術能力，因此「為自已量身打造」手機軟體、結合自家的服務，並推出實體手機，是一件不容易的事情。如今，藉由「Open Mobile System」的出現，電信營運商能取得開放的手機平臺，並自行發展手機服務應用程式。這是首次，電信營運商能真正掌握整體手機軟體的技術。掌握了電信、用戶、服務與手機軟體等關鍵能力，看來，一些有趣的事情正要開始發生。對於 OPhone 的出線，中國移動扮演了一個重要的角色，身為最重要的電信營運商，此舉必然有登高一呼的效應。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android Porting 手札 #1: Android 移植概觀</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/05/android-porting-introduction.html" />
   <id>tag:www.jollen.org,2009:/blog//2.622</id>
   
   <published>2009-05-10T13:58:29Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary>本週六將於北京舉行的「Android 技術大會」上發表有關「Android 移植」的技術演說，配合該演講，最近將陸續整理一些筆記以搭配講稿供與會朋友參考。 Android 的技術優點 Android 平臺的好處是「將開發者侷限在應用層（application level）」的開發，並透過一個設計良好的 application framework 將 library 層「包裝起來」。傳統 GNU/Linux 系統的「開源模式」是「從裡到外」全面開放，應用程式來自四面八方，每個應用程式底層使用到的 library 並不相同，這讓 Linux 平臺的軟體發展容易失控，造成 Linux distribution 上雖然收錄了豐富的應用程式，但相對的也要包山包海地納入非常多的 shared library。 Android 雖然也採用了其他 open source 的專案成果，但 Android 以很聰明的方式，解決傳統 Linux 開放手機平臺的「相依性」問題，這也是過去長久以來，匯整使用（leverage）開放源碼專案開發產品的大問題。Application framework 採用 Java 程式語言，並軟性的將開發者限制在 application level 是...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本週六將於北京舉行的「Android 技術大會」上發表有關「Android 移植」的技術演說，配合該演講，最近將陸續整理一些筆記以搭配講稿供與會朋友參考。

<strong>Android 的技術優點</strong>

Android 平臺的好處是「將開發者侷限在應用層（application level）」的開發，並透過一個設計良好的 application framework 將 library 層「包裝起來」。傳統 GNU/Linux 系統的「開源模式」是「從裡到外」全面開放，應用程式來自四面八方，每個應用程式底層使用到的 library 並不相同，這讓 Linux 平臺的軟體發展容易失控，造成 Linux distribution 上雖然收錄了豐富的應用程式，但相對的也要包山包海地納入非常多的 shared library。

Android 雖然也採用了其他 open source 的專案成果，但 Android 以很聰明的方式，解決傳統 Linux 開放手機平臺的「相依性」問題，這也是過去長久以來，匯整使用（leverage）開放源碼專案開發產品的大問題。Application framework 採用 Java 程式語言，並軟性的將開發者限制在 application level 是 Android 解決上述技術難題的一個關鍵。

網路上有著數以萬計的 Free & Open Source Software 專案，而被 Android 採納的 FOSS 專案僅有約 60 個左右，比起傳統 Linux distribution 必須收錄上千個套件的數量來看，Android 未來若能發揚光大，能是扮演「收斂」開源軟體發展模式的推手。

傳統的 Embedded Linux 系統程式基於 GNU libc 以及大量的相依程式庫（library dependencies），因此很容易有「牽一髮而動全身」的問題出現。例如：某一個library的API變動（可能是函數改名或移除）將使得其它程式庫與應用程式執行錯誤，這時就必須修改原始程式碼並重新編譯才能解決問題。

這個問題的主因，是因為 Linux 系統是採取動態程式庫（shared libraries）的機制，程式庫的變更雖然只需要「抽換」掉動態程式庫檔，但是應用程式在執行時，才會產生「無法載入符號」的錯誤，除非是「定期」進行「系統重編譯」，否則很難即時修正此錯誤。

Android 的底層並無太複雜的「程式庫相依」問題，這使得 Android 可以比較容易將系統與 IDE 開發工具做整合。在標準 C 程式庫（C library）方面，Google 則是採用 BSD 授權實作了一份適合手機系統使用的版本，無疑是一個值得稱許的做法。

由上述的分析來看，Android 平臺在系統層（library、kernel）的移植工作將不再花費工程人員大量的時間，同時就系統層的調校工作來看，也能有更具體明確的調校項目。

<strong>移植項目概述</strong>

從 Google 發佈的標準 Android 系統架構圖來說，Application framework 以及 application 二層並沒有重要的移植工作需要進行，以下以系統架構的角度來簡介 Android 移植技術的重要事項。

1. Application

應用程式層並移植的工作需要進行，但是因為 Android 每個版本的 API level 都不一樣，因此需要進行 API 相容性的測試。例如，Android 1.1 的 API level 為 2、Android 1.5 的 API level 為 3，需要根據 Google 發佈的 API change 文件進行 application 的相容性測試。

2. Application Framework

以大方向來看，加入新的 library 時需要擴充 application framework；Android framework 以 JNI 呼叫下一層的 library，但是 application 不直接呼叫 library，因此讓 Android framework 的設計更嚴謹。

3. Library

Android 的「external library」裡包含部份現有的 FOSS 專案成果，有些 library 的實作為 machine-dependent，針對 machine-dependent 的實作必須修改其程式碼。例如，android.media.MediaPlayer 的底層為 OpenCore 程式庫，而 OpenCore 的 MP3 decode 部份演算法以 assembly 實作。

4. Dalvik VM

JNI 與 interpreter 是 Android runtimer（Dalvik VM）的移植重點。新版本的 Cupcake（Android 1.5）在 JNI 的部份加入了 x86 的支援，interpreter 目前則是支援 armv4、armv5te 以及 x86。

5. Bionic

Bionic 是 Android 專屬的小型客製化 C library，主要是由 BSD C library 移植而來。支援 Linux kernel 的重要實作，像是：system call、dynamic linker & loader、thread 等等都是檢查的重點。Bionic 裡有一個 libthread_db 是基於 Linux futexes 的 thread 實作，很適合像是手機這樣的小型系統使用。

6. 其它

Android framework 的實作，部份需要考量硬體的規格，例如：Surface Manager 需要考量是否有 GPU 或硬體加速。但你在 Android application 建立一個 Surface holder 時，若是將 Surface 的類型設定為 SURFACE_TYPE_HARDWARE，就必須針對硬體加速與 DMA 做移植工作。

<strong>小結</strong>

Android 平臺的移植技術仍屬重要，主要的技術能力著重於 Android framework（例如：加入新的 external library）以及 Linux device driver 上。本次 Android 技術大會除了介紹 Android 移植的重點（highlights）以及具體實作方向外，也會展示近期的小小實作成果。

雖然一開始提到，Android 平臺的好處是「將開發者侷限在應用層（application level）」的開發，但是 Android framework 與 Android 移植的能力仍然重要，畢竟這是直接影響產品開發的關鍵力之一。

]]>
      
   </content>
</entry>
<entry>
   <title>Android Day 活動紀錄：Android 應用程式新手入門訓練</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/05/android-day-event-report.html" />
   <id>tag:www.jollen.org,2009:/blog//2.621</id>
   
   <published>2009-05-06T15:20:18Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary> 上週六（5/2）舉辦「Android Day」訓練活動，上午的活動是「Android 的機會」議程，下午舉辦了一場免費的 Android 訓練課程。Android Day 訓練活動的目的除了希望可以認識朋友，並面對面與大家交換不同的想法外，也希望可以幫助對 Android 應用程式有興趣的朋友，能一天就入門 Android 應用程式設計。對於想初步了解 Android 應用程式設計方法的朋友相當有幫助；透過 Android Day 訓練課程希望能幫助大家節省一開始的自學時間。 上午的議程，由小弟我、高煥堂老師與 David（gOS 執行長）以自由論壇形式，與大家討論 Android 產品端與推廣方面的想法。由於 Android 的 middleware 技術（包含調校、移植等）對產品的發展是一個重要的技術能力，因此高煥堂老師提出一個 shared object（shared library）工作小組的計畫，此外，高老師也針對 middleware 的觀念做了一些說明；David 也從「授權」的角度來分析，為什麼採用 APL（Apache License）授權的 Android 平臺，比起過去以 GPL 授權為主的桌面 Linux 與...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<a href="http://www.androidday.com" target="_blank"><img alt="android-day-banner.jpg" src="http://www.jollen.org/blog/2009/05/08/android-day-banner.jpg" width="630" height="292" border="0" /></a>

上週六（5/2）舉辦「<a href="http://www.androidday.com">Android Day</a>」訓練活動，上午的活動是「Android 的機會」議程，下午舉辦了一場免費的 Android 訓練課程。Android Day 訓練活動的目的除了希望可以認識朋友，並面對面與大家交換不同的想法外，也希望可以幫助對 Android 應用程式有興趣的朋友，能一天就入門 Android 應用程式設計。對於想初步了解 Android 應用程式設計方法的朋友相當有幫助；透過 Android Day 訓練課程希望能幫助大家節省一開始的自學時間。

<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/dZvElmQiR7I&hl=zh_TW&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/dZvElmQiR7I&hl=zh_TW&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>

上午的議程，由小弟我、高煥堂老師與 David（gOS 執行長）以自由論壇形式，與大家討論 Android 產品端與推廣方面的想法。由於 Android 的 middleware 技術（包含調校、移植等）對產品的發展是一個重要的技術能力，因此高煥堂老師提出一個 shared object（shared library）工作小組的計畫，此外，高老師也針對 middleware 的觀念做了一些說明；David 也從「授權」的角度來分析，為什麼採用 APL（Apache License）授權的 Android 平臺，比起過去以 GPL 授權為主的桌面 Linux 與 Mobile Linux 有更好的商業機會，以及更多元的商業模式。

在推廣方面，現場討論到了亞太地區的分工與交流。日本與韓國對於 Android 技術的參與熱度並不比台灣低，因此如何善用台灣「硬體設計」的優勢，並結合 Android 設計服務，來創造新的機會，成為當天討論的一個想法。

下午則是由小弟主講的「Android 應用程式新手入門訓練」訓練活動，由於現場大部份的朋友都沒有安裝 Eclipse + Android Development Toolkit 的經驗，因此一開始利用一些時間，介紹 Android 開發環境的安裝方式；在主要課程方面，則是以「<a href="http://www.jollen.org/blog/2009/04/android-day-package-v1.html">Android Day Package -- Android 應用程式新手入門</a>」講義與範例做為教材，介紹 Android 應用程式的主要觀念（例如：Activity、View 等）。希望這種形式的活動，對大家入門 Android 有幫助。

下週（5/16-17）將在上海與北京舉行的第一屆 Android 技術大會，將會與日本與韓國的專家現場進行討論，這次的技術大會，除了介紹一些重要的 Android 技術議題外，也會是讓大家交流與互動的好場合。]]>
      
   </content>
</entry>
<entry>
   <title>Android Netbook 行不行：從產品角度來思考</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/04/android_netbook_product_concept.html" />
   <id>tag:www.jollen.org,2009:/blog//2.619</id>
   
   <published>2009-04-19T07:05:43Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary>社群開發者將Android移植到EeePC後，興起一股「Android小筆電」討論風潮。Android小筆電的概念就是這樣來的；由開發者給市場的一個考題。市場上一陣Android小筆電產品的新聞，幾家品牌大廠，對Android小筆電市場更是磨刀霍霍。對於這陣Android小筆電的風潮要如何解讀？在此分享個人的觀察與想法，請不吝指教。 Android小筆電的熱潮，起之於玩家對技術的好奇心；對於Android小筆電產品的討論，則是廠商與使用者的期待與想像。從技面的角度來看，Android小筆電仍有使用介面（UI）上的疑慮，尚不足以產品化。由於Android介面的設計預設對象為手機，因此在小筆電上的畫面表現較不理想，操作方面亦同。Android小筆電上仍有技術缺口。 基於「應用程式」概念的小筆電，因是「使用習性」的問題，使用者還是喜歡微軟的作業系統，Linux小筆電還是佔不到便宜。 使用者免不了將Linux小筆電與微軟系統的小筆電拿來相提並論。Linux上有OpenOffice辦公軟體，但微軟系統有使用者更習慣的Office套裝軟體；Linux上有Thunderbird電子郵件軟體，但微軟系統有使用者更習慣的Outlook軟體；無論是上網、電子郵件還是即時通訊，Linux小筆電上的「應用程式」都讓使用者操作得很沒有安全感。 從另外一個角度來思考。 基於「網路服務」概念的Android平臺，因為與微軟系統的小筆電有很大的差異性，因此似乎存在不錯的機會。Android平臺不基於Linux桌面技術，我們沒有辦法將OpenOffice軟體，或是Firefox瀏覽器安裝在Android小筆電上，正好與現有的小筆電有很大的差異性，也給了新產品定位的大空間。 產品定位方面，把Android做為取代微軟系統或Linux桌面的想法，反而讓Android小筆電失去了這個差異性；當大家開始討論Android小筆電上能不能執行辦公室軟體時，誰知道，會不會又像Linux小筆電產品般的結果。 Android平臺的產品可以擁有更多的區隔性，因此機會之一是尋找或創造不同的產品「使用概念」。現階段Android小筆電仍處於技術玩票性質，這是由玩家帶起的概念。要讓Android小筆電產品化仍要補齊技術上的不足。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      社群開發者將Android移植到EeePC後，興起一股「Android小筆電」討論風潮。Android小筆電的概念就是這樣來的；由開發者給市場的一個考題。市場上一陣Android小筆電產品的新聞，幾家品牌大廠，對Android小筆電市場更是磨刀霍霍。對於這陣Android小筆電的風潮要如何解讀？在此分享個人的觀察與想法，請不吝指教。

Android小筆電的熱潮，起之於玩家對技術的好奇心；對於Android小筆電產品的討論，則是廠商與使用者的期待與想像。從技面的角度來看，Android小筆電仍有使用介面（UI）上的疑慮，尚不足以產品化。由於Android介面的設計預設對象為手機，因此在小筆電上的畫面表現較不理想，操作方面亦同。Android小筆電上仍有技術缺口。

基於「應用程式」概念的小筆電，因是「使用習性」的問題，使用者還是喜歡微軟的作業系統，Linux小筆電還是佔不到便宜。

使用者免不了將Linux小筆電與微軟系統的小筆電拿來相提並論。Linux上有OpenOffice辦公軟體，但微軟系統有使用者更習慣的Office套裝軟體；Linux上有Thunderbird電子郵件軟體，但微軟系統有使用者更習慣的Outlook軟體；無論是上網、電子郵件還是即時通訊，Linux小筆電上的「應用程式」都讓使用者操作得很沒有安全感。

從另外一個角度來思考。

基於「網路服務」概念的Android平臺，因為與微軟系統的小筆電有很大的差異性，因此似乎存在不錯的機會。Android平臺不基於Linux桌面技術，我們沒有辦法將OpenOffice軟體，或是Firefox瀏覽器安裝在Android小筆電上，正好與現有的小筆電有很大的差異性，也給了新產品定位的大空間。

產品定位方面，把Android做為取代微軟系統或Linux桌面的想法，反而讓Android小筆電失去了這個差異性；當大家開始討論Android小筆電上能不能執行辦公室軟體時，誰知道，會不會又像Linux小筆電產品般的結果。

Android平臺的產品可以擁有更多的區隔性，因此機會之一是尋找或創造不同的產品「使用概念」。現階段Android小筆電仍處於技術玩票性質，這是由玩家帶起的概念。要讓Android小筆電產品化仍要補齊技術上的不足。
      
   </content>
</entry>
<entry>
   <title>出現搭載 Android 平臺的 PMP 產品</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/04/movit_mini_android_pmp.html" />
   <id>tag:www.jollen.org,2009:/blog//2.618</id>
   
   <published>2009-04-19T06:30:08Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary>LinuxDevices.com 報導了一則很酷的消息 [Android-based PMP to ship in October]。 一家名為 [GiiNii] 的公司，將在 10 月份開始銷售使用 Android 平臺的 PMP（portable media player）；該公司在明年的 1 月份也會銷售 Android 平臺的 DPF（digital picture frame）。 （圖片來源：GiiNii） 這台名為 Movit Mini 的 PMP 實際上就是一個「MID」概念的產品，但 GiiNii 並不將 Movit Mini 稱為 MID，而是將它定位為 PMP。Movit Mini...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[LinuxDevices.com 報導了一則很酷的消息 [<a href="http://linuxdevices.com/news/NS3193160405.html">Android-based PMP to ship in October</a>]。 一家名為 [<a href="http://www.giinii.com/movit_detail.html" target="_blank">GiiNii</a>] 的公司，將在 10 月份開始銷售使用 Android 平臺的 PMP（portable media player）；該公司在明年的 1 月份也會銷售 Android 平臺的 DPF（digital picture frame）。

<img src="http://www.giinii.com/images/products/Lrg/movit/Lrg_Movit-mini-blk-angle-home.jpg" />
（圖片來源：GiiNii）

這台名為 Movit Mini 的 PMP 實際上就是一個「MID」概念的產品，但 GiiNii 並不將 Movit Mini 稱為 MID，而是將它定位為 PMP。Movit Mini 不同於市面的泛 MID 產品，GiiNii 重新做了產品定位：

1. 外觀更輕薄，這意味著 Movit Mini 比 MID 更具攜帶性（mobile）

2. 螢幕尺吋更小，傳統的 MID 是 4.8 吋，Movit Mini 縮小為 4.3 吋

3. 畫面解析度降為 480x272 

不管是 PMP 或 MID，因為都具備觸控螢幕的功能，因此比 Netbook 更適合搭載 Android。報導中也指出，Movit Mini 因為使用 Android 平臺，因此這是一個具備「能存取 Google apps」的 PMP，頗為有趣的產品。

現今的 MID 大多使用 Intel Moblin 平臺（處理器當然使用 Intel 自已的 Atom），因此除了 UI 方面的差異外，似乎比較難表現 MID 本身的產品差異性，當然產品定位也就比較「搖晃」一點。
]]>
      
   </content>
</entry>
<entry>
   <title>「Android Day Package -- Android 應用程式新手入門」</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/04/android-day-package-v1.html" />
   <id>tag:www.jollen.org,2009:/blog//2.617</id>
   
   <published>2009-04-12T03:46:32Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary>「Android Day Package -- Android 應用程式新手入門」整理了這陣子我在研討會的演講材料，包含： 簡報一份 Android 入門教學文件共11集 範例程式4例 因為研討會是一天的演講活動，因此這些內容很適合新手做為「學習 Android 應用程式」的入門教材，大約只需要一天的時間，就能初步了解 Android 的開發工具使用，並了解 Android 的應用程式模式，故取名為「Android Day Package」，期望能提供一個「Android 新手一天入門」的教學套件。請不吝指教。 簡報的部份是受零組件雜誌邀請，進行一天的 Android 演講活動，所特別製作的簡報；範例則是參考 Android SDK 所撰寫的實例，範例是配搭簡報進行實例講解所使用的程式碼。[下載 Android Day Package] 後，可搭配以下共11份教學文件學習；以下的教學文件是為製作簡報時的筆記，特別整理成一份教學文件與大家分享。 課程主題 Android Day Package 提供以下的課程主題。 1. 開放手機平台發展現況 (1hr) ‧開放手機平台陣營 ‧授權模式比較...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>「Android Day Package -- Android 應用程式新手入門」整理了這陣子我在研討會的演講材料，包含：</p>
<ol>
	<li>簡報一份</li>
	<li>Android 入門教學文件共11集</li>
	<li>範例程式4例</li>
</ol>
<p>因為研討會是一天的演講活動，因此這些內容很適合新手做為「學習 Android 應用程式」的入門教材，大約只需要一天的時間，就能初步了解 Android 
的開發工具使用，並了解 Android 的應用程式模式，故取名為「Android Day Package」，期望能提供一個「Android 
新手一天入門」的教學套件。請不吝指教。</p>
<p>簡報的部份是受零組件雜誌邀請，進行一天的 Android 演講活動，所特別製作的簡報；範例則是參考 Android SDK 
所撰寫的實例，範例是配搭簡報進行實例講解所使用的程式碼。[<a href="http://tw.jollen.org/android/android-day-v1.zip">下載 
Android Day Package</a>] 後，可搭配以下共11份教學文件學習；以下的教學文件是為製作簡報時的筆記，特別整理成一份教學文件與大家分享。</p>
<p><b>課程主題</b></p>

Android Day Package 提供以下的課程主題。

1. 開放手機平台發展現況 (1hr)
‧開放手機平台陣營 
‧授權模式比較 
‧市場現況 
‧行銷與推廣策略 

2. Android 入門 (1.5hr)
‧安裝 SDK 
‧Android模擬器 
‧Android開發工具 (ADT) 
‧Android除錯工具 (ADB) 
‧Hierarchy Viewer 

3. Android應用程式模式 (2hr)
‧Android Framework 
‧Activity 
‧Service 
‧BroadcastReceiver 
‧Process types 
‧Views, ViewGroup 
‧Design Screen 
‧AndroidManifest.xml 
‧Intents 

4. Android應用程式開發 (1hr)
‧Hello, Moko 範例程式 
‧Openmoko Neo FreeRunner手機安裝 
‧安裝 apk套件 
‧使用 Neo FreeRunner實機展示 

<p><b>Android 教學</b></p>
<a name="top">
<ul class="archive-list">
	<li class="archive-list-item">2009.01.19: </a>
	<a href="http://www.jollen.org/blog/2009/01/jollen-android-programming-11.html">
	Jollen 的 Android 教學,#11: AndroidManifest.xml 的用途是什麼？</a> </li>
	<li class="archive-list-item">2009.01.19:
	<a href="http://www.jollen.org/blog/2009/01/jollen-android-programming-10.html">
	Jollen 的 Android 教學,#10: 如何檢查 Service 是否已啟動？使用 Android 除錯器</a> </li>
	<li class="archive-list-item">2009.01.12:
	<a href="http://www.jollen.org/blog/2009/01/jollen-android-programming-9.html">
	Jollen 的 Android 教學,#9: 啟動 Service - startService()</a> </li>
	<li class="archive-list-item">2009.01.12:
	<a href="http://www.jollen.org/blog/2009/01/jollen-android-programming-8.html">
	Jollen 的 Android 教學,#8: 沒有 UI 的 Service</a> </li>
	<li class="archive-list-item">2009.01.08:
	<a href="http://www.jollen.org/blog/2009/01/jollen-android-programming-7.html">
	Jollen 的 Android 教學,#7: 如何讓文字並排顯示 - TableLayout</a> </li>
	<li class="archive-list-item">2009.01.05:
	<a href="http://www.jollen.org/blog/2009/01/jollen-android-programming-6.html">
	Jollen 的 Android 教學,#6: WebView 體驗與 findViewByID</a> </li>
	<li class="archive-list-item">2009.01.04:
	<a href="http://www.jollen.org/blog/2009/01/jollen-android-programming-5.html">
	Jollen 的 Android 教學,#5: 使用 View 的 XML 屬性</a> </li>
	<li class="archive-list-item">2009.01.04:
	<a href="http://www.jollen.org/blog/2009/01/jollen-android-programming-4.html">
	Jollen 的 Android 教學,#4: 使用 XML 安排 UI</a> </li>
	<li class="archive-list-item">2008.12.29:
	<a href="http://www.jollen.org/blog/2008/12/jollen-android-programming-3.html">
	Jollen 的 Android 教學,#3: 第一個 Android 專案</a> </li>
	<li class="archive-list-item">2008.12.29:
	<a href="http://www.jollen.org/blog/2008/12/jollen-android-programming-2.html">
	Jollen 的 Android 教學,#2: “Hello Moko” - Activity 與 View 的關係</a> </li>
	<li class="archive-list-item">2008.12.29:
	<a href="http://www.jollen.org/blog/2008/12/jollen-android-programming-1.html">
	Jollen 的Android 教學,#1: Android 應用程式模式</a> </li>
</ul>

Revision: 2009/04/19]]>
      
   </content>
</entry>
<entry>
   <title>Linux Input Device 介紹: APIs</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/04/linux_input_device_apis.html" />
   <id>tag:www.jollen.org,2009:/blog//2.616</id>
   
   <published>2009-04-08T04:18:51Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary>Linux 的 Input Device 是重要的一個 subsystem，在進行實例介紹前，先大略了解一下相關的 API。 Linux Input Device ﻿input.c是Linux的”input”驅動程式，主要支援鍵盤與滑鼠的輸入；input.c介面有趣的地方是採用了事件（event）的方式來處理輸入，以下是input.c介面重要的資料結構與函數： * struct input_dev * void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) * void input_register_device(struct input_dev *); * void input_unregister_device(struct input_dev *); * void input_register_handler(struct...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Linux Device Drivers &amp; Kernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Linux 的 Input Device 是重要的一個 subsystem，在進行實例介紹前，先大略了解一下相關的 API。

<strong>Linux Input Device</strong>

﻿input.c是Linux的”input”驅動程式，主要支援鍵盤與滑鼠的輸入；input.c介面有趣的地方是採用了事件（event）的方式來處理輸入，以下是input.c介面重要的資料結構與函數：

* struct input_dev
* void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
* void input_register_device(struct input_dev *);
* void input_unregister_device(struct input_dev *);
* void input_register_handler(struct input_handler *);
* void input_unregister_handler(struct input_handler *);

Linux 的input機制可用來實作「虛擬鍵盤」或「虛擬滑鼠」，只要呼叫input_event()將輸入資料發佈給input handler即可。

struct input_dev是用來描述輸入事件的重要資料結構，其原型宣告如下：

<div>
struct input_dev {

	void *private;

	int number;
	char *name;
	unsigned short idbus;
	unsigned short idvendor;
	unsigned short idproduct;
	unsigned short idversion;

	unsigned long evbit[NBITS(EV_MAX)];
	unsigned long keybit[NBITS(KEY_MAX)];
	unsigned long relbit[NBITS(REL_MAX)];
	unsigned long absbit[NBITS(ABS_MAX)];
	unsigned long mscbit[NBITS(MSC_MAX)];
	unsigned long ledbit[NBITS(LED_MAX)];
	unsigned long sndbit[NBITS(SND_MAX)];
	unsigned long ffbit[NBITS(FF_MAX)];
	int ff_effects_max;

	unsigned int keycodemax;
	unsigned int keycodesize;
	void *keycode;

	unsigned int repeat_key;
	struct timer_list timer;

	int abs[ABS_MAX + 1];
	int rep[REP_MAX + 1];

	unsigned long key[NBITS(KEY_MAX)];
	unsigned long led[NBITS(LED_MAX)];
	unsigned long snd[NBITS(SND_MAX)];

	int absmax[ABS_MAX + 1];
	int absmin[ABS_MAX + 1];
	int absfuzz[ABS_MAX + 1];
	int absflat[ABS_MAX + 1];

	int (*open)(struct input_dev *dev);
	void (*close)(struct input_dev *dev);
	int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
	int (*upload_effect)(struct input_dev *dev, struct ff_effect *effect);
	int (*erase_effect)(struct input_dev *dev, int effect_id);

	struct input_handle *handle;
	struct input_dev *next;
};
</div>

<strong>定義按鍵</strong>

我們可以設定struct input_dev裡的evbit欄位，來定義所要接受的輸入類型，目前共有8種輸入類型如下：

* EV_KEY：Keys and buttons（按鍵與按鈕）。
* EV_REL：Relative axes（相對座標）。
* EV_ABS：Absolute axes（絕對座標）。
* EV_MSC：Misc events（其它事件）。
* EV_LED：LEDs。
* EV_SND：Sounds（聲音輸入）。
* EV_REP：Autorepeat values（自動重覆數值）。
* EV_FF：Force feedback事件。

以下是一個範例，我們指定dev可接受EV_KEY事件：

dev.evbit[0] = BIT(EV_KEY);

evbit是一個陣列，每個元素可以索引一種輸入類型。每種輸入類型均可指定特定的輸入資料，例如：TAB鍵。指定方式是使用set_bit()或BIT巨集來設定每種輸入類型的陣列。以下是各輸入類型的欄位名稱：

* keybit[NBITS(KEY_MAX)]：Keys and buttons（按鍵與按鈕）。
* relbit[NBITS(REL_MAX)]：Relative axes（相對座標）。
* absbit[NBITS(ABS_MAX)]：Absolute axes（絕對座標）。
* mscbit[NBITS(MSC_MAX)]：Misc events（其它事件）。
* ledbit[NBITS(LED_MAX)]：LEDs。
* sndbit[NBITS(SND_MAX)]：Sounds（聲音輸入）。
* ffbit[NBITS(FF_MAX)]：Force feedback事件。

以下是使用set_bit()的範例：

* set_bit(KEY_UP,    dev.keybit);
* set_bit(KEY_LEFT,  dev.keybit);

或是使用BIT巨集也可以：

* keybit[0] = BIT(KEYUP) | BIT(KEY_LEFT);

input.h裡做位元運算的3個巨集如下：

* NBITS(x)：計算要幾個陣列元素，才夠紀錄第x個位元。
* BIT(x)：傳回單獨第x個位元為1時所代表的數值，例如：x=0時為0x1，x=1時為0x2，x=2時為0x4。
* LONG(x)：第x個位元是屬於第幾個陣列元素（即索引值）。

我們先設定驅動程式能接受EV_KEY事件，然後指定EV_KEY事件的特定輸入值為KEY_UP與KEY_LEFT按鍵。不同事件的輸入資料定義，請參考input.h檔，例如以下是EV_KEY事件的按鍵1~按鍵9定義：

/*
 * Keys and buttons
 */

#define KEY_1			2
#define KEY_2			3
#define KEY_3			4
#define KEY_4			5
#define KEY_5			6
#define KEY_6			7
#define KEY_7			8
#define KEY_8			9
#define KEY_9			10

設定好struct input_dev後再呼叫input_register_device()註冊至上層。當”input device”註冊至kernel後，當該input device被開啟時，便呼叫input device的open method；當input device關閉時，便呼叫input device的close method。
實作input device的open method時，若成功應傳回0，失敗的話則傳回任意的非零值；close method則不須傳回值。

<strong>Report 按鍵</strong>

使用者的按鍵往上層回報所使用的API如下：

* input_report_key(struct input_dev *dev, unsigned int code, int value);
* input_report_rel(struct input_dev *dev, unsigned int code, int value);
* input_report_abs(struct input_dev *dev, unsigned int code, int value);
* input_report_key與input_report_rel其實都是使用input_event()的巨集，input_event()的函數原型與參數說明如下：
* void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);

* @dev：指向input device的指標。
* @type：輸入類型（EV_KEY、EV_ABS等）。
* @code：輸入按鍵（例如EV_KEY的KEY_1）。
* @value：按鍵值。

<strong>Input Handler</strong>

任何的按鍵輸入，都應呼叫input_event()來將input event送到input.c，再由input.c分派事件（遶送）到每一個”input handler”。有註冊input handler的驅動程式，都能讀取輸入資料。
]]>
      
   </content>
</entry>
<entry>
   <title>CTimes 矽導論壇：行動通訊產業 - 看中國崛起與市場機會</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/04/android_phone_china_market.html" />
   <id>tag:www.jollen.org,2009:/blog//2.614</id>
   
   <published>2009-04-01T09:25:50Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary>（原文刊載於零組件雜誌2009年3月份） 近來讀到幾則報導二零零九年移動通信大會的新聞，提到中國在手機產業中，營造了一股崛起的氣氛，有些人更直接了當提出中國手機產業崛起的看法。從產品角度來看，中國在這次大會的產品展示，幾乎涵蓋了所有產品線，可想見中國在手機產業的研發能量頗為驚人。以中興通訊來說，其自主研發的手機產品線，己經涵蓋了各種作業系統，以及三端手機（中階、高階與低階），顯見其產品線的佈局頗為完整。 中國的華為也成功進入全球幾家主要的電信營運商，同時目前也是部份地區的主要供應商之一，可見中國手機產業也具備了電信營運商模式的能力。開放式手機平臺對中國在國際業務的拓業，也會有正向的幫助。二零零八年全球GSM手機出貨排名，華為以24.4%的佔有率排名第二，己經超過 Nokia。華為在移動通信大會上也展示了使用 Android 平臺的手機，因此在結合網路服務與應用客製化方面，華為做足了準備，有機會透過 Android 手機拓業國際市場。 中國的禹華通信近期也推出了 Android 手機的參考設計，這個參考設計採用 Marvell PXA-310 平臺，這是除了 Qualcomm 外的另一個 Android 手機參考平臺。禹華通信的 Android 手機平臺也有客戶採用了。現在，中國許多手機廠商陸續備齊了完整的 Android 設計平臺，只要 Android 應用程式的研發能量能到位，或是能善加利用 Android 開發者社群的資源的利用，未來中國手機製造商（ODM）在 Android 客製化手機的市場，會有一定的競爭力。 至於中國本地的 Android 手機市場機會在哪裡，以下就過去與中國業者的往來，整理一些資訊與大家分享。 目前，2G 的 Android 手機（GPRS/EDGE）在中國市場部份，短期還是會有不錯的市場需求，特別與業者合作的客製化手機部份，特別被看好。支援 Android 的 2G 手機參考平臺也相對完善，例如上述提及，禹華通信推出的參考設計，就是屬於 GPRS/EDGE...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      （原文刊載於零組件雜誌2009年3月份）
 
近來讀到幾則報導二零零九年移動通信大會的新聞，提到中國在手機產業中，營造了一股崛起的氣氛，有些人更直接了當提出中國手機產業崛起的看法。從產品角度來看，中國在這次大會的產品展示，幾乎涵蓋了所有產品線，可想見中國在手機產業的研發能量頗為驚人。以中興通訊來說，其自主研發的手機產品線，己經涵蓋了各種作業系統，以及三端手機（中階、高階與低階），顯見其產品線的佈局頗為完整。 

中國的華為也成功進入全球幾家主要的電信營運商，同時目前也是部份地區的主要供應商之一，可見中國手機產業也具備了電信營運商模式的能力。開放式手機平臺對中國在國際業務的拓業，也會有正向的幫助。二零零八年全球GSM手機出貨排名，華為以24.4%的佔有率排名第二，己經超過 Nokia。華為在移動通信大會上也展示了使用 Android 平臺的手機，因此在結合網路服務與應用客製化方面，華為做足了準備，有機會透過 Android 手機拓業國際市場。

中國的禹華通信近期也推出了 Android 手機的參考設計，這個參考設計採用 Marvell PXA-310 平臺，這是除了 Qualcomm 外的另一個 Android 手機參考平臺。禹華通信的 Android 手機平臺也有客戶採用了。現在，中國許多手機廠商陸續備齊了完整的 Android 設計平臺，只要 Android 應用程式的研發能量能到位，或是能善加利用 Android 開發者社群的資源的利用，未來中國手機製造商（ODM）在 Android 客製化手機的市場，會有一定的競爭力。

至於中國本地的 Android 手機市場機會在哪裡，以下就過去與中國業者的往來，整理一些資訊與大家分享。

目前，2G 的 Android 手機（GPRS/EDGE）在中國市場部份，短期還是會有不錯的市場需求，特別與業者合作的客製化手機部份，特別被看好。支援 Android 的 2G 手機參考平臺也相對完善，例如上述提及，禹華通信推出的參考設計，就是屬於 GPRS/EDGE 的規格。Openmoko 的 GTA02（Neo FreeRunner）本身也是 2G 規格，目前也有多家加值應用開發商（Value-Added Reseller）在詢問採用的可行性，當然軟體部份考慮的是 Android 平臺，而非 Openmoko 本身的軟體。

在 3G 手機部份，許多人認為 3G 在幾年內勢必成為市場主流，屆時 2G 手機將會進一步降價，因此 2G 手機本身的利潤空間也會比較壓縮。Android 手機在 3G 的市場，則是需要比較多的資源整合，以及可行的商業模式，這是 Android 手機研發業者的主要挑戰。

針對 Android 平臺的  3G 手機，中國本土的市場機會之一是 TD-SCDMA 系統。原因是，TD-SCDMA 雖是 4 大 3G 標準之一，但起步較晚，成熟度也較低。以這個角度來看，TD-SCDMA 系統的 Android 3G 手機，仍有待研發資源的投入，因此有一個切入的機會點。以市場角度來看，中國最大電信商中國移動也投入不少研發資金在 TD-SCDMA 的手機研發；TD-SCDMA 目前的主要問題之一就是終端裝置，由此來看，終端裝置開發商會有許多取得中國移動支持的機會。
      
   </content>
</entry>
<entry>
   <title>CTimes 矽導論壇：Android 手機 - 邁向心理效應的轉折點</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/03/android_phone_boost_business.html" />
   <id>tag:www.jollen.org,2009:/blog//2.613</id>
   
   <published>2009-03-30T15:51:13Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary>不確定因素消散 G2延伸氣勢 趨勢即將確立（原文刊載於零組件雜誌2009年2月份） 最近一則有關Android的最新消息是，T-Mobile 即將在五月份開始銷售 G2 手機，對 Android 平臺來說，這是一個具實質意義的里程碑，代表者 Android 手機的氣勢與話題將再延續。從現在看過去，T-Mobile 的 G1 手機帶來的意義，它並不只是全球第一支 Google 手機，更成功扮演了開路者（帶路者）的角色。 回顧過去，一開始，大家都在謠傳 Google 即將推出自己的手機，並進軍行動通訊產業，但後來 Google 在一場正式的記者會上宣佈成立 OHA 並釋出 Android 平臺後，大家才又恍然大悟，原來 Google 推的一個開放平臺，而不是 Google 手機。針對開放開放平臺來說，開發者社群期待的是一個開放源始碼（open source）的平臺，因此一開始非完全開放源始碼的 Android 便開始受到一些質疑。Google 的反應夠快，在去年（二零零八年）的6月2日便發表了一則聲明，宣稱「Android 將會 100% 開放源碼」，果然，在10月22日，Google 便正式公開了 Android 的完整原始碼。 Google...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      不確定因素消散 G2延伸氣勢 趨勢即將確立（原文刊載於零組件雜誌2009年2月份）

最近一則有關Android的最新消息是，T-Mobile 即將在五月份開始銷售 G2 手機，對 Android 平臺來說，這是一個具實質意義的里程碑，代表者 Android 手機的氣勢與話題將再延續。從現在看過去，T-Mobile 的 G1 手機帶來的意義，它並不只是全球第一支 Google 手機，更成功扮演了開路者（帶路者）的角色。

回顧過去，一開始，大家都在謠傳 Google 即將推出自己的手機，並進軍行動通訊產業，但後來 Google 在一場正式的記者會上宣佈成立 OHA 並釋出 Android 平臺後，大家才又恍然大悟，原來 Google 推的一個開放平臺，而不是 Google 手機。針對開放開放平臺來說，開發者社群期待的是一個開放源始碼（open source）的平臺，因此一開始非完全開放源始碼的 Android 便開始受到一些質疑。Google 的反應夠快，在去年（二零零八年）的6月2日便發表了一則聲明，宣稱「Android 將會 100% 開放源碼」，果然，在10月22日，Google 便正式公開了 Android 的完整原始碼。

Google 的策略相當靈活。Android 雖然是一個開放源碼的平臺，但是卻採取有別於傳統 Linux 手機平臺的授權策略。簡單來說，以 Apache 2.0 授權授出的 Android 平臺，允許電信商（carrier）與 OEM 保留原始碼，也就是 Google 不能保證這些廠商也會公開自己的 Android 版本原始碼，對應用程式來說也相當同，「不保證應用程式開發商也會公佈其原始程式碼」。這樣的授權策略無疑是比過去的 GPL 授權更加「商業友善」。

分食 Android 商機似乎成為一個全球運動，在 Android 平臺上開發應用程式，以及電信服務的客制化，成為一個很好的商業模式。從過去的 Android Developer Challenge 大賽作品來分析，Google 與 OHA 從 1788 個參賽者，挑選出 50 個決選者，而大部份的決選作品，都是基於 GPS 與 Google Maps 開發應用程式，其次則是 social networking。顯見大家的看法有很高的共同點。獨立軟體開發商（ISV）也開始推出 Android 平臺的軟體，或是軟體開發套件（SDK），例如一家名叫 Skyhook Wireless 便推出了移植到 Android 上的定位軟體開發套件（geo-positioning）。從這些現象觀察到，過去開發者所專注的平臺（middleware）技術開發，現在己經被 Android 轉移到應用程式（application）與服務整合開發上了。

從近來的報導或是分析報告來看，各界對 Android 手機的商機都是看好的，這與大家過去對 Android 抱持許多不確定性的看法，己經有了很大的不同。做為領頭羊的角色的 G1 手機功不可沒，G1 為大家做了很好的心理建設。因為它的成功，讓大家對 Android 手機充滿信心，也看到了許多商業機會。G2 若能再交出漂亮成績單，所產生的心理效應想必相當驚人。

      
   </content>
</entry>
<entry>
   <title>CTimes 矽導論壇：Android元年 vs 山寨機氣象變化元年</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/02/android_china_business_opportunities.html" />
   <id>tag:www.jollen.org,2009:/blog//2.610</id>
   
   <published>2009-02-26T13:28:02Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary>誰能掌握山寨機的新商業元素，誰就能逐鹿中原。（原文刊載於零組件雜誌2009年1月份） Android與山寨機的關係，是一個特別另人感興趣的話題。最近實地與北京Androidin社群核心成員交換許多想法，有些觀點很值得台灣硬體廠商參考，筆者就一些討論，整理出部份觀察心得與大家交流。 Android在中國地區投下一顆能量彈，這可能是一顆破壞力驚人的炸彈，不過，最可能的地方是它具備「定向精確爆破」的能力。山寨機的成功，讓不管是本地，或是外來的廠商，都打著「山寨模式」的主意。山寨模式在大陸地區出現快三年的時間，在中國本地的銷售數字為一億台，這還不包括「外銷」到海外的數量。這段期間，中國幾家山寨機廠商，也在短短時間內，一躍成為前幾大的本土品牌手機商。 山寨商的腦筋動得快，現在更把主意打到Android上頭。根據山寨商的說法，Android在中國地區會是一個很好的機會，也就是「智能型Android山寨機」將是下一個山寨風潮。與Android社群合作開發Android系統，是山寨商近來特別感興趣的項目。 根據Androidin（中國本地最大Android社群）的說法，已經有幾家山寨商表示對Android智能手機的興趣，同時也希望能與中國本土Android社群合作，開發不同市場需求的軟體，並針對特定市場做銷售。這也正式開放手機平臺最大的優勢，根據客戶需求彈性並快速客製化軟體的「市場定向爆破」能力。 Android社群在大陸地區越活躍，相對的「Android山寨機」就更有機會。過去由晶片廠商提供完整山寨機軟硬體解決方案的模式，將會逐漸轉變為由社群提供Android山寨機軟硬體解決方案。軟體方面，就不需要多說了，以Androidin社群為例，其社群研發能量，以及社群的人員成份，都非常有實力。以硬體來說，社群需要的是開放式的硬體平臺，因為社群人員需要在此平臺上優化Linux核心，才能提出效能穩定的解決方案。 這樣的變化與市場機會，對台灣廠商來說是很好的轉型機會。若是山寨商接受了Android社群提出的解決方案，那麼品牌硬體就會是一個發展方向，因為在操作系統與軟體可以由使用者任意更新（更換）的情況之下，一個受社群、山寨商以及使用者信賴的手機裝置，就會具有相當的潛力。 在研發方面，硬體廠商確實需要即早建立Linux核心與驅動程式的研發能力。大陸地區有許多具備Linux核心開發能力的社群以及開發者。山寨機廠商的強項是在銷售以及通路，因此研發的工作則是落在晶片供應商，或是Android社群上，這就是大家所知道的「山寨機模式」。 與傳統山寨機相比，Android山寨機需要一些不同的元素，誰能掌握這些元素，誰就能逐鹿中原。 （作者為Androidin台灣地區連絡人，連絡信箱：jollen@androidin.com）...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="我的觀點" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      誰能掌握山寨機的新商業元素，誰就能逐鹿中原。（原文刊載於零組件雜誌2009年1月份）

Android與山寨機的關係，是一個特別另人感興趣的話題。最近實地與北京Androidin社群核心成員交換許多想法，有些觀點很值得台灣硬體廠商參考，筆者就一些討論，整理出部份觀察心得與大家交流。

Android在中國地區投下一顆能量彈，這可能是一顆破壞力驚人的炸彈，不過，最可能的地方是它具備「定向精確爆破」的能力。山寨機的成功，讓不管是本地，或是外來的廠商，都打著「山寨模式」的主意。山寨模式在大陸地區出現快三年的時間，在中國本地的銷售數字為一億台，這還不包括「外銷」到海外的數量。這段期間，中國幾家山寨機廠商，也在短短時間內，一躍成為前幾大的本土品牌手機商。

山寨商的腦筋動得快，現在更把主意打到Android上頭。根據山寨商的說法，Android在中國地區會是一個很好的機會，也就是「智能型Android山寨機」將是下一個山寨風潮。與Android社群合作開發Android系統，是山寨商近來特別感興趣的項目。

根據Androidin（中國本地最大Android社群）的說法，已經有幾家山寨商表示對Android智能手機的興趣，同時也希望能與中國本土Android社群合作，開發不同市場需求的軟體，並針對特定市場做銷售。這也正式開放手機平臺最大的優勢，根據客戶需求彈性並快速客製化軟體的「市場定向爆破」能力。

Android社群在大陸地區越活躍，相對的「Android山寨機」就更有機會。過去由晶片廠商提供完整山寨機軟硬體解決方案的模式，將會逐漸轉變為由社群提供Android山寨機軟硬體解決方案。軟體方面，就不需要多說了，以Androidin社群為例，其社群研發能量，以及社群的人員成份，都非常有實力。以硬體來說，社群需要的是開放式的硬體平臺，因為社群人員需要在此平臺上優化Linux核心，才能提出效能穩定的解決方案。

這樣的變化與市場機會，對台灣廠商來說是很好的轉型機會。若是山寨商接受了Android社群提出的解決方案，那麼品牌硬體就會是一個發展方向，因為在操作系統與軟體可以由使用者任意更新（更換）的情況之下，一個受社群、山寨商以及使用者信賴的手機裝置，就會具有相當的潛力。

在研發方面，硬體廠商確實需要即早建立Linux核心與驅動程式的研發能力。大陸地區有許多具備Linux核心開發能力的社群以及開發者。山寨機廠商的強項是在銷售以及通路，因此研發的工作則是落在晶片供應商，或是Android社群上，這就是大家所知道的「山寨機模式」。

與傳統山寨機相比，Android山寨機需要一些不同的元素，誰能掌握這些元素，誰就能逐鹿中原。

（作者為Androidin台灣地區連絡人，連絡信箱：jollen@androidin.com）
      
   </content>
</entry>
<entry>
   <title>自行編譯 Neo FreeRunner 的 kernel</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/02/compile_neo_freerunner_kernel.html" />
   <id>tag:www.jollen.org,2009:/blog//2.609</id>
   
   <published>2009-02-20T06:02:51Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary>怎麼編譯 Openmoko 的 kernel for Neo FreeRunner 呢？請依照以下步驟進行操作。 1. 取得 Neo FreeRunner 的 kernel 原始碼 Openmoko 專案的所有原始碼都存放於 git.openmoko.org，到 [Openmoko 的 kernel 原始碼目錄樹] 底下，可以看到裡頭有完整的 kernel 原始碼，以及開發中的分支。首先執行以下指令，將所有的 kernel 原始碼取出： $ git clone git://git.openmoko.org/git/kernel.git linux-2.6 所有的原始碼都被放置於 linux-2.6/ 目錄下。 2. 取出 Andy 的 branch...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[怎麼編譯 Openmoko 的 kernel for Neo FreeRunner 呢？請依照以下步驟進行操作。

<strong>1. 取得 Neo FreeRunner 的 kernel 原始碼</strong>

Openmoko 專案的所有原始碼都存放於 git.openmoko.org，到 [<a href="http://git.openmoko.org/?p=kernel.git;a=summary">Openmoko 的 kernel 原始碼目錄樹</a>] 底下，可以看到裡頭有完整的 kernel 原始碼，以及開發中的分支。首先執行以下指令，將所有的 kernel 原始碼取出：

$ git clone git://git.openmoko.org/git/kernel.git linux-2.6

所有的原始碼都被放置於 linux-2.6/ 目錄下。

<strong>2. 取出 Andy 的 branch</strong>

Andy 是 Openmoko 的 kernel 開發者，我們想要使用的是開發中的版本，就要取出 Andy 的分支。Openmoko 的 kernel 開發者，會隨時將新程式碼放置於開發中的版本。Openmoko 的 kernel 也會與 mainline 的 kernel 做合併（patch merge）的動作。取出 Andy branch 的指令如下：

$ cd linux-2.6
$ git checkout origin/andy-tracking

<strong>3. 取得 GTA02 的 kernel 設定檔</strong>

Openmoko 提供 GTA01/GTA02/GTA03 的 kernel 設定檔，只要將 GTA02（Neo FreeRunner）的設定檔取出使用即可，不需要再自行設定 kernel 選項：

$ cp arch/arm/configs/gta02_moredrivers_defconfig .config

<strong>4. 取得 Openmoko 的 toolchain</strong>

要編譯 kernel 就需要 cross toolchain，Openmoko 提供一份預先建立好的 ARM9 toolchain，請由 [<a href="http://downloads.openmoko.org/developer/toolchains/" target="_blank">這裡</a>] 下載。請下載 20080916 的版本，例如：openmoko-i686-20080916-arm-linux-gnueabi-toolchain.tar.bz2。

Toolchain 的安裝方式是先切換到根目錄（'/'），再解壓縮：

$ cd /
$ sudo tar jxf &lt;your-path&gt;/openmoko-i686-20080916-arm-linux-gnueabi-toolchain.tar.bz2

解壓後，可以在 /usr/local/openmoko 目錄下找到 toolchain。

<strong>5. 下載 build-kernel.sh/build-image.sh/mkimage</strong>

到 [<a href="http://people.openmoko.org/jollen/openmoko-kernel/">這裡</a>] 下載二個 script 以及 mkimage 工具，並放置於 kernel 原始碼目錄下。別忘了變更屬性為可執行：

$ chmod a+x build-*.sh

另外，將 mkimage 變更屬性後，搬移到系統標準路徑下：

$ chmod a+x mkimage
$ sudo mv mkimage /usr/sbin

Neo FreeRunner 使用 U-Boot 開機程式，所以必須使用 mkimage 工具將 kernel image 包裝成 U-Boot 格式。此工具的原始碼於 U-Boot 原始碼目錄裡可取得。

<strong>6. 開始編譯 kernel</strong>

先執行 build-kernel.sh 編譯 kernel：

$ ./build-kernel.sh

編譯成功後，再執行 build-image.sh 以產生最後的 image 檔：

$ ./build-image.sh

完成後，可在 kernel 原始碼目錄下找到 'uImage-GTA02.bin' 檔案。uImage-GTA02.bin 就是支援 Neo FreeRunner 的 kernel image 檔，將此檔案以 dfu-util 燒錄到手機裡即可。

以上過程若有任何問題，可以到 [<a href="http://openmoko-tw.net">Openmoko 正體中文站</a>] 詢問。]]>
      
   </content>
</entry>
<entry>
   <title>Fyp：LXDE 與 FreeRunner</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/02/fyp_lxde_freerunner.html" />
   <id>tag:www.jollen.org,2009:/blog//2.608</id>
   
   <published>2009-02-19T04:17:38Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary>過去 Debian 的使用者可以將 [Debian for FreeRunner] 安裝在 FreeRunner 上，並安裝 LXDE 享用輕量級的桌面環境。現在有一個基於 Debian for FreeRunner 的新 distribution 己經將 LXDE 正式整合進來了。 源自台灣，現在已是知名的開放源碼專案 [LXDE] 現在已經被 Openmoko 的社群移植到 Neo FreeRunner 了。這個以 LXDE 桌面環境，以及 ［Zhone] 為基礎的新 distribution 稱為 [Fyp]，以下是 Fyp 的實機畫面。 (圖片來源：Openmoko Wiki） Zhone 全名是...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[過去 Debian 的使用者可以將 [<a href="http://wiki.openmoko.org/wiki/Debian">Debian for FreeRunner</a>] 安裝在 FreeRunner 上，並安裝 LXDE 享用輕量級的桌面環境。現在有一個基於 Debian for FreeRunner 的新 distribution 己經將 LXDE 正式整合進來了。

源自台灣，現在已是知名的開放源碼專案 [<a href="http://lxde.org">LXDE</a>] 現在已經被 Openmoko 的社群移植到 Neo FreeRunner 了。這個以 LXDE 桌面環境，以及 ［<a href="http://wiki.openmoko.org/wiki/Zhone">Zhone</a>] 為基礎的新 distribution 稱為 [<a href="http://wiki.openmoko.org/wiki/Fyp">Fyp</a>]，以下是 Fyp 的實機畫面。

<img src="http://wiki.openmoko.org/images/4/4e/Fyp3.png" />
(圖片來源：Openmoko Wiki）

Zhone 全名是 Zen Phone，也就是「禪之手機程式」。Zhone 是一個簡單的撥號與簡訊收發程式，Zhone 基於 [<a href="http://www.freesmartphone.org">FSO</a>] 的應用程式框架，全部採用 Python 撰寫。一個手機的撥號軟體，也可以做得這麼簡約有內涵，或許正是「禪之手機程式」所要表達的意境。

不過根據 [<a href="http://bbs.androidin.com/viewthread.php?tid=3485&extra=page%3D1">大陸網友的實測</a>]，Fyp 在 FreeRunner 上比較難以操作，原因是使用手指觸控，比較難以操作傳統的桌面環境與應用程式：「除了zhone这个大大的界面外，其他的程序用手指简直无法操作」。因為 FreeRunner 的觸控螢幕只有 2.8 吋，所以應該幾乎很難以手指進行操作；但從這個使用者的角度來看，客製化桌面環境的應用，在未來的消費性裝置就是一個重要的技術了。目前市面上有許多小筆電（Netbook）也引進了客製化桌面的技術，讓使用者能更方便操作系統。]]>
      
   </content>
</entry>
<entry>
   <title>二零零九年十大 Linux 與 open source 發展預測、Openmoko 新武器</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/02/predictions_linux_opensource_2009_openmoko.html" />
   <id>tag:www.jollen.org,2009:/blog//2.606</id>
   
   <published>2009-02-05T07:41:15Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary>幾天前，一則新聞「2009 年 Linux 與 open source 十大預測」指出，Android 將會大放異采。報導原文可見 [10 predictions for Linux and open source in 2009]，另外，這裡也有一份簡體中文版的報導 [2009年Linux和开源软件的10大预测]。 十大事件預測的第一名是 Android，報導推測指出，2009 年將是 Android 重要的一年。文中也提到 Openmoko 的 GTA02（Neo FreeRunner）也會採用 Android 系統。對於 FreeRunner 採用 Android 系統的話題，網路上有許多討論，不過簡單來說，移植 Android 到 FreeRunner 上是社群進行的一個專案，而將 FreeRunner 搭載 Android...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[幾天前，一則新聞「2009 年 Linux 與 open source 十大預測」指出，Android 將會大放異采。報導原文可見 [<a href="http://www.e-linux.it/news_detail.php?id=7731">10 predictions for Linux and open source in 2009</a>]，另外，這裡也有一份簡體中文版的報導 [<a href="http://tech.sina.com.cn/s/2009-02-05/08112794801.shtml">2009年Linux和开源软件的10大预测</a>]。

十大事件預測的第一名是 Android，報導推測指出，2009 年將是 Android 重要的一年。文中也提到 Openmoko 的 GTA02（Neo FreeRunner）也會採用 Android 系統。對於 FreeRunner 採用 Android 系統的話題，網路上有許多討論，不過簡單來說，移植 Android 到 FreeRunner 上是社群進行的一個專案，而將 FreeRunner 搭載 Android 進行市場推廣與銷售，則是行銷端的一個想法。至於未來是否會讓 GTA02 搭載 Android 並推廣到其他市場，則是一個「還不確定」的問題。

此外，Openmoko 仍舊持續在開發自已的 software stack。在 Om2008.8 之後，將起而代之的新版本是 [<a href="http://www.FreeSmartphone.Org">FreeSmartphone.Org</a>] 以及 [<a href="http://www.paroli-project.org/">Paroli</a>]，這是一個基於 [<a href="http://www.enlightenment.org/">Enlightenment</a>] 與 Python 技術的行動通訊平臺，簡單來說，FSO 與 Paroli 將 Python 帶進行動通訊裝置，讓開發者能只用 Python 進行手機軟體發展；新的 FSO/Paroli 底層系統則是採用 Enlightenment 技術。

在十大事件預測報導中的第八名就是 Enlightenment，報導指出「Enlightenment 桌面將會推出穩定版 E17」，可見 Enlightenment 也會是 2009 年受矚目的一個 open source 專案。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#11: AndroidManifest.xml 的用途是什麼？</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/01/jollen-android-programming-11.html" />
   <id>tag:www.jollen.org,2009:/blog//2.605</id>
   
   <published>2009-01-19T14:39:13Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary><![CDATA[AndroidManifest.xml 是一個用來描述 Android 應用程式「整體資訊」的設定檔。簡單來說，這是一個「自我介紹」檔，我們可以向 Android 系統「介紹」我們的 Android 應用程式，以便讓 Android 系統完整地了解我們的應用程式資訊。 在 [教學, #9] 中，我們提及：「在這裡修改 AndroidManifest.xml 的目的是為了『在我們的 Android 應用程式裡加入一個 Service 類別』，這樣才有辦法啟動 Service...」這個工作的目的是為了向 Android 系統做二項自我介紹。說明如下。 1. 應用程式「實作了一個 MokoService 類別」 &lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt; ... &lt;service android:name=".MokoService"&gt; ... &lt;/service&gt; ... &lt;/application&gt; 在 application 標籤裡加入...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[AndroidManifest.xml 是一個用來描述 Android 應用程式「整體資訊」的設定檔。簡單來說，這是一個「自我介紹」檔，我們可以向 Android 系統「介紹」我們的 Android 應用程式，以便讓 Android 系統完整地了解我們的應用程式資訊。

在 [<a href="/blog/2009/01/jollen-android-programming-9.html">教學, #9</a>] 中，我們提及：「在這裡修改 AndroidManifest.xml 的目的是為了『在我們的 Android 應用程式裡加入一個 Service 類別』，這樣才有辦法啟動 Service...」這個工作的目的是為了向 Android 系統做二項自我介紹。說明如下。

1. 應用程式「實作了一個 MokoService 類別」

<pre>    &lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt;
    ...
        &lt;service android:name=".MokoService"&gt;
        ...
        &lt;/service&gt;
    ...
    &lt;/application&gt;</pre>

在 application 標籤裡加入 ‘service’ 標籤，告訴 Android 系統我們的應用程式有一個叫做「MokoService」的類別。「android:name」屬性用來指定 Service 的類別名稱，別忘了在 AndroidManifest.xml 裡，類別名稱都是以「.」（小數點）開始。

2. MokoService 類別可處理「com.moko.hello.START_MUSIC」意圖

<pre>       &lt;service android:name=".MokoService"&gt;
        	&lt;intent-filter&gt;
        		&lt;action android:name="com.moko.hello.START_MUSIC" /&gt;
        		&lt;category android:name="android.intent.category.DEFAULT" /&gt;
        	&lt;/intent-filter&gt;
        &lt;/service&gt;</pre>

在 service 標籤裡加入 ‘intent-filter’ 標籤，告訴 Android 系統我們的應用程式可「濾出」哪一個「Intent」。在前面的教學裡，我們把 Intent 暫時解釋為 Event（事件）；因此，這裡的「自我介紹」用意是為了告訴 Android 系統，我們可接受的事件名稱為何。

我們只要在 intent-filter 標籤裡加入 ‘action’ 標籤，並指定 action 標籤的 android:name 屬性即可。Intent 的命名規則為「xxx.yyy.NAME」的路徑命名法。

當 Android 收到由 Activity 發出的 Intent 後，便去找尋可處理 com.moko.hello.START_MUSIC 的類別，然後載入並啟動此類別。

最後，在 ’intent-filter’ 裡加入 ‘category’ 標籤，用來定義 com.moko.hello.START_MUSIC 的分類，在這裡指定為預設類別 「android.intent.category.DEFAULT」，這是一個 Android 定義的常數。完整的 Service 類別「自我介紹」標籤與屬性，可參考 Android SDK 的說明。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#10: 如何檢查 Service 是否已啟動？使用 Android 除錯器</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/01/jollen-android-programming-10.html" />
   <id>tag:www.jollen.org,2009:/blog//2.604</id>
   
   <published>2009-01-19T02:45:13Z</published>
   <updated>2009-08-05T07:02:40Z</updated>
   
   <summary>Activity 是一個有 UI 的類別，Service 則是一個沒有 UI 的類別。要知道 Activity 是否啟動，只要看看手機是否出現畫面即可；要知道 Service 是否有啟動，最容易的方式就是透過「除錯」的方式。以下我們實際以一個完整專案方式來對 Android 應用程式做除錯。 建立 MokoService 類別 點擊 Eclipse 的 File -&gt; New -&gt; Class 項目，利用 Eclipse 的自動新增功能，在先前的 HelloMoko 專案裡建立 MokoService 類別，如圖1。欄位「Superclass」應填入 android.app.Service。 圖1: 建立 MokoService 類別 修改 MokoService 實作 在新增的...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Activity 是一個有 UI 的類別，Service 則是一個沒有 UI 的類別。要知道 Activity 是否啟動，只要看看手機是否出現畫面即可；要知道 Service 是否有啟動，最容易的方式就是透過「除錯」的方式。以下我們實際以一個完整專案方式來對 Android 應用程式做除錯。

<strong>建立 MokoService 類別</strong>

點擊 Eclipse 的 File -> New -> Class 項目，利用 Eclipse 的自動新增功能，在先前的 HelloMoko 專案裡建立 MokoService 類別，如圖1。欄位「Superclass」應填入 android.app.Service。

<img alt="create_class_eclipse.png" src="http://www.jollen.org/blog/2009/01/19/create_class_eclipse.png" width="525" height="663" />
圖1: 建立 MokoService 類別

<strong>修改 MokoService 實作</strong>

在新增的 MokoService 類別裡，加入 onStart() 與 onDestory() 實作，如圖2。onStart() 的實作如下：

<blockquote><pre>	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
	}</pre></blockquote>

因為 onStart() 是一個負載（override）實作，因此要呼叫 superclass 的 onStart() 方法。接著，將滑鼠移到 MokoService 類別裡的第 17 行（super.onStart），然後點擊 Run -> Toggle Breakpoint 在程式碼第 17 行的地方建立一個中斷點。

<img alt="debug_service_1.png" src="http://www.jollen.org/blog/2009/01/19/debug_service_1.png" width="1280" height="727" />
圖2: onStart() 與 onDestory() 實作與設定中斷點

除了 MokoService 類別外，我們還要修改 AndroidManifest.xml 並在 Activity 裡啟動 MokoService 類別，請參考 [<a href="/blog/2009/01/jollen-android-programming-9.html">教學, #9</a>] 的說明。

<strong>啟動除錯器</strong>

點擊 Run -> Debug Configurations 執行專案，並啟動除錯器。當 Android 應用程式成功安裝到 target device 並執行時， 會出現一個詢問對話框，選 Yes 即可，Eclipse 會將環境切換至除錯模式，如圖3。

<img alt="debug_service_2.png" src="http://www.jollen.org/blog/2009/01/19/debug_service_2.png" width="516" height="211" />
圖3: 是否要切換到除錯模式？

接著可以在除錯模式下看到 Android 應用程式停在先前所設定的中斷點（breakpoint），這表示 MokoService 類別已被 Android 系統載入並執行了，如圖4。

<img alt="debug_service_3.png" src="http://www.jollen.org/blog/2009/01/19/debug_service_3.png" width="1280" height="727" />
圖4: 程式在中斷點暫停]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#9: 啟動 Service - startService()</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/01/jollen-android-programming-9.html" />
   <id>tag:www.jollen.org,2009:/blog//2.603</id>
   
   <published>2009-01-12T08:02:33Z</published>
   <updated>2009-08-05T07:04:36Z</updated>
   
   <summary><![CDATA[上一個課程裡，我們實作了一個 Service 的類別稱為 MokoService，現在我們想要在 Activity 裡載入並啟動 MokoService 類別，讓它可以在背景執行，請依以下步驟完成這個任務。。 修改 AndroidManifest.xml 在 Package Explorer 視窗裡找到目前 Android 專案的資訊描述檔，檔名是 AndroidManifest.xml。這是一個用來描述 Android 應用程式「整體資訊」的檔案，每個 Android 應用程式專案都會有一個。在這裡修改 Androidmanifest.xml 的目的是為了「在我們的 Android 應用程式裡加入一個 Service 類別」，這樣才有辦法啟動 Service。修改後的內容如下，紅色的部份是新增的描述：。 &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.moko.hello" android:versionCode="1" android:versionName="1.0.0"&gt; &lt;application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true"&gt;...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>上一個課程裡，我們實作了一個 Service 的類別稱為 MokoService，現在我們想要在 Activity 裡載入並啟動 MokoService 類別，讓它可以在背景執行，請依以下步驟完成這個任務。。</p>

<strong>修改 AndroidManifest.xml</strong>

<p>在 Package Explorer 視窗裡找到目前 Android 專案的資訊描述檔，檔名是 AndroidManifest.xml。這是一個用來描述 Android 應用程式「整體資訊」的檔案，每個 Android 應用程式專案都會有一個。在這裡修改 Androidmanifest.xml 的目的是為了「在我們的 Android 應用程式裡加入一個 Service 類別」，這樣才有辦法啟動 Service。修改後的內容如下，紅色的部份是新增的描述：。</p>

<blockquote><pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.moko.hello"
      android:versionCode="1"
      android:versionName="1.0.0"&gt;
    &lt;application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true"&gt;
        &lt;activity android:name=".HelloMoko"
                  android:label="@string/app_name"&gt;
            &lt;intent-filter&gt;
                &lt;action android:name="android.intent.action.MAIN" /&gt;
                &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
            &lt;/intent-filter&gt;
        &lt;/activity&gt;
<font color="#ff0000">        &lt;service android:name=".MokoService"&gt;
            &lt;intent-filter&gt;
                &lt;action android:name="com.moko.hello.START_MUSIC" /&gt;
                &lt;category android:name="android.intent.category.DEFAULT" /&gt;
            &lt;/intent-filter&gt;
        &lt;/service&gt;</font>
    &lt;/application&gt;
&lt;/manifest&gt;</pre></blockquote>

<p>這是什麼意思呢？我們留待後續再做說明。接著只需要再加上一行程式碼，就能啟動 MokoService 類別了。</p>

<strong>啟動 Service - startService()</strong>

<p>回到 HelloM 類別，加入一行程式碼：</p>

<blockquote><pre>public class HelloMoko extends Activity {
   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState); 
       
       setContentView(R.layout.main);
       
       <font color="#ff0000">startService(new Intent ("com.moko.hello.START_MUSIC"));</font>
   }
}</pre></blockquote>

<p>Activity 類別裡有一個 method 叫做 startService：</p>

<blockquote>startService(Intent service)</blockquote>

<p>呼叫 startService() 即可啟動一個 Service 類別，只是，startService() 的參數是一個「Intent」的型別，並不是所要啟動的類別名稱。「Intent」是一個很像「Event」的類別，後續我們再做比較精確的說明，在這裡，我們不如把 Intent 當成是 Event（事件）。</p>

<p>當程式送出 com.moko.hello.START_MUSIC 事件給 Android 時，Android 便去尋找能處理此事件的類別，然後啟動它。在這裡，能處理 com.moko.hello.START_MUSIC 事件的類別就是 MokoService，這個關係就是透過 AndroidManifest.xml 的設定實現的。</p>]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#8: 沒有 UI 的 Service</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/01/jollen-android-programming-8.html" />
   <id>tag:www.jollen.org,2009:/blog//2.602</id>
   
   <published>2009-01-12T07:15:49Z</published>
   <updated>2009-08-05T07:04:36Z</updated>
   
   <summary>到目前為止，我們都著重在 Activity 以及 UI 的介紹，在 Android 應用程式裡，有一種沒有 UI 的類別（android.app.Service），稱之為 Service。簡單來說，Service 是一個 background process（背景程序），透過背景程序，我們可以實作一些不需要 UI 的功能，例如：在背景撥放音樂。 以下是利用 Eclipse 環境自動產生的類別 &apos;MokoService&apos;： import android.app.Service; import android.content.Intent; import android.os.IBinder; public class MokoService extends Service { @Override public IBinder onBind(Intent intent) { // TODO Auto-generated...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>到目前為止，我們都著重在 Activity 以及 UI 的介紹，在 Android 應用程式裡，有一種沒有 UI 的類別（android.app.Service），稱之為 Service。簡單來說，Service 是一個 background process（背景程序），透過背景程序，我們可以實作一些不需要 UI 的功能，例如：在背景撥放音樂。</p>

<p>以下是利用 Eclipse 環境自動產生的類別 'MokoService'：</p>

<blockquote><pre>import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MokoService extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

}</pre></blockquote>

<p>MokoService 類別繼承自 android.app.Service，幾個有關 Service 的重要觀念如下：</p>

<p>1. Service 物件以 separated process 的方式執行，這表示 Service 與 UI（Activity）並不在同一個 process 裡執行，而是個自在不同的 process 執行。</p>

<p>2. Android 應用程式是在 Activity 裡啟動與停止 Service。</p>

<p>3. 覆載（override）onStart() 方法（method）在 Service 被啟動時，執行我們想要的背景功能。</p>

<p>4. 覆載 onDestroy() 方法在 Service 被停止時，停止執行中的背景功能。</p>

<p>以下是一個加入 onStart 與 onDestroy 的  MokoService 實作：</p>

<blockquote><pre>import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MokoService extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}
	
	@Override
	public void onStart(Intent intent, int startId) {
		
	}
	
	@Override
	public void onDestroy() {
		
	}
}</pre></blockquote>

目前，我們了解 Activity 與 Service 的觀念了，接下來，要怎麼在 Activity 裡啟動 Service 呢？]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#7: 如何讓文字並排顯示 - TableLayout</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/01/jollen-android-programming-7.html" />
   <id>tag:www.jollen.org,2009:/blog//2.601</id>
   
   <published>2009-01-08T08:51:57Z</published>
   <updated>2009-08-05T07:04:36Z</updated>
   
   <summary>android.widget.TableLayout 是一個「排版」的類別，假設現在我們想要做出如圖1的文字排版效果，那麼使用 TableLayout 就是標準的做法。傳統寫程式排版的做法不是非常的方便，所以我們將採用 XML layout 方式來實作。 圖1: 文字並排顯示 建立新專案: HelloLayout 建立新的專案「HelloLayout」，並撰寫程式碼如下： package com.moko.layout; import com.moko.layout.R; import android.app.Activity; import android.os.Bundle; public class HelloLayout extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState)...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p><a href="http://code.google.com/intl/zh-TW/android/reference/android/widget/TableLayout.html" target="_blank">android.widget.TableLayout</a> 是一個「排版」的類別，假設現在我們想要做出如圖1的文字排版效果，那麼使用 TableLayout 就是標準的做法。傳統寫程式排版的做法不是非常的方便，所以我們將採用 XML layout 方式來實作。</p>

<img alt="TableLayout_1.png" src="http://www.jollen.org/blog/2009/01/08/TableLayout_1.png" width="900" height="752" />
<p>圖1: 文字並排顯示</p>

<strong>建立新專案: HelloLayout</strong>

<p>建立新的專案「HelloLayout」，並撰寫程式碼如下：</p>

<pre>package com.moko.layout;

import com.moko.layout.R;

import android.app.Activity;
import android.os.Bundle;

public class HelloLayout extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}</pre>

<p>由於我們採用 XML layout 的做法，所以主程式不需要做什麼修改。本範例的重點應該是在 main.xml 檔案的編寫。</p>

<strong>設計 TableLayout: 編寫 main.xml</strong>

<p>新的 Android 專案創建時，預設是使用 LinearLayout（線性排版）來安排 UI。現在，我們將使用 TableLayout 來取代 LinearLayout，以「表格」方式來安排 UI。TableLayout 讓我們可以將畫面切割成一張表格，如果我們可以設計一個二欄式（2 columns）的表格，就可以做出如圖1的顯示效果了。</p>

<p>以下是 main.xml 的內容：</p>

<pre>&lt;?xml version="1.0" encoding="utf-8"?>

&lt;TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"&gt;

	&lt;TableRow&gt;
		&lt;TextView  
		    android:layout_width="fill_parent" 
		    android:layout_height="wrap_content" 
		    android:text="www.androidin.com"
		    android:padding="3dip"
		    android:autoLink="web" /&gt;
		&lt;TextView  
		    android:layout_width="fill_parent" 
		    android:layout_height="wrap_content" 
		    android:text="www.google.com"
		    android:autoLink="web" /&gt;
	&lt;/TableRow>

&lt;/TableLayout&gt;</pre>

<p><a href="http://code.google.com/intl/zh-TW/android/reference/android/widget/TableRow.html" target="_blank">android.widget.TableRow</a> 是配合 TableRow 使用的一個類別，當我們在 TableLayout 裡安排一個 TableRow 時，在 TableRow「裡頭的所有 View」就會被安排在同一列（row）裡。以本範例來說，在第一列（row）裡有二個 TextView，所以這二行文字顯示時，就會呈現如圖1的效果。</p>

<p>為了避免文字擠在一起，因此我們在 TextView 裡加上了 padding 的屬性，如下：</p>

		    android:padding="3dip"

<p>第一個 TextView 的 padding 為 3dip，表示與旁邊的 View 必須空 3 個「間格」，這樣二個 TextView 才不會擠在一起。</p>



]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#6: WebView 體驗與 findViewByID</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/01/jollen-android-programming-6.html" />
   <id>tag:www.jollen.org,2009:/blog//2.600</id>
   
   <published>2009-01-05T15:08:43Z</published>
   <updated>2009-08-05T07:04:36Z</updated>
   
   <summary>如果要繼續體驗 View 的樂趣，那麼「WebView」這個 View 無疑是最佳人選。android.webkit.WebView 是使用「WebKit」技術的 View，主要的用途是「顯示網頁」。使用 WebView，我們可以在 Android 應用程式裡顯示自已的 HTML 文件，或是線上的網頁。 接下來請依照以下步驟，建立我們的第二個 Android 應用程式「Hello Web」。 建立新專案: HelloWeb 建立一個新的 Android 專案，如圖1。 圖1: 建立 Hello Web 專案 並且撰寫 HelloWeb.java 程式如下： package com.moko.web; import android.app.Activity; import android.os.Bundle; import android.webkit.WebView; import com.moko.web.R; public...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>如果要繼續體驗 View 的樂趣，那麼「WebView」這個 View 無疑是最佳人選。android.webkit.WebView 是使用「WebKit」技術的 View，主要的用途是「顯示網頁」。使用 WebView，我們可以在 Android 應用程式裡顯示自已的 HTML 文件，或是線上的網頁。</p>

<p>接下來請依照以下步驟，建立我們的第二個 Android 應用程式「Hello Web」。</p>


<strong>建立新專案: HelloWeb</strong>

<p>建立一個新的 Android 專案，如圖1。</p>

<img alt="hello_web_1.png" src="http://www.jollen.org/blog/2009/01/05/hello_web_1.png" width="525" height="508" /><br />
圖1: 建立 Hello Web 專案

<p>並且撰寫 HelloWeb.java 程式如下：</p>

<pre>package com.moko.web;

import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;

import com.moko.web.R;

public class HelloWeb extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
<strong>        final String mimetype = "text/html";
        final String encoding = "utf-8";
        
        WebView wv;
        
        wv = (WebView) findViewById(R.id.wv);
        wv.loadData("&lt;img src=\"http://www.google.com.tw/intl/en_com/images/logo_plain.png\" /&gt;", mimetype, encoding);</strong>
    }
}</pre>

<p>上述程式碼採用 XML layout 方式來安排 UI，因此接下來的工作就是編輯 XML layout 檔案。</p>


<strong>規劃 UI: main.xml</strong>

<p>編輯 main.xml 來規劃「Hello Web」的 UI 如下：</p>

<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;

&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    &gt;
<strong>&lt;WebView 
	android:layout_width="fill_parent" 
	android:layout_height="wrap_content" 
	android:id="@+id/wv" 
	/&gt;</strong>
&lt;/LinearLayout&gt;</pre>

<p>在這裡我們定義了「WebView」標籤，並且指定「WebView」的 ID 為「wv」。透過指定「ID」屬性給 View 的方式，便能「讓 Android 應用程式在執行時期（run-time）找到指定的 View 物件」。</p>


<strong>使用 View 的 ID 屬性: findViewByID</strong>

<p>怎麼在執行時期，找到「XML layout」安排好的 View 呢？看到 HelloWeb.java 的程式片斷如下：</p>

<pre>        final String mimetype = "text/html";
        final String encoding = "utf-8";
        
        WebView wv;
        
        <strong>wv = (WebView) findViewById(R.id.wv);</strong>
        wv.loadData("&lt;img src=\"http://www.google.com.tw/intl/en_com/images/logo_plain.png\" /&gt;", mimetype, encoding);</pre>

<p>呼叫 findViewByID() 方法，即可在執行時期「動態取得 View 物件」。當我們在 main.xml 裡加入 WebView 標籤，「存檔」後，R.java 資源索引檔也會跟著更新，我們可透過「R.id.wv」來索引到 WebView 物件。以下是 R.java 的內容：</p>

<pre>package com.moko.web;

public final class R {
    public static final class attr {
    }
    public static final class drawable {
        public static final int icon=0x7f020000;
    }
<strong>    public static final class id {
        public static final int wv=0x7f050000;
    }</strong>
    public static final class layout {
        public static final int main=0x7f030000;
    }
    public static final class string {
        public static final int app_name=0x7f040001;
        public static final int hello=0x7f040000;
    }
}</pre>

<p>取得 WebView 物件後，呼叫 WebView 的 loadData() 方法，將 HTML 內容載入到 WebView 物件裡，並顯示在 Activity 上。loadData() 的參數如下：</p>

<ul><li>第一個參數：HTML 內容</li>
<li>第二個參數：MimeType 類型，指定為 text/html，即 HTML 類型文件</li>
<li>第三個參數：文字編碼方法，指定為 utf-8（Unicode）</li></ul>

<p>Hello Web 範例程式所載入的 HTML 文件是一個 &lt;IMG&gt; 標籤，因此我們在視窗上所看到的內容就是一張圖檔，如下圖（使用真正的 Google Phone 做測試）。</p>

<img alt="hello_web_2.png" src="http://www.jollen.org/blog/2009/01/05/hello_web_2.png" width="308" height="466" /><br />
圖: Hello Web 執行結果。]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#5: 使用 View 的 XML 屬性</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/01/jollen-android-programming-5.html" />
   <id>tag:www.jollen.org,2009:/blog//2.599</id>
   
   <published>2009-01-04T14:49:52Z</published>
   <updated>2009-08-05T07:04:36Z</updated>
   
   <summary>上一篇文章介紹了 XML-based layout 後，發現這是一個很方便，而且有用的 UI 安排方式。以圖1為例，我們現在想要做出一個應用程式，讓文字的超鍊結（hyperlink）可以被使用者點選，並自動呼叫瀏覽器連到該網站，這樣的應用程式該如何撰寫呢？請依以下步驟修改程式碼。 圖1：如何設計一個可點擊 URL link 的應用程式？ View 的 XML 屬性 每一個 View 都有許多屬性，我們可以利用 XML 來描述每一個 View 的屬性，進而達到控制物件的效果。以 TextView 為例，有一個「android:autoLink」屬性可以控制「是否要自動將網址轉換為可點擊的 URL 文字」。 要怎麼知道每一個 View 都哪些屬性呢？這個時候就要祭出 Android SDK 的 documentation 了。以 TextView 為例，透過以下的說明，可以了解 TextView 有哪些屬性，以及該屬性的用途： http://code.google.com/intl/zh-TW/android/reference/android/widget/TextView.html#attr_android:autoLink 原來，只需要透過「autoLink」屬性，並將此屬性設定為「web」即可做出我們想要的功能。 修改...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[上一篇文章介紹了 XML-based layout 後，發現這是一個很方便，而且有用的 UI 安排方式。以圖1為例，我們現在想要做出一個應用程式，讓文字的超鍊結（hyperlink）可以被使用者點選，並自動呼叫瀏覽器連到該網站，這樣的應用程式該如何撰寫呢？請依以下步驟修改程式碼。

<img alt="xml_layout_attributes_1.png" src="http://www.jollen.org/blog/2009/01/04/xml_layout_attributes_1.png" width="900" height="752" />
圖1：如何設計一個可點擊 URL link 的應用程式？

<strong>View 的 XML 屬性</strong>

每一個 View 都有許多屬性，我們可以利用 XML 來描述每一個 View 的屬性，進而達到控制物件的效果。以 TextView 為例，有一個「android:autoLink」屬性可以控制「是否要自動將網址轉換為可點擊的 URL 文字」。

要怎麼知道每一個 View 都哪些屬性呢？這個時候就要祭出 Android SDK 的 documentation 了。以 TextView 為例，透過以下的說明，可以了解 TextView 有哪些屬性，以及該屬性的用途：

<a href="http://code.google.com/intl/zh-TW/android/reference/android/widget/TextView.html#attr_android:autoLink">http://code.google.com/intl/zh-TW/android/reference/android/widget/TextView.html#attr_android:autoLink</a>

原來，只需要透過「autoLink」屬性，並將此屬性設定為「web」即可做出我們想要的功能。

<strong>修改  main.xml</strong>

將 main.xml 修改如下：

<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"    
    &gt;
&lt;TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
<strong>    android:text="Jollen's Blog - http://www.jollen.org/blog"
    android:autoLink="web"</strong>
    /&gt;
&lt;/LinearLayout&gt;</pre>

我們為 TextView 物件新增一個「android:autoLink」的屬性，並將此屬性設定為「web」，以後只要「text」屬性裡出現 URL，TextView 就會自動將 URL「文字」轉換成可點擊的 link。

程式執行時，只要點擊 link，就會自動啟動瀏覽器，並連接該網址，如下圖。

<img alt="xml_layout_attributes_2.png" src="http://www.jollen.org/blog/2009/01/04/xml_layout_attributes_2.png" width="900" height="752" />]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#4: 使用 XML 安排 UI</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2009/01/jollen-android-programming-4.html" />
   <id>tag:www.jollen.org,2009:/blog//2.598</id>
   
   <published>2009-01-04T14:22:04Z</published>
   <updated>2009-08-05T07:04:36Z</updated>
   
   <summary><![CDATA[繼上一篇文章介紹了 View 的觀念後，接下來就要了解一下如何「安排」Android 應用程式的 layout。 Android 應用程式的 layout（UI 佈局）除了直接撰寫程式碼的方式外，也能使用 XML 檔案來做描述（XML-based Layout）。在 Android Development Kit 的「Package Explorer」視窗，點選「res -> layout」選擇 main.xml，可以看到 “Hello Moko” 應用程式的 XML layout 檔案，如圖1。 圖1："Hello Moko" 的 XML layout 檔 以下這段 XML 用來描述「TextView」物件的 layout： &lt;TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello"...]]></summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>繼上一篇文章介紹了 View 的觀念後，接下來就要了解一下如何「安排」Android 應用程式的 layout。</p>

<p>Android 應用程式的 layout（UI 佈局）除了直接撰寫程式碼的方式外，也能使用 XML 檔案來做描述（XML-based Layout）。在 Android Development Kit 的「Package Explorer」視窗，點選「res -> layout」選擇 main.xml，可以看到 “Hello Moko” 應用程式的 XML layout 檔案，如圖1。</p>

<img alt="xml_layout_1.png" src="http://www.jollen.org/blog/2009/01/04/xml_layout_1.png" width="1194" height="729" />
圖1："Hello Moko" 的 XML layout 檔

<p>以下這段 XML 用來描述「TextView」物件的 layout：</p>

<pre>&lt;TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    /&gt;</pre>

以上述的例子來看，我們可以設定以下幾個 tag 來定義 TextView 的屬性：

- 'android:layout_width' - View 的寬度
- 'android:layout_height' - View 的高度
- 'android:text' - TextView 所要顯示的文字

到上一篇文章為止所撰寫的「Hello Moko」是以程式碼編寫的方式來安排 UI，要怎麼將 Hello Moko 改以 XML 做為 UI 的安排方式呢？請依照以下步驟進行程式調整。

<strong>R.java: 資源索引檔</strong>

在 Package Explorer 點選「src -> com.moko.hello -> R.java」，如圖2。

<img alt="xml_layout_2.png" src="http://www.jollen.org/blog/2009/01/04/xml_layout_2.png" width="1194" height="729" />
圖2："Hello Moko" 的 R.java

R.java 是由 Android Development Kit 所自動產生的資源索引檔（resource index），「R」是一個類別，這是 Android 應用程式資源的索引類別。「R.layout」類別則是 UI 佈局的索引類別，R.layout 類別裡的「main」成員就是 Android 應用程式的「主佈局索引」。

<strong>修改 Hello Moko 程式碼</strong>

R.java 根據 main.xml 自動產生，「並不是由程式設計師手動編寫」，請勿修改此檔案。接下來，只要把先前的程式（HelloMoko.java）修改成下列寫法即可：

<pre>public class HelloMoko extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
       <strong> setContentView(R.layout.main);</strong>
	}
}</pre>

<p>當 Activity 被建立後，我們呼叫 setContentView() 方法，將主要的 UI（R.layout.main）顯示在視窗上。R.layout.main 索引到一個 TextView 物件，此物件定義於 main.xml。將 R.layout.main 顯示在 Activity 視窗上，請記得修改程式碼，才能使用 XML-based layout。

<p>我們順帶將 TextView 物件的 text 屬性修改如下：</p>

<pre>&lt;TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Hello TextView"
    /&gt;</pre>

<img alt="xml_layout_3.png" src="http://www.jollen.org/blog/2009/01/04/xml_layout_3.png" width="1194" height="729" />

程式執行結果如下（使用 Android 模擬器）。

<img alt="xml_layout_4.png" src="http://www.jollen.org/blog/2009/01/04/xml_layout_4.png" width="900" height="752" />]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#3: 第一個 Android 專案</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/12/jollen-android-programming-3.html" />
   <id>tag:www.jollen.org,2008:/blog//2.587</id>
   
   <published>2008-12-29T12:13:25Z</published>
   <updated>2009-08-05T07:04:36Z</updated>
   
   <summary>初步了解如何撰寫第一個 Android 應用程式後，接著就可以實際來建立我們的第一個 Android 專案了。Android Development Kit（ADT）使用 Eclipse 整合式開發環境，根據 Android SDK 裡的文件說明，先安裝 Eclipse 以及 ADT，然後建立一個新專案（File -&gt; New -&gt; Project），並選擇「Android Project」，如圖1。 圖1：建立 Android Project 接著輸入專案屬性： 1. Package name：Java 套件名稱，在這裡我們將應用程式的套件命名為 com.moko.hello。 2. Activity name：輸入應用程式的 Activity 類別名稱，建立一個繼承 Activity 的新類別。 3. Application name：輸入應用程式名稱，即應用程式標題。 圖2：輸入專案屬性...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[初步了解如何撰寫第一個 Android 應用程式後，接著就可以實際來建立我們的第一個 Android 專案了。Android Development Kit（ADT）使用 Eclipse 整合式開發環境，根據 Android SDK 裡的文件說明，先安裝 Eclipse 以及 ADT，然後建立一個新專案（File -> New -> Project），並選擇「Android Project」，如圖1。

<img alt="new_project_1.png" src="http://www.jollen.org/blog/2008/12/29/new_project_1.png" width="525" height="500" />
圖1：建立 Android Project

接著輸入專案屬性：

1. Package name：Java 套件名稱，在這裡我們將應用程式的套件命名為 com.moko.hello。
2. Activity name：輸入應用程式的 Activity 類別名稱，建立一個繼承 Activity 的新類別。
3. Application name：輸入應用程式名稱，即應用程式標題。

<img alt="new_project_2.png" src="http://www.jollen.org/blog/2008/12/29/new_project_2.png" width="525" height="508" />
圖2：輸入專案屬性

建立新專案後，在主程式 HelloMoko.java 撰寫第一個 Android 應用程式如圖3。第一個 Android 應用程式在 Activity 上顯示一個 View。

<img alt="new_project_3.png" src="http://www.jollen.org/blog/2008/12/29/new_project_3.png" width="1194" height="729" />
圖3：第一個 Android 應用程式

設計好的應用程式可以使用 Android 模擬器來執行。Android Development Kit 也將 Android 實體手機整合在開發環境裡，因此，我們實際以 T-Mobile G1 手機（全球第一支 Google phone）來做測試。

選取 Run -> Run Configurations 後，可以看到圖4的設定選單。在「Project:」欄位選取「Browse...」選取我們的 Android 專案 - HelloMoko，然後點選「Apply」套用設定。

<img alt="new_project_4.png" src="http://www.jollen.org/blog/2008/12/29/new_project_4.png" width="800" height="640" />
圖4：設定 Run Configurations

接著點選「Target」標籤，將「Device Target Selection Mode」設定為「Manual」，然後點選「Run」執行 Android 專案。在執行專案前，請先將手機連接到電腦。

<img alt="new_project_5.png" src="http://www.jollen.org/blog/2008/12/29/new_project_5.png" width="800" height="640" />
圖5：設定 Target

最後，可以看到圖6的畫面，Android Development Kit 會自動偵測 Android 手機。選取手機後按「OK」，Android Development Kit 就會自動編譯專案，並將應用程式打包成 apk 套件後下載到手機上執行。

除了 G1 手機外，Openmoko 的 Neo FreeRunner 也能執行 Android 系統，Android Development Kit 也能偵測到 Neo FreeRunner 並自動將套件下載到 Neo FreeRunner 上安裝執行。

<img alt="new_project_6.png" src="http://www.jollen.org/blog/2008/12/29/new_project_6.png" width="500" height="300" />
圖6：選擇 Android 手機

在 Eclipse 的訊息窗裡，可以看到 apk 套件的下載、安裝以及執行過程的完整訊息：

<pre>[2008-12-29 16:51:29 - HelloMoko] ------------------------------
[2008-12-29 16:51:29 - HelloMoko] Android Launch!
[2008-12-29 16:51:29 - HelloMoko] adb is running normally.
[2008-12-29 16:51:29 - HelloMoko] Launching: com.moko.hello.HelloMoko
[2008-12-29 16:51:32 - HelloMoko] Uploading HelloMoko.apk onto device 'HT843GZ46367'
[2008-12-29 16:51:32 - HelloMoko] Installing HelloMoko.apk...
[2008-12-29 16:51:35 - HelloMoko] Success!
[2008-12-29 16:51:35 - HelloMoko] Starting activity com.moko.hello.HelloMoko on device 
[2008-12-29 16:51:36 - HelloMoko] ActivityManager: Starting: Intent { comp={com.moko.hello/com.moko.hello.HelloMoko} }</pre>

<strong>延伸閱讀</strong>

* 2008.11.21: <a href="http://www.jollen.org/blog/2008/11/hello_moko_free_runner_android.html">安裝 Android 應用程式（apk）至 Neo FreeRunner</a>]]>
      
   </content>
</entry>
<entry>
   <title>Jollen 的 Android 教學,#2: “Hello Moko” - Activity 與 View 的關係</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/12/jollen-android-programming-2.html" />
   <id>tag:www.jollen.org,2008:/blog//2.586</id>
   
   <published>2008-12-29T12:04:21Z</published>
   <updated>2009-08-05T07:04:36Z</updated>
   
   <summary>上一則文章介紹了 Activity 與 View 的觀念，若能再理解 Activity 與 View 的關係，就不難了解 Android 應用程式的整個模式了。請看以下的範例程式： package com.moko.hello; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class HelloMoko extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) {...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>上一則文章介紹了 Activity 與 View 的觀念，若能再理解 Activity 與 View 的關係，就不難了解 Android 應用程式的整個模式了。請看以下的範例程式：</p>

<pre>package com.moko.hello;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class HelloMoko extends Activity {
   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);

       TextView tv = new TextView(this);
       tv.setText("Hello Moko");
       setContentView(tv);
   }
}</pre>

<p>這是在 Android SDK 文件裡的一段範例程式，類別 HelloAndroid 繼自 Activity。下圖是Activity的生命週期（lifecycle）。在「Jollen 的 Android 教學,#1」裡提到 Activity 負責建立視窗，根據 Activity lifecycle，當視窗建立時，onCreate 事件被觸發，所以我們在 onCreate 裡建立 View。</p>

<img alt="activity_lifecycle.png" src="http://www.jollen.org/blog/2008/12/29/activity_lifecycle.png" width="538" height="668" />

<p>TextView 是 Android 的其中一個 View，故名思義，這是一個顯示文字的 View。最後，呼叫 Activity 的 method 'setContentView' 來將 UI 顯示於視窗上。</p>
]]>
      
   </content>
</entry>
<entry>
   <title>Jollen  的Android 教學,#1: Android 應用程式模式</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/12/jollen-android-programming-1.html" />
   <id>tag:www.jollen.org,2008:/blog//2.585</id>
   
   <published>2008-12-29T11:58:24Z</published>
   <updated>2009-08-05T07:04:36Z</updated>
   
   <summary>Android 應用程式的模式（application model），可由以下幾個觀念講起。在真正進入 Android 程式設計前，必須先了解以下幾個名詞觀念。 1. Android package（.apk） Android 應用程式套件，包含應用程式本身，以及相關的資源檔案。將 apk 套件下載到 Android 手機後，即可安裝至手機上。Android Development Kit 可自動將 apk 套件下載至模擬器或實體手機。 2. task Task 就是「應用程式」本身，也就是 Android 手機上的圖示，使用者可點擊圖示啟動 task。從開發者的角度來看，task就是一個或多個 activities。 3. process Process 在作業系統的定義上，指的是「執行中的程式」，在 Android 的應用程式模式中，代表的是低階的執行程式，也就是系統層（kernel）的部份。一個 apk 套件裡的所有程式，都是在一個 process 裡執行。 4. 什麼是 Activity（android.app.Activity）...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Android OS" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      Android 應用程式的模式（application model），可由以下幾個觀念講起。在真正進入 Android 程式設計前，必須先了解以下幾個名詞觀念。

1. Android package（.apk）

Android 應用程式套件，包含應用程式本身，以及相關的資源檔案。將 apk 套件下載到 Android 手機後，即可安裝至手機上。Android Development Kit 可自動將 apk 套件下載至模擬器或實體手機。

2. task

Task 就是「應用程式」本身，也就是 Android 手機上的圖示，使用者可點擊圖示啟動 task。從開發者的角度來看，task就是一個或多個 activities。

3. process

Process 在作業系統的定義上，指的是「執行中的程式」，在 Android 的應用程式模式中，代表的是低階的執行程式，也就是系統層（kernel）的部份。一個 apk 套件裡的所有程式，都是在一個 process 裡執行。

4. 什麼是 Activity（android.app.Activity）

簡單來說，這昰一個與使用者互動的物件。一個 Activity 類別（class）負責建立視窗（window），我們可以透過 View 類別將UI放置在視窗上。

當 Activity 被啟動（active）或執行（running）時，就是在 foreground（前景）模式，在 foreground 模式的 Activity 會被顯示在螢幕上。

當執行中的 Activity 部份畫面被其他 Activity 蓋掉時，該 Activity 便被暫停（paused），被暫停的 Activity 在系統記億體不足時，便會被清除（kill）。只被蓋掉部份畫面，或是變成透明狀況的 Activity 不會停止，只會進入暫停狀態。

當執行中的 Activity 全部畫面都被其他 Activity 取代時，該 Activity 便被停止（stopped），當系統需要記憶體時，停止中的 Activity 會先被系統清除。

當系統需要清除 Activity 時，系統會要求 Activity 自行結束，或是直接殺掉 Activity 的 process。

5. 什麼是 View（android.app.View）

簡單來說，android.app.View 類別就是手機的 UI。View 負責繪製UI與處理事件（event），Android 利用 View 打造出所謂的 Widgets（元件），利用 Widget 可打造出互動式的使用者介面（interactive GUI）。

Android 應用程式的 UI 從程式碼的角度來看，就是一顆「view tree」，程式設計師可以利用直接撰寫程式碼，或是透過「XML layout」檔的方式，來安排應用程式的 view tree。

另外，還有一個特殊的 View 類別，稱為 ViewGroup（android.view.ViewGrup）。ViewGroup 是一種特別的 View，可以用來「裝載」其他的 View，對 ViewGroup 而言，這些被包含起來的 View 為 Children。

6. Process Types

在一般情況下，Android 應用程式都有一個自已的 Linux process。

在 Android 系統裡，process 的生命週期並不是直接由 Android 應用程式本身來決定，而是由系統來決定，也因此，Android 應用程式的開發者必須正確地撰寫程式碼，並使用 Android 的元件（component），否則系統不管應用程式是否仍在執行，仍會將應用程式的 process 清除（kill）掉。

Android 的 process 有五種類型：foreground process、visible process、service process、background process 與 empty process。
      
   </content>
</entry>
<entry>
   <title>Linux 驅動程式的 scheduling 觀念, #1:</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/12/kernel-scheduling-concept-1.html" />
   <id>tag:www.jollen.org,2008:/blog//2.580</id>
   
   <published>2008-12-14T03:58:18Z</published>
   <updated>2009-08-05T07:04:36Z</updated>
   
   <summary>本週進行「Linux Device Drivers: Jollen 的 10 堂課」教育訓練，發現有些同學對於作業系統的「排程（scheduling）」觀念仍有些疑問，因此，在課程中以三段小程式來說明「什麼是排程」，以協助同學建立紮實的排程觀念。 以下是一段正常的 open system call 實作： int card_open(struct inode *inode, struct file *filp) { return 0; } 當 process 開啟 device file 後，因為 kernel-space 的 open system call 實作會直接 return，因此 CPU 會切換至前景（foreground）、 process 繼續往下執行。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Linux Device Drivers &amp; Kernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>本週進行「Linux Device Drivers: Jollen 的 10 堂課」教育訓練，發現有些同學對於作業系統的「排程（scheduling）」觀念仍有些疑問，因此，在課程中以三段小程式來說明「什麼是排程」，以協助同學建立紮實的排程觀念。</p>

<p>以下是一段正常的 open system call 實作：</p>

<pre>int card_open(struct inode *inode, struct file *filp)
{
	return 0;
}</pre>

<p>當 process 開啟 device file 後，因為 kernel-space 的 open system call 實作會直接 return，因此 CPU 會切換至前景（foreground）、 process 繼續往下執行。</p>

<p>第二段是不正確的 open system call 實作：</p>

<pre>int card_open(struct inode *inode, struct file *filp)
{
	while (1);
	return 0;
}</pre>

<p>當 process 開啟 device file 後，因為 CPU 切換至後景（background），但是在 OS 裡頭的 open system call 實作是一個無窮迴圈，OS 並沒有做 system call 的返回，因此 CPU 並不會切換到前景，所以，電腦感覺起來呈現「當機」狀態。</p>

<p>因為 CPU 的時間無法切換到前景，因此任何的 process 都無法執行，電腦當然沒有任何反應。這裡，可沒有所謂的「time slice」與「context switch」的觀念與動作。請同學思考：作業系統是對 process 做排程。</p>

<p>最後一段程式，我們加入了呼叫排程器的動作：</p>

<pre>int card_open(struct inode *inode, struct file *filp)
{
	while (1)
		schedule();
	return 0;
}</pre>

<p>schedule() 是排程器主函數，等於是主動呼叫 scheduler 做 re-scheduling。在這個情況下，雖然 OS 仍然沒有做 system call 返回，但因為我們以「手排」的方式做排程，因此 CPU 會換切到前景，前景程式就會被分配時間執行，因此，電腦仍然有反應。</p>

<p>唯一要注意的地方是，因為這一個 open system call 並沒有 return，所以原來的 process 並不會繼續往下執行。利用三段簡單的程式碼，對作業系統的排程觀念做了一次討論，對於建立「什麼是 scheduling」的觀念，是很有幫助的。</p>]]>
      
   </content>
</entry>
<entry>
   <title>安裝 Android 應用程式（apk）至 Neo FreeRunner</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/11/hello_moko_free_runner_android.html" />
   <id>tag:www.jollen.org,2008:/blog//2.576</id>
   
   <published>2008-11-21T05:54:30Z</published>
   <updated>2009-08-05T07:04:36Z</updated>
   
   <summary>首先，依照 Android 文件上的說明 [先安裝 SDK]，再 [撰寫 Hello, Android!] 應用程式後，打包成 apk 格式；本文使用的 Android SDK 搭配的 Eclipse 版本是 3.4（Ganymede）。接著，再照 [Android Documentation] 的說明撰寫一個 Android 應用程式，再將程式編譯後打包成 HelloMoko.apk 檔案。 當然，必須將 FreeRunner 更新為 Android 系統，更新方式可至 Openmoko 中文 wiki 下載投影片：http://wiki.openmoko.org/wiki/Main_Page/zh_tw。請依以下步驟將 HelloMoko.apk 安裝至 FreeRunner 手機上。以下的實驗環境為 Ubuntu 8.04.1。 1....</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[首先，依照 Android 文件上的說明 [<a href="http://code.google.com/android/intro/installing.html">先安裝 SDK</a>]，再 [<a href="http://code.google.com/android/intro/hello-android.html">撰寫 Hello, Android!</a>] 應用程式後，打包成 apk 格式；本文使用的 Android SDK 搭配的 Eclipse 版本是 3.4（Ganymede）。接著，再照 [<a href="http://code.google.com/android/documentation.html">Android Documentation</a>] 的說明撰寫一個 Android 應用程式，再將程式編譯後打包成 HelloMoko.apk 檔案。

當然，必須將 FreeRunner 更新為 Android 系統，更新方式可至 Openmoko 中文 wiki 下載投影片：<a href="http://wiki.openmoko.org/wiki/Main_Page/zh_tw">http://wiki.openmoko.org/wiki/Main_Page/zh_tw</a>。請依以下步驟將 HelloMoko.apk 安裝至 FreeRunner 手機上。以下的實驗環境為 Ubuntu 8.04.1。

1. 連接 FreeRunner 與 PC

將 FreeRunner 以 USB 連接 PC，再將 FreeRunner 手機開機至 Android 環境。請注意，依照 Openmoko wiki 上的說明，若在開機後再連接 PC，可能會有問題。可利用 lsusb 指令檢查 FreeRunner 是否順利連到 PC 上：

<blockquote><pre>$ lsusb
Bus 007 Device 002: ID 04b4:1724 Cypress Semiconductor Corp. 
Bus 007 Device 001: ID 0000:0000  
Bus 003 Device 001: ID 0000:0000  
Bus 006 Device 001: ID 0000:0000  
<font color="#ff0000">Bus 005 Device 034: ID 1457:5117 </font>
Bus 005 Device 001: ID 0000:0000  
Bus 004 Device 001: ID 0000:0000  
Bus 004 Device 004: ID 04d9:0499 Holtek Semiconductor, Inc. 
Bus 002 Device 001: ID 0000:0000  
Bus 001 Device 001: ID 0000:0000</pre></blockquote>

2. 殺掉 adb server

執行 adb 時，adb-server 會自動啟動。因此，若是先前曾利用 Eclipse 啟動過 Android 模擬器來測試 HelloMoko 的話，adb-server 己經在背景執行了。啟動 adb server 後再連接 FreeRunner，可能會讓 adb server 找不到 FreeRunner，因此，最可靠的做法是：先檢查系統是否有 adb server，將執行中的 adb server kill 掉後，再重新啟動 adb server。

<blockquote><pre>$ ps ax|grep adb
20092 ?        S+     0:00 grep adb
21032 ?        Sl     0:00 adb fork-server server
$ sudo kill -9 21032</pre></blockquote>

adb 是 Android SDK 所提供的工具，可於 Android SDK 的 tools/ 目錄下取得。

3. 設定 PC 端 IP

接下來設定 PC 端的 IP 位址為 192.168.0.x，例如：

<blockquote><pre>$ sudo ifconfig <font color="#ff0000">usb0 192.168.0.200</font></pre></blockquote>

FreeRunner 的預設 IP 為 192.168.0.202，可以 ping 此位址測試是否能正常連線。

4. 啟動 adb server

設定 ADBHOST 環境變數：

<blockquote><pre>$ export ADBHOST=192.168.0.202</pre></blockquote>

ADBHOST 的值為 FreeRunner 的 IP 位址。再執行 adb 啟動 adb server，adb server 會自動偵測 Android 手機：

<blockquote><pre>$ adb devices
* daemon not running. starting it now *
* daemon started successfully *
List of devices attached 
<font color="#ff0000">emulator-5554   device</font></pre></blockquote>

在 'List of devices attached' 項目可以看到系統自動偵測到的 Android 手機。

5. 安裝 HelloMoko.apk

使用 adb 將 HelloMoko.apk 安裝到 FreeRunner / Android 手機：

<blockquote><pre>$ adb install HelloMoko.apk</pre></blockquote>

安裝完成後，重新啟動 FreeRunner 即可在應用程式選單裡看到 HelloMoko。
]]>
      
   </content>
</entry>
<entry>
   <title>Neo FreeRunner: 3 軸加速度感測器程式實作</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/11/programming_freerunner_accelerometer.html" />
   <id>tag:www.jollen.org,2008:/blog//2.574</id>
   
   <published>2008-11-10T04:29:37Z</published>
   <updated>2009-08-05T07:04:36Z</updated>
   
   <summary>Neo FreeRunner 搭載二個「3 軸加速度感測器」，這是一個很有趣的硬體，他可 以偵測手機的移動狀態，配合應用程式，可以實作出有趣的小玩具。以 iPhone 為 例，它有一個很人性化的功能，當手機 90 度轉向時，視窗也會跟著 90 度轉換， 這樣的功能就是透過「加速度感測器」晶片來完成的。 Neo FreeRunner 有二個 3 軸加速度感測器，當手機移動時，可以利用程式讀取每 一個軸的加速度值。讀取加速度感測器的方法是透過 Linux 的 input layer： /dev/input/event{2,3} Process 透過這二個裝置檔讀取 input layer 的資料，kernel 會回傳一筆加速度感測器的資料給 process，該筆資料的 data type 為 struct input_event，即 kernel 的 input event...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>Neo FreeRunner 搭載二個「3 軸加速度感測器」，這是一個很有趣的硬體，他可 以偵測手機的移動狀態，配合應用程式，可以實作出有趣的小玩具。以 iPhone 為 例，它有一個很人性化的功能，當手機 90 度轉向時，視窗也會跟著 90 度轉換， 這樣的功能就是透過「加速度感測器」晶片來完成的。</p>

<p>Neo FreeRunner 有二個 3 軸加速度感測器，當手機移動時，可以利用程式讀取每 一個軸的加速度值。讀取加速度感測器的方法是透過 Linux 的 input layer：</p>

<pre>    /dev/input/event{2,3}</pre>

<p>Process 透過這二個裝置檔讀取 input layer 的資料，kernel 會回傳一筆加速度感測器的資料給 process，該筆資料的 data type 為 struct input_event，即 kernel 的 input event 資料結構。程式的做法是，每次讀取一筆加速度感測器資料，再判斷資料的類型，以及各軸的加速度值。</p>

<p>程式寫法如下：</p>

<pre>    #include &lt;linux/input.h&gt;

    int main(void)
    {

        struct input_event motion;

        fd = open("/dev/input/event3", S_IRUSR);

        while (1) {
            read(fd, &motion, sizeof(motion));
        }
    }</pre>

<p>struct input_event 資料結構的定義如下：</p>

<pre>    struct input_event {
        struct timeval time;
        __u16 type;
        __u16 code;
        __s32 value;
    };</pre>


<p>讀出的資料如下：</p>

<ul>
<li>motion.time: 讀取到該筆資料的時間</li>
<li>motion.type: 值為 2 時，表示該筆資料為加速度值</li>
<li>motion.code: 表示讀取的加速度方向，0 = x 軸、1 = y 軸、2 = z 軸</li>
<li>motion.value: 該軸的加速度值，正負號代表「正負方向」</li>
</ul>

<p>本範例讀取 FreeRunner 上的第二個 3 軸加速度感測器，x/y/z 軸所代表的方向如下圖。</p>

<img src="http://wiki.openmoko.org/images/c/c6/Accelerometer_orientation2.png" />
(Source: Openmoko Wiki)

<p>如果想要讀取 x 軸的加速度：</p>

<pre>    int x;

    /* 資料有效且為 x 軸 */
    if (motion.type == 2 && motion.code == 0) {
        x = motion.value;
    }</pre>

<p>若 x 為負值，表示手機往左邊的方向移動。再舉一個例子，讀取 y 軸的加速度：</p>

<pre>    int y;

    /* 資料有效且為 y 軸 */
    if (motion.type == 2 && motion.code == 1) {
        y = motion.value;
    }</pre>


<p>若 y 軸的加速度為正值，表示手機往下移動。更多有關 FreeRunner 加速度感測器（accelerometer）的資訊，可參閱 Openmoko wiki [<a href="http://wiki.openmoko.org/wiki/Accelerometer_data_retrieval">Accelerometer data retrieval</a>]。</p>]]>
      
   </content>
</entry>
<entry>
   <title>FreeRunner 搭載 Android 實機測試</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/11/freerunner_android_snapshot.html" />
   <id>tag:www.jollen.org,2008:/blog//2.573</id>
   
   <published>2008-11-05T06:45:34Z</published>
   <updated>2009-08-05T07:04:36Z</updated>
   
   <summary>看了這麼久的 Android 消息，今天終於可以實際將 Neo FreeRunner 更新成 Android 系統，進行實機測了。將 FreeRunner 變成 Android 手機的做法，可以在 [Openmoko Wiki] 下載教學簡報。以下是實機測試畫面。 將 FreeRunner 重新燒錄 Android 的 kernel 以及 rootfs 後，直接開機。大約過了1分鐘後，看到了 Android 的開機畫面，開機時間還可接受，但似乎目前的版本並不是相當穩定，仍有開機失敗的機率。 開機後，來到鎖定畫面，必須按一下 FreeRunner 的按鍵，才能進到主選單。 主選單是典型的 Android 畫面，當然是採用觸控方式操作。整個 FreeRunner + Android 給我的第一印像還算不錯，觸控操作挺順手的，不會有「卡卡」的感覺。 來到 Android 的應用程式選單，裡頭有許多 Android...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[看了這麼久的 Android 消息，今天終於可以實際將 Neo FreeRunner 更新成 Android 系統，進行實機測了。將 FreeRunner 變成 Android 手機的做法，可以在 [<a href="http://wiki.openmoko.org/wiki/Main_Page/zh_tw">Openmoko Wiki</a>] 下載教學簡報。以下是實機測試畫面。

將 FreeRunner 重新燒錄 Android 的 kernel 以及 rootfs 後，直接開機。大約過了1分鐘後，看到了 Android 的開機畫面，開機時間還可接受，但似乎目前的版本並不是相當穩定，仍有開機失敗的機率。

<img src="http://people.openmoko.org/jollen/freerunner-android/freerunner-android-1.png" />

開機後，來到鎖定畫面，必須按一下 FreeRunner 的按鍵，才能進到主選單。

<img src="http://people.openmoko.org/jollen/freerunner-android/freerunner-android-2.png" />

主選單是典型的 Android 畫面，當然是採用觸控方式操作。整個 FreeRunner + Android 給我的第一印像還算不錯，觸控操作挺順手的，不會有「卡卡」的感覺。

<img src="http://people.openmoko.org/jollen/freerunner-android/freerunner-android-3.png" />

來到 Android 的應用程式選單，裡頭有許多 Android 的應用程式。

<img src="http://people.openmoko.org/jollen/freerunner-android/freerunner-android-4.png" />

這是 Android 的撥號器（dailer）程式。雖然沒有很仔細測試整體系統，不過第一時間給我的感覺很不錯、也很有新鮮感。 ;-)

<img src="http://people.openmoko.org/jollen/freerunner-android/freerunner-android-5.png" />]]>
      
   </content>
</entry>
<entry>
   <title>Android 已經能在 FreeRunner 上執行</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/11/android_running_on_freerunner.html" />
   <id>tag:www.jollen.org,2008:/blog//2.572</id>
   
   <published>2008-11-05T01:05:47Z</published>
   <updated>2009-08-05T07:04:36Z</updated>
   
   <summary>自從 Google 正式公開 Android 原始碼後，Openmoko 社群便開始努力將 Android 移植到 FreeRunner 手機上，期間不斷有小報導指出 Openmoko 將推出 Android 手機。不過，正確的說法應該是「Openmoko 將 Android 移植到 FreeRunner 上」，而不是另外打造一支新的手機。 前二天，連「Openmoko 投靠 Android 聯盟」的消息都出現了（其中一則報導還附上 FreeRunner 執行 Android 的照片）： * Openmoko來投 Android聯盟再添一員 * 本月有望推出 Android家族第2款手機 投靠 OHA 聯盟？這還是未經證實的小報導，不過，FreeRunner 能執行 Android 已經是可以官方證實的消息了。Openmoko 的確「已經將...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[自從 Google 正式公開 Android 原始碼後，Openmoko 社群便開始努力將 Android 移植到 FreeRunner 手機上，期間不斷有小報導指出 Openmoko 將推出 Android 手機。不過，正確的說法應該是「Openmoko 將 Android 移植到 FreeRunner 上」，而不是另外打造一支新的手機。

前二天，連「Openmoko 投靠 Android 聯盟」的消息都出現了（其中一則報導還附上 FreeRunner 執行 Android 的照片）：

* <a href="http://financenews.sina.com/sinacn/304-000-106-109/2008-11-02/0908935461.html">Openmoko來投 Android聯盟再添一員</a>
* <a href="http://financenews.sina.com/sinacn/304-000-106-109/2008-11-03/1421936946.html">本月有望推出 Android家族第2款手機</a>

投靠 OHA 聯盟？這還是未經證實的小報導，不過，FreeRunner 能執行 Android 已經是可以官方證實的消息了。Openmoko 的確「已經將 Android 移植到 FreeRunner」，而且也對外釋出，已經可以由網路上下載 Android 的 image 了。我們來看一下 Openmoko 在這裡做了什麼事情：

1. 主要的移植開發者為 Sean McNeil

2. 修改了 Binutils 2.18 以順利編譯 Android 原始碼

3. gcc 4.2.4 加入 gcc41-java-arm4.patch 以順利編譯 Android 原始碼

4. 執行 Android 的 kernel 版本是 2.6.26

這項工作，其實過程都是很透明的，因為 Sean McNeil 陸續都有將大部份的 patch 都丟到 mailing list 上，再加上社群的討論以及網路上的移植工作，「FreeRunner 能執行 Android」已經是預料中的事情了。

針對開發者或教育研究單位來說，Openmoko 所維護的 distribution 將會是一個「super set」，也就是「不同的 Linux distribution 或開放手機軟體，都能在 FreeRunner 硬體裝置上執行」。如同前一篇日記所說的，FreeRunner 能執行 Android 的話，不但可以吸引 Android 的開發者參與 Openmoko 社群的活動，對投入 Android 平臺的教學研究機構來說，也能將成果實際放到 FreeRunner 手機上執行測試。

<strong>延伸閱讀</strong>

* 2008.10.31: <a href="http://www.jollen.org/blog/2008/10/openmoko_freerunner_google_android.html">Openmoko FreeRunner 與 Google Android: 現況與想法</a>
* 2008.10.27: <a href="http://www.jollen.org/blog/2008/10/porting_android_to_free_runner.html">移植 Android 到 Neo1973 與 Neo FreeRunner</a>]]>
      
   </content>
</entry>
<entry>
   <title>Openmoko FreeRunner 與 Google Android: 現況與想法</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/10/openmoko_freerunner_google_android.html" />
   <id>tag:www.jollen.org,2008:/blog//2.571</id>
   
   <published>2008-10-31T04:54:26Z</published>
   <updated>2009-08-05T07:04:36Z</updated>
   
   <summary>自從 Android 公開原始碼後，Openmoko 的社群便開始積極進行移植的工作。最近在網路上也開始看到許多這方面的報導： * Rumor: OpenMoko Android Phone In November? * OpenMoko Jumps On Android Bandwagon * Openmoko將在11月推出Android手機？ * 开源手机OpenMoko转投Android门下 * 预计Openmoko将在11月推出Android手机？ 這些報導看起來比較像是「謠言」（rumor），有些報導甚致還放了圖片，不過，有圖不一定有真相，明眼人一看就知道這些圖都是「後製」出來的。但是，Openmoko 社群正在移植 Android 至 FreeRunner 也是一個事實。從目前 Openmoko 社群的移植工作來看，主要進行的項目有： 1. 修改 ARMv5 指令集。由於 FreeRunner 採用的 s3c2442 處理器是 ARMv4...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[自從 Android 公開原始碼後，Openmoko 的社群便開始積極進行移植的工作。最近在網路上也開始看到許多這方面的報導：

* <a href="http://phandroid.com/2008/10/29/rumor-openmoko-android-phone-in-november/">Rumor: OpenMoko Android Phone In November?</a>
* <a href="http://www.ubergizmo.com/15/archives/2008/10/openmoko_jumps_on_android_bandwagon.html">OpenMoko Jumps On Android Bandwagon</a>
* <a href="http://chinese.engadget.com/2008/10/30/openmoko-at-work-on-android-handset/">Openmoko將在11月推出Android手機？</a>
* <a href="http://news.cnblogs.com/n/43307/">开源手机OpenMoko转投Android门下</a>
* <a href="http://gphone.tgbus.com/news/mtnews/200810/167494.shtml">预计Openmoko将在11月推出Android手机？</a>

這些報導看起來比較像是「謠言」（rumor），有些報導甚致還放了圖片，不過，有圖不一定有真相，明眼人一看就知道這些圖都是「後製」出來的。但是，Openmoko 社群正在移植 Android 至 FreeRunner 也是一個事實。從目前 Openmoko 社群的移植工作來看，主要進行的項目有：

1. 修改 ARMv5 指令集。由於 FreeRunner 採用的 s3c2442 處理器是 ARMv4 指令集，因此必須修改低階的 assembly code。

2. 硬體支援的部份。讓 Android middleware 能在 FreeRunner 的 Linux kernel 上執行。

3. 修改 Android 的 build system。讓 Android 的 build system 能製作 jffs2 格式的 image file，這也是 FreeRunner 採用的 image file 格式。

這些工作看起來都有很不錯的進展，社群開發者也已經將部份成果 patches 提交到 [<a href="http://source.android.com/submit-patches">Android Open Source Project</a>]。Android 開放式手機平臺成功吸引全球目光，但對社群開發者來說，仍然缺少能支援 Android 的「開放手機硬體」，雖然市面已經推出 Android 手機，但仍不是「開放式」硬體，對 open source developer 來說，少了那麼一點樂趣。

如果 FreeRunner 真的能執行 Android 的話，想必一定可以吸引對 Android 有興趣的開發者進入 Openmoko 社群，對 Openmoko 社群的成長也會有所幫助。FreeRunner 是一個完全開放式的手機硬體，因此對 application 開發者、middleware 開發者以及 kernel 開發者來說，都是一個充滿許多樂趣的平臺。

目前台灣也有許多大學實驗室投入 Android 平臺的研究，但不足的地方在於「硬體裝置」的取得。當 FreeRunner 能真正支援 Android 時，對這些研究人員來說，想必也是一個好消息，因為可以把 Android 的研究成果，實際放到真正的手機裝置上執行與測試。]]>
      
   </content>
</entry>
<entry>
   <title>移植 Android 到 Neo1973 與 Neo FreeRunner</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/10/porting_android_to_free_runner.html" />
   <id>tag:www.jollen.org,2008:/blog//2.570</id>
   
   <published>2008-10-27T08:23:54Z</published>
   <updated>2009-08-05T07:04:36Z</updated>
   
   <summary>Android 於 10 月 21 日正式公開原始碼 [Android is now available as open source]，Openmoko 的開發者社群第一時間也出現許多討論 [Android open sourced]。 很快地，「移植 Android 到 Neo1973 與 Neo FreeRunner」的工作也開始了，目前這項移植工作還是「underway」進行中；不過，社群開發者仍紀錄了最新的移植狀況在 Openmoko wiki 上 [Android]。 相關資源 * 2008-08-25: Andorid是否可以porting到FreeRunner...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Android 於 10 月 21 日正式公開原始碼 [<a href="http://source.android.com/posts/opensource">Android is now available as open source</a>]，Openmoko 的開發者社群第一時間也出現許多討論 [<a href="http://lists.openmoko.org/pipermail/community/2008-October/034025.html">Android open sourced</a>]。

很快地，「移植 Android 到 Neo1973 與 Neo FreeRunner」的工作也開始了，目前這項移植工作還是「underway」進行中；不過，社群開發者仍紀錄了最新的移植狀況在 Openmoko wiki 上 [<a href="http://wiki.openmoko.org/wiki/Android">Android</a>]。

相關資源

* 2008-08-25: <a href="http://openmoko-tw.net/phpbb/viewtopic.php?f=10&t=9&p=51#p51">Andorid是否可以porting到FreeRunner</a>]]>
      
   </content>
</entry>
<entry>
   <title>「Openmoko Linux 2008 開放手機新體驗」簡報上線</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/10/programming_neo_freerunner_efl.html" />
   <id>tag:www.jollen.org,2008:/blog//2.568</id>
   
   <published>2008-10-16T15:47:36Z</published>
   <updated>2008-10-16T12:55:41Z</updated>
   
   <summary>今天受邀至台北科技大學資訊工程系演講，講題是「Openmoko Linux 2008 開放手機新體驗」，正好能接續昨天的日記「Neo FreeRunner 應用程式開發概念圖」，在簡報的最後，附上了一小部份的講義「如何在Om2008.8 撰寫 EFL 應用程式並編譯」供同學們參考。 下載簡報 [Openmoko Linux 2008 開放手機新體驗]。Openmoko 近期有許多新消息，有興趣的同學可以至 [Openmoko 中文 Wiki] 查詢。 延伸閱讀 2008.10.15: Neo FreeRunner 應用程式開發概念圖...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[今天受邀至台北科技大學資訊工程系演講，講題是「Openmoko Linux 2008 開放手機新體驗」，正好能接續昨天的日記「<a href="http://www.jollen.org/blog/2008/10/programming_neo_freerunner.html">Neo FreeRunner 應用程式開發概念圖</a>」，在簡報的最後，附上了一小部份的講義「如何在Om2008.8 撰寫 EFL 應用程式並編譯」供同學們參考。

下載簡報 [<a href="http://people.openmoko.org/jollen/Om-programming-freerunner-ntut-1016.pdf">Openmoko Linux 2008 開放手機新體驗</a>]。Openmoko 近期有許多新消息，有興趣的同學可以至 [<a href="http://wiki.openmoko.org/wiki/Main_Page/zh_tw">Openmoko 中文 Wiki</a>] 查詢。

<strong>延伸閱讀</strong>

2008.10.15: <a href="http://www.jollen.org/blog/2008/10/programming_neo_freerunner.html">Neo FreeRunner 應用程式開發概念圖</a>]]>
      
   </content>
</entry>
<entry>
   <title>Neo FreeRunner 應用程式開發概念圖</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/10/programming_neo_freerunner.html" />
   <id>tag:www.jollen.org,2008:/blog//2.567</id>
   
   <published>2008-10-15T06:41:33Z</published>
   <updated>2008-10-15T07:25:29Z</updated>
   
   <summary>Openmoko 的 distribution 現在有許多不同的版本，一大堆名詞總讓人一開始就一頭霧水，像是：Om2007.2、Om2008.8、FDOM、ASU等等。剛開始接觸 Openmoko 以及 Neo FreeRunner 的同學，經常要花一些時間認真讀 Openmoko wiki 才能了解通盤概念。 許多同學只是想要在 FreeRunner 上寫寫簡單的小程式，一開始遇到這些從沒聽過的名詞，花很多時間，有時還是搞不清楚「怎麼在 FreeRunner 上寫小程式」，總是會有一些挫折感。因此，在這裡整理一份簡單的「Neo FreeRunner 應用程式開發概念圖」，幫助同學建立整體概念。 怎麼在 Neo FreeRunner 上寫一個簡單的小程式呢？請看下圖的說明。 Om2007.2 與 Om2008.8 都是 Openmoko 的官方版本（official distribution），Om2007.2 與 Om2008.8 除了有 Openmoko 自已的開發成果外，也使用了許多 FOSS（Free and Open Source Software）的套件，因此，需要將...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Openmoko 的 distribution 現在有許多不同的版本，一大堆名詞總讓人一開始就一頭霧水，像是：Om2007.2、Om2008.8、FDOM、ASU等等。剛開始接觸 Openmoko 以及 Neo FreeRunner 的同學，經常要花一些時間認真讀 Openmoko wiki 才能了解通盤概念。

許多同學只是想要在 FreeRunner 上寫寫簡單的小程式，一開始遇到這些從沒聽過的名詞，花很多時間，有時還是搞不清楚「怎麼在 FreeRunner 上寫小程式」，總是會有一些挫折感。因此，在這裡整理一份簡單的「Neo FreeRunner 應用程式開發概念圖」，幫助同學建立整體概念。

怎麼在 Neo FreeRunner 上寫一個簡單的小程式呢？請看下圖的說明。

<img alt="programming_freerunner.png" src="http://www.jollen.org/blog/2008/10/15/programming_freerunner.png" />

Om2007.2 與 Om2008.8 都是 Openmoko 的官方版本（official distribution），Om2007.2 與 Om2008.8 除了有 Openmoko 自已的開發成果外，也使用了許多 FOSS（Free and Open Source Software）的套件，因此，需要將 Openmoko 的成果與這些 FOSS 套件整理成一個完整的散佈套件，以提供 Openmoko 手機使用，這就是「Openmoko Linux」或「Openmoko Linux distribution」。這樣的概念就像是 Ubuntu Desktop 是一個給個人電腦使用的 Linux distribution，Fedora 也是一個 Linux distribution。

Om2007.2 是 Openmoko 官方的第二個釋出版本，middleware 的主要元件為 libgsmd 與 GTK+。Openmoko 提供 Om2007.2 的 pre-built toolchain 以及一個 sample（放置於 pre-built toolchain 的 openmoko-sample2 目錄）讓開發者可以很方便地撰寫程式，並將編譯好的程式打包成 opkg 後安裝到手機。

Om2008.8 是 Openmoko 官方的第三個釋出版本，同時也是很重要的一個版本，Om2008.8 主要的變更是使用了 Qtopia 的成果，將 Qtopia 移植到 x11 環境，並與其 GTK+ 的環境做整合。此外，也加入了 EFL（Enlightenment）的 UI 環境，並加入了一個可動態安裝套件的 Installer 程式，以及 Locations GPS 應用程式。在視窗管理方面，採用 EFL 的 Illume；同時也有較佳的 theme 支援，也加入了 Qtopia keyboard。Om2008.8 可同時執行 Qtopia/EFL/GTK+/x11 應用程式，並透過 D-Bus 技術做整合，可以說是一個創新的手機軟體平臺。

在 Om2008.8 平臺上，除了能使用 GTK+ 的 pre-built toolchain 來寫程式外，Openmoko 也提供了新版本的 pre-built toolchain。如果您想使用 EFL 來寫程式，可以安裝新版本的 pre-built toolchain，並透過 opkg-target 來安裝 EFL 的開發環境（libevas-dev 與 libetk-dev）至 pre-built toolchain，即可使用 C 來撰寫 EFL 程式。同樣地，我們可以使用上述的 openmoko-sample2 來編譯 EFL 程式，並打包成 opkg 後安裝至手機。

另外一個方式則是使用 Python 來撰寫 EFL 應用程式，直接將 Python script 上傳到 FreeRunner 即可執行，當然也可以打包成 opkg 後再安裝。

過去曾使用 Qtopia 撰寫程式的同學，也能在 Om2008.8 上執行 Qtopia 應用程式；不過，如果是 Qt 應用程式的話，雖然 Om2008.8 裡有包含 Qt library，但比較不建議使用。]]>
      
   </content>
</entry>
<entry>
   <title>停止軟體專利世界日（Stop Software Patents World Day）</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/09/stop_software_patent_world_day.html" />
   <id>tag:www.jollen.org,2008:/blog//2.565</id>
   
   <published>2008-09-25T15:08:32Z</published>
   <updated>2008-09-25T12:33:22Z</updated>
   
   <summary>今天是 [Free Software Foundation（自由軟體基金會）] 的 [Stop Software Patents, World Day]，所以也來 [貼貼 banner] 嚮應一下。 今年五月份，自由軟體基金會的創辦人 Richard Stallman 來台演講時，發表了一場「The Danger of Software Patent」的演說。Richard Stallman 以一張圖說明了為何軟體專利是「無限的危害」，至今仍令人印像深刻。ZDNet Taiwan 上的一則報導 [自由軟體之父：軟體專利有害無益] 便引述了 Richard Stallman 的一段談話： 「專利權本身的目的是為鼓勵人們將新創概念公佈出來，但現行的專利體系卻會造成反效果，」 因為認同這個觀念，因此嚮應一下「停止軟體專利世界日」。 延伸閱讀 * 2008.05.22: Richard Stallman 台灣行第四天紀錄: 5/15 演講實紀...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[今天是 [<a href="http://www.fsf.org/">Free Software Foundation</a>（自由軟體基金會）] 的 [<a href="http://stopsoftwarepatents.org/">Stop Software Patents, World Day</a>]，所以也來 [<a href="http://stopsoftwarepatents.org/banners">貼貼 banner</a>] 嚮應一下。

<a href="http://stopsoftwarepatents.org/"><img src="http://stopsoftwarepatents.wdfiles.com/local--files/banners/webbanner_standard.png" border="0"></a>

今年五月份，自由軟體基金會的創辦人 Richard Stallman 來台演講時，發表了一場「The Danger of Software Patent」的演說。Richard Stallman 以一張圖說明了為何軟體專利是「無限的危害」，至今仍令人印像深刻。ZDNet Taiwan 上的一則報導 [<a href="http://www.zdnet.com.tw/news/software/0,2000085678,20129320,00.htm">自由軟體之父：軟體專利有害無益</a>] 便引述了 Richard Stallman 的一段談話：

<blockquote>「專利權本身的目的是為鼓勵人們將新創概念公佈出來，但現行的專利體系卻會造成反效果，」</blockquote>

因為認同這個觀念，因此嚮應一下「停止軟體專利世界日」。

<strong>延伸閱讀</strong>

* 2008.05.22: <a href="http://www.jollen.org/blog/2008/05/richard_stallman_speech_nthu.html">Richard Stallman 台灣行第四天紀錄: 5/15 演講實紀</a>
* 2008.05.21: <a href="http://www.jollen.org/blog/2008/05/richard_stallman_day4.html">Richard Stallman 台灣行第四天紀錄: 5/15 新竹清大行側寫</a>
* 2008.05.21: <a href="http://www.jollen.org/blog/2008/05/richard_stallman_departure.html">Richard Stallman 結束訪台行程: 5/19 離台</a>
* 2008.05.16: <a href="http://www.jollen.org/blog/2008/05/richard_stallman.html">Richard Stallman 台灣行第三天：下課後</a>
* 2008.05.14: <a href="http://www.jollen.org/blog/2008/05/richard_stallman_day3_tku.html">Richard Stallman 台灣行第三天：演講「The Danger of Software Patent」</a>
* 2008.05.12: <a href="http://www.jollen.org/blog/2008/05/richard_stallman_day1.html">Richard Stallman 台灣行第一天</a>
* 2008.05.03: <a href="http://www.jollen.org/blog/2008/05/richard_stallman_speech_taiwan.html">自由軟體基金會創辦人 Richard Stallman 來台演講</a>]]>
      
   </content>
</entry>
<entry>
   <title>演講「加入 kernel 除蟲大隊：簡介 kernel debug 工具」簡報上線</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/09/kernel_debug_intro.html" />
   <id>tag:www.jollen.org,2008:/blog//2.564</id>
   
   <published>2008-09-14T12:00:11Z</published>
   <updated>2008-09-14T11:34:45Z</updated>
   
   <summary>近期受邀發表了一場與「kernel debug」有關的演講，進行時間大約是70分鐘，在此提供簡報電子檔[加入 kernel 除蟲大隊]供有興趣的朋友下載。本次演講的目的是對 kernel debug 主題做「開場」，再加上時間有限，因此並沒有對 kernel debug 的技術做太深入的討論，反而是透過整理的方式，對幾個常見的 kernel debug 工具與方法做總覽。 演講最後展示了使用 gdb+qemu 來進行 kernel source-level debug 的方法。「加入 kernel 除蟲大隊」需要具備什麼樣的基本技能呢？ 首先，主要的工具「GNU Debugger」當然是必學的主題，不過因為這次的主題是 kernel debug，因此只約略介紹 user-space 下幾個重要的除錯觀念： Breakpoint, single step, inspect variables 如何設定中斷點，進行單步執行，並在程式 run-time 時期檢視變數內容。 Segmentation fault 程式被訊號（signal）被中止時，怎麼找到不正常終止的程式碼。一個典型的 segmentation...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Linux Device Drivers &amp; Kernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[近期受邀發表了一場與「kernel debug」有關的演講，進行時間大約是70分鐘，在此提供簡報電子檔[<a href="http://tw.jollen.org/slides/kernel-debug-intro-20080914.pdf">加入 kernel 除蟲大隊</a>]供有興趣的朋友下載。本次演講的目的是對 kernel debug 主題做「開場」，再加上時間有限，因此並沒有對 kernel debug 的技術做太深入的討論，反而是透過整理的方式，對幾個常見的 kernel debug 工具與方法做總覽。

演講最後展示了使用 gdb+qemu 來進行 kernel source-level debug 的方法。「加入 kernel 除蟲大隊」需要具備什麼樣的基本技能呢？

首先，主要的工具「GNU Debugger」當然是必學的主題，不過因為這次的主題是 kernel debug，因此只約略介紹 user-space 下幾個重要的除錯觀念：

<strong>Breakpoint, single step, inspect variables</strong>

如何設定中斷點，進行單步執行，並在程式 run-time 時期檢視變數內容。

<strong>Segmentation fault</strong>

程式被訊號（signal）被中止時，怎麼找到不正常終止的程式碼。一個典型的 segmentation fault 是發生在程式存取非法的記憶體位置時。

<strong>Core dump</strong>

程式不正常中止時，會產生 core dump 檔案。透過 core dump 檔與原始的 ELF image 來比對出程式發生不正常中斷的行號。

<strong>Multi-threaded, client-server, GUI</strong>

多執行緒的除錯、client-server 架構與 GUI 系統的除錯也是重要的除錯技能。以多執行緒為例，我們可以透過「attach」的方式讓 gdb attach 到執行中的子程序進行除錯；又以 GUI 系統為例，我們有時會想要追踪一個由 kernel 發出到 UI 端的事件（event)，或是追踪 IPC 的訊息內容。針對這部份來說，有時透過除錯來觀察「系統行為」會比程式邏輯的除錯來得重要，當然除錯上也會稍微複雜一些。

針對 kernel debug 的部份來說，初學者應該以「建立正確使用除錯工具的觀念」與「建立合適的除錯環境」為主軸。另外，對於 oops（kernel panic）訊息的分析，則是核心除錯的重頭大戲，只是這裡所涉及的背景知識會多一些，在投影片裡列出 oops 訊息分析所應了解的幾個主題。不過，不管是 user-space 除錯，或是 kernel-space 除錯，仍必須建立基本的系統程式觀念，像是：

* symbol table
* process virtual address space
* kernel virtual address space
* system call
* exceptions
* stack, heap

本次演講，也介紹了一些關於核心除錯的重要觀念，幾個未列在投影片的部份，在這裡做個簡單整理。

<strong>開機是一個循序式過程</strong>

Kernel 的開機過程，是一個傳統的「循序式（sequence）」執行過程，如同我們展示以 gdb + qemu 進行除錯一樣，可以檢視並了解 kernel 的開機流程，以及開機失敗時的程式碼位置。

<strong>開機完成後是狀態切換</strong>

當 kernel 開機完成後，便會啟動一個外部程式，稱為 init process，從這個時間開始，user-space 程式便得以執行。Kernel 此時並不是一個循序式執行（sequential function calls）的狀態。

當不同的 process 執行時，因為呼叫的 system call 不同，因此 kernel 的狀態也不同。再舉一例，以驅動程式來說，在開機過程中，kernel module 只做載入的動作；但是，驅動程式所實作的 system call，如：read、write、ioctl，則是必須透過 user program 執行 system call 才會被叫用。以後面的例子來說，這就不會只是一個單的 kernel debug，或者說「並不是只對 kernel 做除錯」。

<strong>Remote Debug</strong>

以 remote debug 的方式進行除錯，remote 端（target 端）所載入的 kernel 是編譯完成後，放置於 arch/arm/boot（以 ARM 為例）目錄下的 kernel image，這是 target 端所使用的 kernel image（run-time）。

Local 端（除錯本機端）也要載入 kernel image，此時載入 kernel image 的目的是為了讀取 symbol table 以及其它 ELF 節區資訊，這裡所載入的 kernel image 為 ‘vmlinux’，即編譯完成後放置於 kernel 根目錄下的原始 ELF image file。由此可知，本機端的 ELF image 必須包含完整的除錯資訊，讓 kernel image 包含除錯資訊的做法是在編譯核心時，將幾個除錯選項打開，這部份在簡報中有做說明。

最後，大家可以參考 jserv 兄過去所發表過有關gdb的演講簡報 [<a href="http://blog.linux.org.tw/~jserv/archives/002043.html">「快快樂樂學 GNU Debugger (gdb) Part I + II」簡報上線</a>]。]]>
      
   </content>
</entry>
<entry>
   <title>UI 設計新體驗 Python-etk</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/09/introduction_python-etk.html" />
   <id>tag:www.jollen.org,2008:/blog//2.563</id>
   
   <published>2008-09-04T15:00:18Z</published>
   <updated>2008-09-04T13:01:24Z</updated>
   
   <summary>最近在整理一些有關使用者介面設計的資料，希望可以提份一份簡單有趣的UI設計教學投影片，對象是學生，目的是讓同學可以「無恐懼玩UI」。 現今能做UI的技術很多，其中相對比較容易的方式就是以script language來打造UI，而當前最受注意的方式就是以Python快速寫UI。當然，網路上還有許多不同的UI技術，像是能讓「designer」真正自由發揮、免除寫code的SVG browser，也是一個值得注意的技術。 今天要介紹的主角是python-etk，故名思義，這是Python的ETK模組。ETK是一個不錯的東西，全名是Enlightenment Tool Kit，它的功能定位就像是GTK+的角色。GTK+是大名鼎鼎的圖形元件（widget）庫，由GTK+專案所沿伸出來的Glib也是一個使用廣泛的「強化版C程式庫」。ETK有沒有像Glib這樣的東西？有的，叫做Ecore。 Enlightenment（簡稱E）是一個知名且古老的window manager。[Enlightenment]包含許多程式庫以及工具，這些程式庫與工具總稱為EFL（Enlightenment Foundation Libraries）。簡單來看，可以畫出EFL的架構如下。 EVAS是一個「畫布」程式庫。Ecore的角色如同GTK+的產物Glib，不過並不完全等於。EDJE則是一個「layout engine」。最上面的ETK就是我們的主角，Enlightenment的圖形元件庫。 透過python-etk來實作ETK應用程式，可以帶給我們一些愉快的經驗。要怎麼寫一個向世界問好的入門級python-etk程式呢？以下是一個範例（hello_world.py）： #!/usr/bin/python import etk class MyButton(etk.Button): def _size_request(self): return (100, 200) btn = MyButton(label = &quot;Click Me&quot;) btn.on_clicked(lambda x: etk.main_quit()) # Main w = etk.Window(title=&quot;Hello World&quot;, size_request=(150,...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Open Mobile Platform" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>最近在整理一些有關使用者介面設計的資料，希望可以提份一份簡單有趣的UI設計教學投影片，對象是學生，目的是讓同學可以「無恐懼玩UI」。</p>

<p>現今能做UI的技術很多，其中相對比較容易的方式就是以script language來打造UI，而當前最受注意的方式就是以Python快速寫UI。當然，網路上還有許多不同的UI技術，像是能讓「designer」真正自由發揮、免除寫code的SVG browser，也是一個值得注意的技術。</p>

<p>今天要介紹的主角是python-etk，故名思義，這是Python的ETK模組。ETK是一個不錯的東西，全名是Enlightenment Tool Kit，它的功能定位就像是GTK+的角色。GTK+是大名鼎鼎的圖形元件（widget）庫，由GTK+專案所沿伸出來的Glib也是一個使用廣泛的「強化版C程式庫」。ETK有沒有像Glib這樣的東西？有的，叫做Ecore。</p>

<p>Enlightenment（簡稱E）是一個知名且古老的window manager。[<a href="http://www.enlightenment.org/">Enlightenment</a>]包含許多程式庫以及工具，這些程式庫與工具總稱為EFL（Enlightenment Foundation Libraries）。簡單來看，可以畫出EFL的架構如下。</p>

<img alt="efl.png" src="http://www.jollen.org/blog/2008/09/04/efl.png" width="438" height="263" />

<p>EVAS是一個「畫布」程式庫。Ecore的角色如同GTK+的產物Glib，不過並不完全等於。EDJE則是一個「layout engine」。最上面的ETK就是我們的主角，Enlightenment的圖形元件庫。</p>

<p>透過python-etk來實作ETK應用程式，可以帶給我們一些愉快的經驗。要怎麼寫一個向世界問好的入門級python-etk程式呢？以下是一個範例（hello_world.py）：</p>

<blockquote><pre>#!/usr/bin/python

import etk

class MyButton(etk.Button):
	def _size_request(self):
	    return (100, 200)

btn = MyButton(label = "Click Me")
btn.on_clicked(lambda x: etk.main_quit())

# Main
w = etk.Window(title="Hello World", size_request=(150, 150), child=btn)
w.show_all()

def quit(obj):
    etk.main_quit()
w.on_destroyed(quit)

etk.main()</pre></blockquote>

<p>目前有一些知名的Linux手機專案已經開始使用python-etk，例如Openmoko以及Nokia的maemo專案。後續將再配合一個範例來說明hello_world.py程式，及其執行結果。</p>


]]>
      
   </content>
</entry>
<entry>
   <title>Intel 收購 Opened Hand</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/09/intel_buy_opened_hand.html" />
   <id>tag:www.jollen.org,2008:/blog//2.561</id>
   
   <published>2008-09-02T02:19:31Z</published>
   <updated>2008-09-01T23:46:43Z</updated>
   
   <summary>一年多前 [Mobile Linux initiative 成立]，Mobile Linux initiative（或稱為 Moblin community）採用 Intel Atom 平臺，並專注於 Mobile Internet Devices（MIDs）、Netbooks 與其它 embedded devices 的開發。而這個以 Intel Atom 為主的社群，有了重大的變化。 根據 PC World 的一則消息指出：[Intel Buys British Linux Developer Opened Hand]。是的，Intel 買下了知名的軟體開發公司 [OpenedHand]；同一時間，Opened Hand 也在網站上發佈這則消息（引述自 Opened Hand 網站）： We...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[一年多前 [<a href="http://www.jollen.org/blog/2007/07/_intelbased_mobile_linux.html">Mobile Linux initiative 成立</a>]，Mobile Linux initiative（或稱為 Moblin community）採用 Intel Atom 平臺，並專注於 Mobile Internet Devices（MIDs）、Netbooks 與其它 embedded devices 的開發。而這個以 Intel Atom 為主的社群，有了重大的變化。

根據 PC World 的一則消息指出：[<a href="http://www.pcworld.com/businesscenter/article/150520/intel_buys_british_linux_developer_opened_hand.html">Intel Buys British Linux Developer Opened Hand</a>]。是的，Intel 買下了知名的軟體開發公司 [<a href="http://o-hand.com/">OpenedHand</a>]；同一時間，Opened Hand 也在網站上發佈這則消息（引述自 Opened Hand 網站）：

<blockquote>We are pleased to announce that OpenedHand Ltd has been acquired by Intel Corporation. The OpenedHand team will join the Intel Open Source Technology Center and will focus on the development of the Moblin Software Platform, the optimized software stack for Intel Atom processors.

Intel will continue supporting open source projects currently led by OpenedHand staff such as Clutter and Matchbox projects, and in most cases, will accelerate these projects as they become an integral part of Moblin.</blockquote>

Opened Hand 在被 Intel 收購後，將加入 Intel Open Source Technology Center，並且將專注在 Moblin 軟體平臺的發展。Opened Hand 是 GNOME 最重要的 contributor，Opened Hand 帶領的幾個知名專案像是 Clutter 與 Matchbox 等，也將會繼續發展，這些專案在加入 Moblin 後有助於加快其開發速度。

Opened Hand 過去開發過許多知專案，幾個代表性專案有 Nokia Internet Tablets（N770）、OLPC、Vernier，以及 Openmoko。]]>
      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] fork 多個小孩</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/08/fork_n_child.html" />
   <id>tag:www.jollen.org,2008:/blog//2.559</id>
   
   <published>2008-08-23T07:48:08Z</published>
   <updated>2008-08-23T05:11:39Z</updated>
   
   <summary>今天進行「GNU Toolchains &amp; Embedded Linux Programming」課程，在講解 fork 時，有同學問到「能不能 fork 多個 child process」，當然是可以的。後續又有同學問到，「能不能 fork 孫子」，當然也是可以的，只不過，在 child process 裡再 fork child process 並不是很主要的做法，只在一些特殊情況，例如要避免 zombie process 產生時，才會用上。 所以，我們只講解如何 fork 多個 child process 的做法。我們舉了一段 code 當做範例，這段 code 寫得很單純，可以說明 fork 的一些觀念。在這裡，大家必須了解的是「fork 之後」的行為是什麼： 1. parent process...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[今天進行「GNU Toolchains & Embedded Linux Programming」課程，在講解 fork 時，有同學問到「能不能 fork 多個 child process」，當然是可以的。後續又有同學問到，「能不能 fork 孫子」，當然也是可以的，只不過，在 child process 裡再 fork child process 並不是很主要的做法，只在一些特殊情況，例如要避免 zombie process 產生時，才會用上。

所以，我們只講解如何 fork 多個 child process 的做法。我們舉了一段 code 當做範例，這段 code 寫得很單純，可以說明 fork 的一些觀念。在這裡，大家必須了解的是「fork 之後」的行為是什麼：

1. parent process 的執行流程
2. child process 的執行流程

接著將以下的程式（<em>n_fork.c</em>）實際上機執行，並觀察執行結果。

<img alt="n-fork.jpg" src="http://www.jollen.org/blog/2008/08/23/n-fork.jpg" width="606" height="345" />

執行後出現以下結果：

<pre>$ gcc -o n_fork n_fork.c
$ ./n_fork &
This is the child process. PID: 8450
This is the child process. PID: 8451
This is the child process. PID: 8452
Parent process, PID: 8449
Child process ID: 8450 8451 8452</pre>

我們用 <em>pstree</em> 指令來觀察執行之後的系統狀態：

<img alt="nfork-pstree.jpg" src="http://www.jollen.org/blog/2008/08/23/nfork-pstree.jpg" width="388" height="105" />

後續我們會結合一個 Web server 的練習，來展示 fork 多個 child process 的應用。]]>
      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] Symbol Table、objdump 與 ELF 綜合小考</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/08/symbol_table_elf_data_start.html" />
   <id>tag:www.jollen.org,2008:/blog//2.558</id>
   
   <published>2008-08-23T02:47:36Z</published>
   <updated>2008-08-23T01:18:41Z</updated>
   
   <summary>上週進行「GNU Toolchains &amp; Embedded Linux Programming」課程時，最後出了一道考題給同學。題目如下。 請說明上述程式執行後，為什麼會出現以下結果。請將原理描述清楚。 $ gcc -o helo helo.c $ ./helo 0x80495c0 now x = 10 now x = 100 這是一道綜合性的考題，考了很多東西。完全沒有 toolchains 觀念前，同學是一頭霧水，也沒有什麼方向。但是在二天的課程後，從同學繳回的測試卷來看，大家的觀念都已經很健全了。在這裡將題目也提供給大家思考。這是一道不算難的考題，主要考的是「觀念」，並透過「工具的操作」來驗證這些觀念。 觀念的建立絕對是教育訓練最重要的一個環節，也是講師的主要任務，而透過工具的交互操作，來強化課堂觀念，是一個不錯的方法，可以幫助同學記憶。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[上週進行「GNU Toolchains & Embedded Linux Programming」課程時，最後出了一道考題給同學。題目如下。

<img alt="helo.jpg" src="http://www.jollen.org/blog/2008/08/23/helo.jpg" width="280" height="328" />

請說明上述程式執行後，為什麼會出現以下結果。請將原理描述清楚。

<pre>$ gcc -o helo helo.c
$ ./helo
0x80495c0
now x = 10
now x = 100</pre>

這是一道綜合性的考題，考了很多東西。完全沒有 toolchains 觀念前，同學是一頭霧水，也沒有什麼方向。但是在二天的課程後，從同學繳回的測試卷來看，大家的觀念都已經很健全了。在這裡將題目也提供給大家思考。這是一道不算難的考題，主要考的是「觀念」，並透過「工具的操作」來驗證這些觀念。

觀念的建立絕對是教育訓練最重要的一個環節，也是講師的主要任務，而透過工具的交互操作，來強化課堂觀念，是一個不錯的方法，可以幫助同學記憶。]]>
      
   </content>
</entry>
<entry>
   <title>Openmoko 釋出 ASU</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/08/asu_om20088_release.html" />
   <id>tag:www.jollen.org,2008:/blog//2.554</id>
   
   <published>2008-08-12T15:38:04Z</published>
   <updated>2008-08-12T13:37:16Z</updated>
   
   <summary>2008 年 8 月 8 日是北京奧運的開幕日，這一天，也是 Openmoko 推出第三代最新一代手機平臺「Om 2008.8」的日子。Om 2008.8 也稱為 ASU，ASU 是一個專案代號，全名是 April/August Software Update。 ASU 可同時支援 EFL、Qtopia 以及 GTK+ 應用程式，同時也包含一個安裝程式（Installer），可讓使用者自由安裝手機應用軟體，這是過去在校園巡迴課程向同學所介紹的 Openmoko 新的概念，如今終於正式現身了。 ASU 比較另人期待的地方是加入了 EFL 以及 Qtopia，過去 Om 2007.2 是基於 GTK+ 的手機平臺，現在的 Om 2008.8 則是「跳脫」GTK+ 的重要里程碑。ASU 裡有二個值得一提的軟體成果，首先是 Illume。[Illume]...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[2008 年 8 月 8 日是北京奧運的開幕日，這一天，也是 Openmoko 推出第三代最新一代手機平臺「Om 2008.8」的日子。Om 2008.8 也稱為 ASU，ASU 是一個專案代號，全名是 April/August Software Update。

ASU 可同時支援 EFL、Qtopia 以及 GTK+ 應用程式，同時也包含一個安裝程式（Installer），可讓使用者自由安裝手機應用軟體，這是過去在校園巡迴課程向同學所介紹的 Openmoko 新的概念，如今終於正式現身了。

ASU 比較另人期待的地方是加入了 EFL 以及 Qtopia，過去 Om 2007.2 是基於 GTK+ 的手機平臺，現在的 Om 2008.8 則是「跳脫」GTK+ 的重要里程碑。ASU 裡有二個值得一提的軟體成果，首先是 Illume。[<a href="http://wiki.openmoko.org/wiki/Illume">Illume</a>] 是一個能支援 GTK+ 的 window manager，這是 [<a href="www.enlightenment.org">Enlightenment</a>] 裡的一個模組，Illume 讓 enlightenment 的 UI 能在手機上有更好的表現。另外一個重要的軟體成果則是 ASU 能在 X11 環境上執行 Qtopia 的應用程式與服務，並使用上述提及的 Illume 做為 window manager。Illume 能同時支援多種不同的圖形介面程式庫。

<a href="http://wiki.openmoko.org/images/b/bb/OpenmokoFramework08.png" target="_blank"><img src="http://wiki.openmoko.org/images/b/bb/OpenmokoFramework08.png"  border="0" width="680" /></a>
圖：Openmoko 新的 Software Architecture，能同時支援 ELF（enlightenment）、Qtopia（on X11）以及 GTK+ 應用程式。（圖片來源：wiki.openmoko.org）

Neo FreeRunner/ASU 是 Openmoko 至今最重要的產品，雖然軟體與硬體仍然不足以讓 Neo FreeRunner/ASU 成為日常生活用的手機，但 Openmoko 社群對 ASU 仍大多是抱持正面的看法。其他軟體方面的問題，像是最近在社群裡被抱怨的開機時間（boot time）問題，或是已知的其他問題，像是 GSM modem、電池、WiFI driver 等，都是目前努力的工作項目，未來也會有所改善。

從 Om 2007.1 到 Om 2007.2，再由 Om 2007.2 到 ASU/Om 2008.8，接下來 Openmoko 即將推出的好菜為 FSO（FreeSmartphone.Org）。FSO 會是再次令人驚奇的新里程碑。]]>
      
   </content>
</entry>
<entry>
   <title>Linux 驅動程式的 I/O, #4: 什麼是 Blocking I/O</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/08/linux_device_driver_blocking_io.html" />
   <id>tag:www.jollen.org,2008:/blog//2.553</id>
   
   <published>2008-08-04T00:13:33Z</published>
   <updated>2008-08-03T21:21:41Z</updated>
   
   <summary>在先前的專欄中，我們為大家介紹了「I/O」以及「interrupt handling」，接下來我們要將這二個部份合在一起，並討論幾個相當重要的觀念以及機制。首先，我們回到最早在介紹 Linux 驅動程式架構的部份，我們介紹到了 system call 以及 file operations 的觀念；接續 I/O 的部份，我們又提到 read/write system call。到這裡，我們就要融合貫通先前所介紹的重要觀念。請大家先將先前的專欄讀熟，再接續本系列專欄。 在 Linux 驅動程式的整個框架中，最重要，而且必須一開始就先了解的主題有二個： 1. Blocking I/O 的觀念。 2. Wait queue 以及 event-driven（event-polling）的觀念。 雖然這裡分成二個小主題，不過其實這是同樣的一個主題。這裡有很多值得提出討論的觀念，首先針對 Blocking I/O 的觀念進行深度探討。 什麼是 blocking I/O？ 當 user process 透過 read/write system...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Linux Device Drivers &amp; Kernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[在先前的專欄中，我們為大家介紹了「I/O」以及「interrupt handling」，接下來我們要將這二個部份合在一起，並討論幾<!--this article is copyright by www.jollen.org-->個相當重要的觀念以及機制。首先，我們回到最早在介紹 Linux 驅動程式架構的部份，我們介紹到了 system call 以及 file operations 的觀念；接續 I/O 的部份，我們又提到 read/write system call。到這裡，我們就要融合貫通先前所介紹的重要觀念。請大家先將先前的專欄讀熟，再接續本系列專欄。

在 Linux 驅動程式的<!--this article is copyright by www.jollen.org-->整個框架中，最重要，而且必須一開始就先了解的主題有二個：

1. Blocking I/O 的觀念。
2. Wait queue 以及 event-driven（event-polling）的觀念。

雖然這裡分成二個小主題，不過<!--this article is copyright by www.jollen.org-->其實這是同樣的一個主題。這裡有很多值得提出討論的觀念，首先針對 Blocking I/O 的觀念進行深度探討。

<strong>什麼是 blocking I/O？</strong>

當 user process 透過 read/write system call 讀取<!--this article is copyright by www.jollen.org-->硬體資料時，會有哪些情況出現？請注意，這裡講的是「user process」，並不是驅動程式的 system call 實作（driver function、fops->read 或 fops->write）。以 user process 呼叫 read() 來讀取硬體資料的案例來說，當然免不了就是以下的情況：

1. 驅動程式能順利由硬<!--this article is copyright by www.jollen.org-->體拿到資料，並丟到 user-space 給「該」process。
2. 驅動程<!--this article is copyright by www.jollen.org-->式目前無法由硬體拿到資料。怎麼辦？

現在沒辦法馬上由硬體拿到資<!--this article is copyright by www.jollen.org-->料，怎麼辦呢？當然要等待了。驅動程式必須設法等到可以由硬體拿到資料為止，再將資料丟給該 process。試想，現在有一個 process 想要讀取硬體資料，第一次的 read() 很順利地馬上就拿到資料了，可是第二次的 read() 因為硬體的關係，驅動程式暫時無法由硬體取得資料，於是 process 的第二次 read() 並不會立刻結束。

Process 這個時候「停在」第二次的 read() 呼叫，但其實此時，系統的執行位置是來到驅動程式的 read driver function（fops->read），而 fops->read 在待候硬體資料。「Blocking」就是「停住」的意思，所以第<!--this article is copyright by www.jollen.org-->二次的 read() 動作就變成是 blocking I/O。請注意：

1. 這裡一定是討論 user process 是否會停在 read() 或 write()。Blocking I/O 一定要由 user process 的角度討論才會是正確的觀念。
2. 第二次<!--this article is copyright by www.jollen.org-->的 read 是 blocking I/O（blocking operaton），這是「驅動程式的 fops->read 實作」所導致的結果。所以，user process 的 read/write 會不會停住，完全是看 fops->read 與 fops->write 的實作。
3. 我們在這裡只討論驅動程式的 read/write 實作，也就是 user process 存取 device file。

這就是所謂的 blocking I/O。由驅動程式<!--this article is copyright by www.jollen.org-->的角度來看，可以總結如下：

1. 當驅動程式想讓 user process 在呼叫 read() 函數時，都保證能取得資料，此時驅動程式便要實作「當目前尚<!--this article is copyright by www.jollen.org-->無資料可回傳給 user  process 時，便讓 user process 停留等待」的機制（可能是驅動程式尚無法由裝置取得資料）。

2. w當驅動程式想讓 user process 在呼叫 write() 函數時，都保證能寫<!--this article is copyright by www.jollen.org-->入資料，此時驅動程式便要實作「當目前無法寫入資料至裝置時，便讓 user process 停留等待」的機制（可能是裝置尚未 ready）。

讓 user process 停止的方式，涉及排程的觀念，這部份在下一篇日記會接著說明。

<table id="table16" border="0" cellpadding="0" cellspacing="0" width="100%"><tr><td bgcolor="#FF5959"><img alt="" height="1" width="1"></td></tr></table><table id="table14" border="0" cellpadding="2" cellspacing="0" width="100%"><tr><td bgcolor="#FFD8CA"><font size="-1"><b>Also See</b></font></td></tr></table><table id="table15" border="0" cellpadding="2" cellspacing="0" width="100%"><tr><td width="100%"><ul><li>2006.12.22:&nbsp;<a href="http://www.jollen.org/blog/2006/12/inux_device_driver_io_1.html">Linux 驅動程式的 I/O, #1: 基本概念</a></li><li>2006.12.20: <a href="http://www.jollen.org/blog/2006/12/linux_device_driver_io2.html">Linux 驅動程式的 I/O, #2: I/O 存取相關函數</a></li><li>2006.12.20: <a href="http://www.jollen.org/blog/2006/12/linux_device_driver_io_3.html">Linux 驅動程式的 I/O, #3: kernel-space 與 user-space 的「I/O」</a></li></ul></td></tr></table>
                          ]]>
      
   </content>
</entry>
<entry>
   <title>Openmoko 跨出英勇的一步</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/07/openmoko_brave_step.html" />
   <id>tag:www.jollen.org,2008:/blog//2.550</id>
   
   <published>2008-07-26T10:54:09Z</published>
   <updated>2008-07-26T09:05:10Z</updated>
   
   <summary>自從 Openmoko 在7月4日正式發佈新版的 Neo FreeRunner 後，便不斷受到許多西方媒體的矚目與報導，各種聲音也出現在 Openmoko 社群，以及每一個人的網誌上。許多媒體都給予相當正面的評價與報導，對 Openmoko 團隊來說，這絕對是一大鼓舞。當然，好聲音不少，壞聲音也有。像是，Boing Boing 便刊登了一篇對 Openmoko 相當正面的報導： Openmoko open-source cell phone beats Android to the punch 不久前，Internetling 也刊登了一則有關Openmoko 的評論，標題是「3 Reasons Why Everyone will buy one iPhone and not OpenMoko」。一開始的開場白實在犀厲： But unfortunately, people probably...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[自從 Openmoko 在7月4日正式發佈新版的 Neo FreeRunner 後，便不斷受到許多西方媒體的矚目與報導，各種聲音也出現在 Openmoko 社群，以及每一個人的網誌上。許多媒體都給予相當正面的評價與報導，對 Openmoko 團隊來說，這絕對是一大鼓舞。當然，好聲音不少，壞聲音也有。像是，Boing Boing 便刊登了一篇對 Openmoko 相當正面的報導：

<blockquote><a href="http://gadgets.boingboing.net/2008/07/04/openmoko-opensource.html">Openmoko open-source cell phone beats Android to the punch</a></blockquote>

不久前，Internetling 也刊登了一則有關Openmoko 的評論，標題是「<a href="http://www.internetling.com/2008/07/22/3-reasons-why-everyone-will-buy-the-iphone-and-not-openmoko/">3 Reasons Why Everyone will buy one iPhone and not OpenMoko</a>」。一開始的開場白實在犀厲：

<blockquote>But unfortunately, people probably wont buy it...</blockquote>

作者並不是在批評或是「唱衰」Openmoko，反而是以比較中性的來度來看待Openmoko 的努力與成果，我認為這是一篇很有價值的文章，同時也能讓我們能以更多元的角度來思考 Openmoko 的未來。這些不同的聲音與看法，反而是 Openmoko 更應該要正視與關心的。

作者由 marketing、software 以及 users 的角度來評論。首先，以 marketing 的角度來看，Apple 有一個優秀的行銷團隊，但 Openmoko 只有社群，雖然我們都喜歡Openmoko，可是沒有什麼驅動力讓一般大眾購買 Openmoko 手機，大家會買的是iPhone。Openmoko 只能透過口耳相傳（word of mouth）的模式進行。

接著，由 software 的角度來看，FreeRunner 比起之前的 Neo1973 好很多了，但仍然「unreliable」。「Openmoko 並不是 Nokia，他們名號不大。」作者提到。「要有大變革，不要賣一個無法和 iPhone 相比的產品。」

最後是由 users 的角度來看，Linux 很令人敬畏，「但有誰告訴過他外婆，這個長相可疑的手機，比 iPhone 還好？」iPhone 做到了完全創新，也有好看的介面。「這些潛在的信眾（Linux 愛好者）並不信任你並且也不在乎。」這是一場辛苦的戰爭，但Linux 最終會立足於 hand-held 市場。「我們需要的是時間，只是現在時機不對。」但作者最後還是給予 Openmoko 團隊正面的評價：

<blockquote>but let us still cheer the OpenMoko team on for making a brave step forward. </blockquote>

從作者的口吻來看，他似乎希望大家等待 Linux 手機時代的到來。「why wait for the Year of the Linux Phone…」。

或許，大家也發現了，Neo FreeRunner 現階段還是定位給開發者使用的手機，並不符合與該作者的論述出發點。但是，不管作者是否了解 Openmoko 的商業模式，也不管這些論點是否符合 Openmoko 的 roadmap，出現在網路上的看法，就是外界對 Openmoko 的看法。因此，如果這些觀點與 Openmoko 的想法不符，那麼對 Openmoko 團隊來說，更重要的工作就不是做手機，而是「更正確地傳達理念」。

英勇的第一步已經邁出，希望 Openmoko 往當初的理想與目標繼續邁進。加油。]]>
      
   </content>
</entry>
<entry>
   <title>可以開機就好：談作業系統的基礎訓練</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/07/linux-kernel-from-scratch.html" />
   <id>tag:www.jollen.org,2008:/blog//2.549</id>
   
   <published>2008-07-24T07:50:52Z</published>
   <updated>2008-07-24T05:31:53Z</updated>
   
   <summary>最近在和朋友在討論 Embedded Linux 課程的規劃事宜，希望可以歸納過去所收集的學員意見，以及就助教所提出的課堂問題，對現有課程做調整以及精進。二個星期前，和 thinker 以及 dennis 在聊課程時，興起了一個念頭，我們想要規劃一門「作業系統」的課程。 過去的教育訓練發現，有些學員對於作業系統的背景知識不足，也有些學員對於 Linux kernel 的原理很有興趣，更有些學員對如何寫一個 OS 感興趣，但，由於沒有系統化的文件提供這方面的資訊，因此，讓大家只能由片斷的文件（googling）自己拼湊相關知識，不但沒有效率，而且也經常徒勞無功。 我們想要做的「作業系統」課程，可不是把「恐龍書」搬出來教一教就行了，而是希望走「實務」路線，因此，thinker 提出了一個想法：教大家做一個「只能開機」的 OS。我跟 dennis 都覺得這是一個很不錯的構想，透過「建構式」教學，讓大家從無到有自己寫一個作業系統，這個作業系統也不需要很完整，只要能做到「可以開機」就好了。 昨天晚上，大家再次聚會，再討論了這個「boot only」的 OS。「從無到有自己寫」是一個不太可行的做法，畢竟訓練時數有限，況且「有現成的 Linux kernel」可以用，因此，「從 Linux kernel 剪貼程式碼來做一個新的 OS」是一個最具體可行的做法，也是大家的共識。 透過由 Linux kernel「copy-and-paste」程式碼，拼裝出一個 OS，是一件有意義的事情。雖然是一個拼裝的 OS，但是要讓它可以動，就要了解處理器架構，以及整個開機流程，而且也要知道「要讓一個 OS 可以開機，至少要實作什麼單元。」這是一件有趣的事，大家興趣都來了，一陣技術討論後，很快地，在不到一個小時內，我們就把主題都抓出來了。初步的構想如下。 要知道 Linux kernel 的開機流程，就要有一個學習環境，我們一致認為，透過 Qemu...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Linux Device Drivers &amp; Kernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[最近在和朋友在討論 Embedded Linux 課程的規劃事宜，希望可以歸納過去所收集的學員意見，以及就助教所提出的課堂問題，對現有課程做調整以及精進。二個星期前，和 thinker 以及 dennis 在聊課程時，興起了一個念頭，我們想要規劃一門「作業系統」的課程。

過去的教育訓練發現，有些學員對於作業系統的背景知識不足，也有些學員對於 Linux kernel 的原理很有興趣，更有些學員對如何寫一個 OS 感興趣，但，由於沒有系統化的文件提供這方面的資訊，因此，讓大家只能由片斷的文件（googling）自己拼湊相關知識，不但沒有效率，而且也經常徒勞無功。

我們想要做的「作業系統」課程，可不是把「恐龍書」搬出來教一教就行了，而是希望走「實務」路線，因此，thinker 提出了一個想法：教大家做一個「只能開機」的 OS。我跟 dennis 都覺得這是一個很不錯的構想，透過「建構式」教學，讓大家從無到有自己寫一個作業系統，這個作業系統也不需要很完整，只要能做到「可以開機」就好了。

昨天晚上，大家再次聚會，再討論了這個「boot only」的 OS。「從無到有自己寫」是一個不太可行的做法，畢竟訓練時數有限，況且「有現成的 Linux kernel」可以用，因此，「從 Linux kernel 剪貼程式碼來做一個新的 OS」是一個最具體可行的做法，也是大家的共識。

透過由 Linux kernel「copy-and-paste」程式碼，拼裝出一個 OS，是一件有意義的事情。雖然是一個拼裝的 OS，但是要讓它可以動，就要了解處理器架構，以及整個開機流程，而且也要知道「要讓一個 OS 可以開機，至少要實作什麼單元。」這是一件有趣的事，大家興趣都來了，一陣技術討論後，很快地，在不到一個小時內，我們就把主題都抓出來了。初步的構想如下。

要知道 Linux kernel 的開機流程，就要有一個學習環境，我們一致認為，透過 Qemu 模擬器與 gdb 進行 source-level debug 會是一個很不錯的做法，而且也可以在拼湊的同時，透過 Qemu 來測試與除錯；最後再將拼裝好的 OS 實際放到開發板上做測試。我們自己的 JK2410 開發板，同時也提供 JK2410 模擬器，所以可以繼續延用我們的「<a href="http://wiki.jk2410.org">Jollen-Kit! 嵌入式系統專用學習平臺</a>」。

有了學習環境後，就可以開始討論「最小型的作業系統」需要實作什麼功能。理論來說，實作出 clock、IRQ handler、virtual memory 以及 context-switch 就可以讓 OS 開機，並且提供「最最最」簡單的功能，比如「Hello, World!」。要能成功 copy-and-paste 出可放到 ARM9 開發板開機的 OS，除了要對 Linux kernel 的 BSP 本身很熟悉外，也要對這些技術的實作細節掌握得很好，所以，用 Linux kernel 來從無到有打造一個自己的 OS 可說是一舉三得的方法：

1. 可以了解 Linux 的 BSP（board-support package）做法，以及開機流程。
2. 可以了解 ARM architecture。
3. 可以學習最根本的 OS 理論與技術。

目前，我們已經完成課程的規劃，不久後也會完成講義的初步規劃。這是一個頗有意義的主題，而且也是一個很好的學習途徑，希望對這個主題有興趣的朋友，可以提供意見或想法給我們。

]]>
      
   </content>
</entry>
<entry>
   <title>Process State 與 Wait Queue</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/07/process_state_wait_queue.html" />
   <id>tag:www.jollen.org,2008:/blog//2.545</id>
   
   <published>2008-07-17T15:52:48Z</published>
   <updated>2008-07-17T22:34:35Z</updated>
   
   <summary>本週要繼續進行 Linux Device Driver 的教育訓練，正好上週有同學問到「process 狀態」的問題，原因是我們在講解範例時，提到 O&apos;Reilly 的 Linux Device Driver 書上以「half sleep」來說明「手動變更 current 狀態」的做法，以及為何不直接呼叫 sleep_on() API 的原因。 當時只做了相當簡要的回答，同學也對 OS 書上講到的 process state 有些不了解。本週打算做比較深入的討論，結果發現我的 Linux Kernel 專欄休眠許久，「Process State」這個章節居然還沒有整理上來，因此在這裡補上這個部份，以免上課要講解時無料可用。 Process 的狀態（state）紀錄在 process descriptor 的 state 欄位。如果您對 process、fork（process creation）以及 preemptive 不熟悉的話，建議您先從頭依序閱讀「Linux Kernel...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Linux Device Drivers &amp; Kernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本週要繼續進行 Linux Device Driver 的教育訓練，正好上週有同學問到「process 狀態」的問題，原因是我們在講解範例時，提到 O'Reilly 的 Linux Device Driver 書上以「half sleep」來說明「手動變更 current 狀態」的做法，以及為何不直接呼叫 sleep_on() API 的原因。

當時只做了相當簡要的回答，同學也對 OS 書上講到的 process state 有些不了解。本週打算做比較深入的討論，結果發現我的 Linux Kernel 專欄休眠許久，「Process State」這個章節居然還沒有整理上來，因此在這裡補上這個部份，以免上課要講解時無料可用。

Process 的狀態（state）紀錄在 process descriptor 的 <em>state</em> 欄位。如果您對 process、fork（process creation）以及 preemptive 不熟悉的話，建議您先從頭依序閱讀「<a href="http://www.jollen.org/Linux_Kernel/">Linux Kernel 專欄</a>」裡的文章，才能對以下的 process state 轉換圖產生一點感覺。

<img alt="process_states.png" src="http://www.jollen.org/blog/2008/07/18/process_states.png" width="645" height="285" />

Linux 系統透過 fork system call 建立新的 process，當 process 被生出來後，他的狀態就是「執行中狀態」，也就是 TASK_RUNNING。不過 process 產生後，並不是馬上就能執行，必須被排程器挑選後做 context switch 才是「正在執行中」的 process。我們以 <em>current</em> 代表「正在執行中」的那一個 process，前面所謂的執行中狀態指的是被放在 task queue / run queue（OS 叫 ready queue）中的 process。當 <em>current </em>正在執行時，很可能被其他 priority 更高的 process 搶奪執行權，這時 <em>current</em> 就會被放回 ready queue 裡，這是因為 Linux 是一個可搶先（preemptive）排程的作業系統。

好了，今天 <em>current</em> 要存取硬體，這時如果硬體裝置出現問題，無法讀寫資料，此時「Linux 驅動程式必須把<em> current </em>放到 wait queue 裡睡覺（等待）」。

Wait queue 就是用來讓 <em>current</em> 睡覺的 kernel API。

Process 被放到 wait queue 時的狀態為 TASK_INTERRUPTIBLE 或是 TASK_UNINTERRUPTIBLE。這個時候因為我們的 process 在睡覺了（被放到 wait queue），所以 scheduler 就會再由 ready queue 裡挑一個 process 來執行。

Wait queue 裡的 process 怎麼辦？

睡著的 process 必須被叫醒（wake up），這個動作一般是在 interrupt handler 裡做的。當 process 被叫起來後，狀態再度切換成 TASK_RUNNING 了，於是，又得到被 scheduler 挑選執行的權力了。

Process state 的定義可以在 include/linux/sched.h 裡找到（以下適用 2.6.24 版本以前）：

<blockquote>#define TASK_RUNNING            0<br />
#define TASK_INTERRUPTIBLE      1<br />
#define TASK_UNINTERRUPTIBLE    2</blockquote>

Kernel 也提供了一個 API 可用來設定 <em>current</em> 的狀態：

<blockquote>set_current_state(state_value) </blockquote>

在驅動程式裡手動變更 process state 的目的是為了將 process 放到 wait queue 並達到 critical section 的效果。]]>
      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] 入門 ARM9 平臺 Linux 驅動程式的基本功</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/07/goto_arm_linux_device_drivers.html" />
   <id>tag:www.jollen.org,2008:/blog//2.541</id>
   
   <published>2008-07-13T06:27:10Z</published>
   <updated>2008-07-13T10:21:05Z</updated>
   
   <summary>本週進行「Linux Device Drivers」訓練課程，開始帶領學員在 JK2410 開發板上實際撰寫硬體控制的程式碼。前一階段課程費了許多功夫解釋整個架構和觀念，這部份是與硬體無關的主題，主要針對 Linux 作業系統本身的實作與機制做觀念解說，例如：scheduling（為什麼要使用 wait queue 做 I/O 排程、以及使用時機）、critical section 等等。 我們花了一點時間幫同學建立基本概念，主要都是基本功的訓練，整理如下： 1. JK2410 開發板的操作：如何下載 kernel 與 rootfs 到開發板。 2. Kernel 編譯與設定：toolchain 的取得與安裝、Linux kernel 原始碼的取得、如何設定 kernel、如何包裝成 u-boot 格式。 3. 如何將 cdata 移植到 kernel source tree：透過 Config.in（2.4 kernel）與...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      本週進行「Linux Device Drivers」訓練課程，開始帶領學員在 JK2410 開發板上實際撰寫硬體控制的程式碼。前一階段課程費了許多功夫解釋整個架構和觀念，這部份是與硬體無關的主題，主要針對 Linux 作業系統本身的實作與機制做觀念解說，例如：scheduling（為什麼要使用 wait queue 做 I/O 排程、以及使用時機）、critical section 等等。

我們花了一點時間幫同學建立基本概念，主要都是基本功的訓練，整理如下：

1. JK2410 開發板的操作：如何下載 kernel 與 rootfs 到開發板。

2. Kernel 編譯與設定：toolchain 的取得與安裝、Linux kernel 原始碼的取得、如何設定 kernel、如何包裝成 u-boot 格式。

3. 如何將 cdata 移植到 kernel source tree：透過 Config.in（2.4 kernel）與 Makefile 的修改，將過去辛苦從零寫起的 cdata 驅動程式移植到 kernel 原始碼目錄裡。目前我們的做法是，將 cdata 範例與 kernel 編譯成一個 image 檔，理由是，現階段暫時不去碰 root filesystem。

4. 在 JK2410 開發板上實際把玩 cdata 範例，過去我們都是在 PC 端操作，這次終於能將 cdata 移植到 ARM9 開發板上，並實際操作了。

我們在編譯 kernel 的過程中，也機會教育同學如何思考並解決一些編譯時的錯誤：

5. 如何選擇正確的驅動程式，例如：JK2410 的 serial driver。

6. linking 階段的錯誤（undefined reference）以及解決問題的思考邏輯。

7. compiling 階段的錯誤，以及解決問題的思考邏輯。

這些都是課程由 host 端進入到 target 端（ARM9）時，同學必須要具備的基本功夫，大家可將以上 7 點做為基本能力檢核的 check list。
      
   </content>
</entry>
<entry>
   <title>千呼萬喚 Neo FreeRunner 正式上市</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/07/neo_freerunner_onsale.html" />
   <id>tag:www.jollen.org,2008:/blog//2.540</id>
   
   <published>2008-07-04T03:42:17Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>千呼萬喚始出來，第一個開放式的行動通訊平臺 Openmoko 今天正式展開第二代手機產品 Neo FreeRunner 的線上銷售。Openmoko 的官方新聞稿已經發佈在這裡了 [Openmoko Declares Independence for the Mobile Phone]，特別選在獨立紀念日開放 Neo FreeRunner 訂購，正意味著 Openmoko 將在手機市場裡「獨立」走出自己的路，Openmoko 在行動通訊界做了一個革新，這個革新代表的是手機終於獲得真正的自由。 與之前銷售 Neo1973 不同的地方是，Openmoko 這次除了透過線上直銷外，在印度、德國、法國與英國的朋友也能向當地代理商購買 Neo FreeRunner。 距離上次 Openmoko 推出第一代產品 Neo1973 已經過了好長一段時間了，這些日子裡，行動通訊產業發生了許多大事，像是開放手機平臺（如 Android）概念的興起，以及觸控螢幕手機（如 iPhone）的流行，都讓大家有一種耳目一新的感覺。 Openmoko 呢？ 這段時間，Openmoko 除了面臨外在的挑戰外，內部也有很大的調整與改變，但不管怎麼樣，我們相信結果是好的，社群開發者也更積極參與 Openmoko 平臺的開發，而且我們也看到了 Openmoko...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[千呼萬喚始出來，第一個開放式的行動通訊平臺 Openmoko 今天正式展開第二代手機產品 Neo FreeRunner 的線上銷售。Openmoko 的官方新聞稿已經發佈在這裡了 [<a href="http://www.openmoko.com/press/Openmoko_20080702.pdf">Openmoko Declares Independence for the Mobile Phone</a>]，特別選在獨立紀念日開放 Neo FreeRunner 訂購，正意味著 Openmoko 將在手機市場裡「獨立」走出自己的路，Openmoko 在行動通訊界做了一個革新，這個革新代表的是手機終於獲得真正的自由。

<img alt="freerunner_onsale.PNG" src="http://www.jollen.org/blog/2008/07/04/freerunner_onsale.PNG" width="554" height="255" />

與之前銷售 Neo1973 不同的地方是，Openmoko 這次除了透過線上直銷外，在印度、德國、法國與英國的朋友也能向當地代理商購買 Neo FreeRunner。

距離上次 Openmoko 推出第一代產品 Neo1973 已經過了好長一段時間了，這些日子裡，行動通訊產業發生了許多大事，像是開放手機平臺（如 Android）概念的興起，以及觸控螢幕手機（如 iPhone）的流行，都讓大家有一種耳目一新的感覺。

Openmoko 呢？

這段時間，Openmoko 除了面臨外在的挑戰外，內部也有很大的調整與改變，但不管怎麼樣，我們相信結果是好的，社群開發者也更積極參與 Openmoko 平臺的開發，而且我們也看到了 Openmoko 更進一步將 Neo 手機的機構設計以 CC 授權公開了。許多革新的做法，不斷讓大家看到這個開源手機專案的獨特之處。

Openmoko 還有一個與過去不同的地方。現在的 Openmoko 特別著重學校教育，在 Openmoko 新版的網站上可以看到有一個 [<a href="http://www.openmoko.com/opportunities-universities.html">University</a>] 的頁面，Openmoko 特別關心學校方面的研究計畫，不管是軟體或是設計，都能向 Openmoko 公司或是 Openmoko 社群取得一些幫助。過去 Openmoko 在台灣也與多所大學有所接觸，許多老師與同學對於使用 Neo 手機來製作專題都表達高度興趣，目前也有一些小成績，下學期希望能夠和大家分享這些同學的研究成果。

]]>
      
   </content>
</entry>
<entry>
   <title>Google 手機計畫的腳步慢下來了</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/06/android_slowed_carrier.html" />
   <id>tag:www.jollen.org,2008:/blog//2.537</id>
   
   <published>2008-06-24T03:11:08Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>在 The Wall Street Journal 上的一篇文章指出「Google 手機計畫的腳步慢下來了」，有興趣的朋友可參考原文 [Google&apos;s Mobile-Handset Plans Are Slowed]。原因是 carrier 仍與 Android 平臺奮戰中。以下是一些重點掃描，還有些許自已的想法。 Wireless carriers 要的是可以支援自家網路服務的行動裝置，而不是銷售支援其他網路服務的手機，或是自已的網路服務只是該手機的「附加功能」。由此文章也可以看出，這樣的需求，讓 wireless carriers 也開始要求手機製造商製造「branded phones」。即使像 Samsung 這樣的手機製造大廠，也面臨 carrier 要求掛品牌的問題，這方面 Samsung 並沒有什麼回應。 手機品牌廠面臨的一個問題是，當使用者需要的是能提供網路服務的手機時，勢必要和 carrier 建立良好的合作關係。當 carrier 提出的規格，是要求掛自家品牌時，像 Samsung 這樣的手機廠就會面臨一些壓力。從另一個角度來看，手機製造商（handset makers）有了另一個不錯的機會。 提供客製化的應用程式與 UI，以支援不同的網路服務，這是 carrier...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Open Mobile Platform" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[在 The Wall Street Journal 上的一篇文章指出「Google 手機計畫的腳步慢下來了」，有興趣的朋友可參考原文 [<a href="http://online.wsj.com/article/SB121418837707895947.html">Google's Mobile-Handset Plans Are Slowed</a>]。原因是 carrier 仍與 Android 平臺奮戰中。以下是一些重點掃描，還有些許自已的想法。

Wireless carriers 要的是可以支援自家網路服務的行動裝置，而不是銷售支援其他網路服務的手機，或是自已的網路服務只是該手機的「附加功能」。由此文章也可以看出，這樣的需求，讓 wireless carriers 也開始要求手機製造商製造「branded phones」。即使像 Samsung 這樣的手機製造大廠，也面臨 carrier 要求掛品牌的問題，這方面 Samsung 並沒有什麼回應。

手機品牌廠面臨的一個問題是，當使用者需要的是能提供網路服務的手機時，勢必要和 carrier 建立良好的合作關係。當 carrier 提出的規格，是要求掛自家品牌時，像 Samsung 這樣的手機廠就會面臨一些壓力。從另一個角度來看，手機製造商（handset makers）有了另一個不錯的機會。

提供客製化的應用程式與 UI，以支援不同的網路服務，這是 carrier 使用 Android 平臺的原因。他們希望能發展客製化的 Android 應用程式，以推廣自已的網路服務，並透過服務來收費。但是在客製化 Android 軟體時，不但自已糟遇到一些問題，連手機製造商也面臨一些技術難題。

有些手機製造商花出比原先預期更多的時間，在整合與測試 Android 平臺。同時，依照 carrier 所提出的規格進行 UI 客製化時，也花費更多的時間。這是造成 Android 手機延誤上市的原因之一。

Google 必須召集更多的硬體、服務與軟體供應商來支援 Android 平臺。Google 必須解決他的 3rd party 目前所面臨的一些技術問題，這些都造成 Android 軟體發展上的沈重負擔。

為 wireless carrier 製造手機裝置是開放手機平臺公司的另外一個選擇，carrier 想要自有品牌的手機，並且想要使用 Android 平臺發展客製化的軟體平臺與 UI，以提供自有品牌的服務，而不是提供一支只有 Android 原有功能的手機。Carrier 正在思考如何提供使用者一個易於存取自有網路服務的行動裝置，看起來開放手機平臺的確有很好的機會。

 ]]>
      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] 從 kernel-space 讀取 user-space 的字串</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/06/write_driver_function.html" />
   <id>tag:www.jollen.org,2008:/blog//2.536</id>
   
   <published>2008-06-22T03:47:40Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>User application 使用 write() 函數將字串寫到裝置檔，所以在 driver 裡頭，就要實作 write system call。當字串的傳遞是透過 write system call 寫至 kernel-space 時，driver 就要使用 copy_from_user() 來讀取 user-space 的字串。以下是一個簡單的 write driver function 實作參考，此實作提供由 kernel-space 讀取 kernel-space 字串的方法，當然這裡頭包含諸多隱含在程式裡的重要關念，例如： 1. user-space page 是 valid 或 invalid。 2. 讓不同 device file...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[User application 使用 write() 函數將字串寫到裝置檔，所以在 driver 裡頭，就要實作 write system call。當字串的傳遞是透過 write system call 寫至 kernel-space 時，driver 就要使用 copy_from_user() 來讀取 user-space 的字串。以下是一個簡單的 write driver function 實作參考，此實作提供由 kernel-space 讀取 kernel-space 字串的方法，當然這裡頭包含諸多隱含在程式裡的重要關念，例如：

1. user-space page 是 valid 或 invalid。
2. 讓不同 device file 擁有私有資料結構的做法。
3. 同一個 process 在重覆進入 write driver function 時的同步問題尚未考慮，簡單來說就是同步問題還沒考慮到。

程式片段如下：

<pre>ssize_t card_write(struct file *filp, const char *buff, 
		size_t count, loff_t *offp)
{
	struct cdata_s *cdata = (struct cdata_s *)filp->private_data;
	char *str = cdata->buffer;
	int idx = cdata->idx;
	int i;
 
	if (count == 0 || count > 64) 
		goto fail1;
 
	/* get data from user-space */
	for (i = 0; i < count; i++) {
		if (idx >= 64) {
			printk(KERN_ALERT "cdata: buffer full.\n");
			goto fail2;
		}
		if (copy_from_user(str+idx, buff+i, 1))
			goto fail2;
		idx++;
	}
 
fail1:
	cdata->idx = idx;
	return 0;
fail2:
	cdata->idx = idx;
	return -EFAULT;
}</pre>

課堂中提到，這是一個 nonblocking write 的實作，後續可加入一些機制來處理 buffer full 的狀況。]]>
      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] 呼叫 kmalloc(GFP_KERNEL) 的函數要可以重覆進入</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/06/kmalloc_reentrant.html" />
   <id>tag:www.jollen.org,2008:/blog//2.535</id>
   
   <published>2008-06-22T02:10:46Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>使用 kmalloc() 時，要特別注重的是「可重覆進入」的觀念。kmalloc() 的第二個參數稱為 allocation flag，用來控制 kmalloc() 的行為，當此參數有指定 GFP_KERNEL 旗標時，kmalloc() 就是一個 blocking function。 使用 GFP_KERNEL 旗標來配置記憶體時，為什麼會有可重覆進入的議題呢？主要的關鍵在於，當 kmalloc(..., GFP_KERNEL) 無法配置記憶體時，便會做「等待」的動作，這個等待的動作是對「current process」做重排程，並等候記憶體空間。 以 open driver function 來看，通常我們會在 open driver function 裡做記憶體的配置，當記憶體目前無法取得時，open driver function 便會停止（等待），因此不會完成這一次的函數呼叫（沒有 return），此時，同一個 open driver function 會不會再被「重覆」呼叫執行呢？當然會。因為，可能會有另一個 process 去開啟 major...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[使用 kmalloc() 時，要特別注重的是「可重覆進入」的觀念。kmalloc() 的第二個參數稱為 allocation flag，用來控制 kmalloc() 的行為，當此參數有指定 GFP_KERNEL 旗標時，kmalloc() 就是一個 blocking function。

使用 GFP_KERNEL 旗標來配置記憶體時，為什麼會有可重覆進入的議題呢？主要的關鍵在於，當 kmalloc(..., GFP_KERNEL) 無法配置記憶體時，便會做「等待」的動作，這個等待的動作是對「current process」做重排程，並等候記憶體空間。

以 open driver function 來看，通常我們會在 open driver function 裡做記憶體的配置，當記憶體目前無法取得時，open driver function 便會停止（等待），因此不會完成這一次的函數呼叫（沒有 return），此時，同一個 open driver function 會不會再被「重覆」呼叫執行呢？當然會。因為，可能會有另一個 process 去開啟 major number 相同的裝置檔，因此，同一個 open driver function 又被呼叫了，但是前一次的呼叫卻還在等待。

當函數第二次被呼叫時，第一次的呼叫還沒有結束執行，所以，函數「重覆」進來執行了。

延伸閱讀

2008.04.20: <a href="http://www.jollen.org/blog/2008/04/private_data_and_reentrant_function.html">[教育訓練紀錄] 關於驅動程式的 private data 與可重覆進入函數</a>]]>
      
   </content>
</entry>
<entry>
   <title>Open Source in Mobile 2008 今年更盛大了</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/06/osim_2008.html" />
   <id>tag:www.jollen.org,2008:/blog//2.534</id>
   
   <published>2008-06-21T15:14:31Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>[OSiM World（Open Source in Mobile 2008）] 將於九月17-18日於德國 Berlin 舉行，將有超過 100 位來自 Open Source Mobile 生態系統（ecosystem）的不同產業界重量級講者，為大家帶來各種不同的講題。OSiM 可說是全世界最大且影響力最強的 Open Source Mobile 研討會，有超過 42 個國家的與會者以及不同產業的領域者將出席此會議，今年的 OSiM 可說是 Open Source Mobile 的領導級活動。 倒底有哪些重量級人物將發表演說，查了一下 [Speakers] 果然不是蓋的，像是： * Ari Jaaksi - Nokia / Open Source Operations...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[[<a href="http://www.osimworld.com">OSiM World（Open Source in Mobile 2008）</a>] 將於九月17-18日於德國 Berlin 舉行，將有超過 100 位來自 Open Source Mobile 生態系統（ecosystem）的不同產業界重量級講者，為大家帶來各種不同的講題。OSiM 可說是全世界最大且影響力最強的 Open Source Mobile 研討會，有超過 42 個國家的與會者以及不同產業的領域者將出席此會議，今年的 OSiM 可說是 Open Source Mobile 的領導級活動。

倒底有哪些重量級人物將發表演說，查了一下 [<a href="http://www.osimworld.com/newt/l/handsetsvision/osim08/speakers.html">Speakers</a>] 果然不是蓋的，像是：

* Ari Jaaksi - Nokia / Open Source Operations 的 Director
* hristy Wyatt - Motorola / Software Platform & Ecosystem 的 Vice President
* Morgan Gillis - LiMo Foundation 的 Executive Director
* Benoit Schillings - Trolltech 的 Chief Technical Officer

當然，Openmoko 也沒有缺席此項盛會。Openmoko 的 founder Sean Moss-Pultz 也會出席發表演說。又看了一下 [<a href="http://www.osimworld.com/newt/l/handsetsvision/osim08/agenda_d1.html">Agenda Day 1</a>] 以及 [<a href="http://www.osimworld.com/newt/l/handsetsvision/osim08/agenda_d2.html">Agenda Day 2</a>] 二天的議程，「果然犀利」，其中有一個議程是我特別感興趣的：

<blockquote>Raising Operator Confidence in Open Source, Guido Arnone, Director,Terminals Technology Vodafone

    * What is the benefit of Open Source for Operators?
    * What reservations are there about Open Source?
    * Understanding what the Operator wants to hear
    * Are Operators comfortable outside the walled garden?</blockquote>

由「operator」的角度來看「Open Source」絕對是一件有意思的事。
]]>
      
   </content>
</entry>
<entry>
   <title>Google 說 Android 將會 100% 開放源碼</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/06/google_android_full_opensource.html" />
   <id>tag:www.jollen.org,2008:/blog//2.531</id>
   
   <published>2008-06-05T00:48:08Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>過去大家經常在討論「Android 不是 100% 開放源碼」，但 Google 目前已做了正式的解釋，Google 表示「the core Android platform will be 100% open source」這又將掀起大家對 Android 的另一波討論。 報導表示，在與多位 Google 員工確認後知道「everything will be opened」，並且所有核心部份也都將採用 Apache software license (ASLv2)，非 core Android 部份的授權則不一定採用 ASLv2。Android 平臺是基於 Embedded Linux 系統，在 Embedded Linux 平臺上，大部份 FOSS 軟體原本就採用...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Open Mobile Platform" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[過去大家經常在討論「Android 不是 100% 開放源碼」，但 Google 目前已做了正式的解釋，Google 表示「<a href="http://www.searchenginejournal.com/google-says-android-will-be-100-open-source/7012/">the core Android platform will be 100% open source</a>」這又將掀起大家對 Android 的另一波討論。

報導表示，在與多位 Google 員工確認後知道「everything will be opened」，並且所有核心部份也都將採用 Apache software license (ASLv2)，非 core Android 部份的授權則不一定採用 ASLv2。Android 平臺是基於 Embedded Linux 系統，在 Embedded Linux 平臺上，大部份 FOSS 軟體原本就採用 GPLv2 的授權，這個部份當然不會有所變動。與 Eclipse 相關的軟體，例如 ADT (Android Development Tools plug-in) 採用的是 Eclipse Public License (EPL)。

雖然 core Android platform 將會 100% open source，但要了解的重要觀念是：

<blockquote>The core Android system will be open source, but there’s no guarantee that carrier,s OEMs and application developers will keep their applications open source.</blockquote>

開放手機平臺的演化又再進一步了。]]>
      
   </content>
</entry>
<entry>
   <title>Linux WiMAX Driver 實作現況分析</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/06/linux_wimax_driver.html" />
   <id>tag:www.jollen.org,2008:/blog//2.530</id>
   
   <published>2008-06-01T15:20:11Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>前陣子接受 DigiTimes 的「手持行動裝置開發關鍵軟體技術發展」研討會邀請，當時就在思考要以什麼主題為主。一些題目大概都是老生常談了，而且又不想以介紹性的方式進行。想了又想，發現最近最當紅的主題非 WiMAX 莫屬，WiMAX 也是今年 Computex 展的主題，因此決定以 Intel 的 [Linux WiMAX development project] 專案做為討論標的。5 月 29 日這一天的演講就以「Linux WiMAX Driver 實作現況分析」定題了。 linuxmax.org 是 Intel 所支持的一個專案計畫，此計畫目前已釋出第一個 WiMAX device driver 以及 WiMAX stack。目前在 linuxwimax.org 上已能找到 Intel WiMAX Connection 2400m 的驅動程式，以及一個 WiMAX stack...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Linux Device Drivers &amp; Kernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[前陣子接受 DigiTimes 的「手持行動裝置開發關鍵軟體技術發展」研討會邀請，當時就在思考要以什麼主題為主。一些題目大概都是老生常談了，而且又不想以介紹性的方式進行。想了又想，發現最近最當紅的主題非 WiMAX 莫屬，WiMAX 也是今年 Computex 展的主題，因此決定以 Intel 的 [<a href="http://linuxwimax.org">Linux WiMAX development project</a>] 專案做為討論標的。5 月 29 日這一天的演講就以「Linux WiMAX Driver 實作現況分析」定題了。

linuxmax.org 是 Intel 所支持的一個專案計畫，此計畫目前已釋出第一個 WiMAX device driver 以及 WiMAX stack。目前在 linuxwimax.org 上已能找到 Intel WiMAX Connection 2400m 的驅動程式，以及一個 WiMAX stack 驅動程式（subsystem）。2400m 是一個符合 mobile WiMAX 標準的 WiMAX chipset，mobile WiMAX 是行動 WiMAX 的一個標準（802.16e），主要給行動裝置使用。

當天的演講投影片可由此下載 [<a href="http://tw.jollen.org/slides/introduction_wimax_driver.pdf">introduction_wimax_driver.pdf</a>]。雖然定題為「Linux WiMAX Driver 實作現況分析」，不過若以 device driver 的角度來看，其實會變得比較像是在講 USB 與 network device 的 subsystem。若是以整個架構來看，WiMAX driver 在分層設計這裡已經有很不錯的實作，包含以下二個部份：

1. 透過 netlink layer 做為 user-to-kernel 的介面，在 application 端也有 API 的實作，可透過 libnl 來操作 WiMAX 的設定。
2. 針對 device driver 提供分層架構設計：<em>struct wimax_dev</em> 以及 <em>wimax_dev_add()</em>。

另外，為了解 WiMAX driver 與 kernel-space 的緊密性關性，我們透過了 2400m 的驅動程式來分析其架構關係，以及 I/O 處理方法。初步了解，WiMAX device driver 仍是透過 transport layer 來做處理，WiMAX stack 目前只提供 netlink layer 給下層的裝置驅動程式。其餘部份大略整理於投影片中，請指教。]]>
      
   </content>
</entry>
<entry>
   <title>Richard Stallman 台灣行第四天紀錄: 5/15 演講實紀</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/05/richard_stallman_speech_nthu.html" />
   <id>tag:www.jollen.org,2008:/blog//2.522</id>
   
   <published>2008-05-22T03:40:24Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>這次的演講地點是清華大學的大禮堂，這是一個又大又舒適的場地，大家都能坐在舒服的軟椅上聽演講。我們在入口處設置了「義賣處」，專賣由 Free Software Foundation 遠渡重洋寄來的一些小玩意兒，我們也依照 Richard 的意思，在現場義賣他自己的書。 今天的主題是自由軟體運動，以及 GNU/Linux operating system，這場演講其實我並沒有很專心在聽講（*汗*），因為一直不斷地在會場穿梭。不過，有許多這天來聽演講的朋友，都在自已的 blog 上做了很不錯的紀錄，他們的紀錄會比較有參考價值： * 2008-05-21: E-Mate News: A talk from Richard Stallman * 2008-05-19: Hialan&apos;s Blog: 5/15 Richard Stallman 清大演講心得 * 2008-05-17: 魔法設計的藝術: 自由軟體之父理查史托曼的演講(清華場) * 2008:05-16: Ryan Chung&apos;s Blog: Richard...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[這次的演講地點是清華大學的大禮堂，這是一個又大又舒適的場地，大家都能坐在舒服的軟椅上聽演講。我們在入口處設置了「義賣處」，專賣由 Free Software Foundation 遠渡重洋寄來的一些小玩意兒，我們也依照 Richard 的意思，在現場義賣他自己的書。

<img alt="rms_day4_5.jpg" src="http://www.jollen.org/blog/2008/05/22/rms_day4_5.jpg" width="640" height="427" />

<img alt="rms_day4_6.jpg" src="http://www.jollen.org/blog/2008/05/22/rms_day4_6.jpg" width="640" height="427" />

今天的主題是自由軟體運動，以及 GNU/Linux operating system，這場演講其實我並沒有很專心在聽講（*汗*），因為一直不斷地在會場穿梭。不過，有許多這天來聽演講的朋友，都在自已的 blog 上做了很不錯的紀錄，他們的紀錄會比較有參考價值：

* 2008-05-21: <a href="http://twcu.blogspot.com/2008/05/definition-1-free-software-2-4.html">E-Mate News: A talk from Richard Stallman</a>
* 2008-05-19: <a href="http://hialan.blogspot.com/2008/05/515-richard-stallman.html">Hialan's Blog: 5/15 Richard Stallman 清大演講心得</a>
* 2008-05-17: <a href="http://magicdesign.blogspot.com/2008/05/blog-post_17.html">魔法設計的藝術: 自由軟體之父理查史托曼的演講(清華場)</a>
* 2008:05-16: <a href="http://ryan403.blogspot.com/2008/05/richard-stallman.html">Ryan Chung's Blog: Richard Stallman 清華演講心得分享</a>
* 2008-05-15: <a href="http://www.wretch.cc/blog/ranma/12494671">踏出阿宅 走向質男   Freedom is ..the GNU</a>

這一場的聽眾人數我們沒有精確統計過，但是比起前一天在淡江大學，人數明顯多很多。超過一千個座位的大禮堂，坐了將近七成，而且互動與反應都比前一天還熱烈。當我的同事帶領 Richard 上講臺時，我還聽到旁邊有個小妹講「哇！好可愛喔」，她該不會是覺得老爹圓滾滾的肚子很可愛吧。

<img alt="rms_day4_7.jpg" src="http://www.jollen.org/blog/2008/05/22/rms_day4_7.jpg" width="640" height="427" />

<img alt="rms_day4_8.jpg" src="http://www.jollen.org/blog/2008/05/22/rms_day4_8.jpg" width="640" height="427" />

講臺上除了 Richard Stallman 外，最引人注意的大概就是台上一字排開的「綠茶」吧！沒辦法，大師真的超愛這種綠茶的，只記得第一天帶 Richard 回 Openmoko 公寓時買了幾瓶給他，從此他就愛上這種綠茶了。

<img alt="rms_day4_9.jpg" src="http://www.jollen.org/blog/2008/05/22/rms_day4_9.jpg" width="640" height="427" />

<img alt="rms_day4_10.jpg" src="http://www.jollen.org/blog/2008/05/22/rms_day4_10.jpg" width="640" height="427" />

Richard Stallman 準備許多不同的演講主題，在清華大學這場，我們特別選了與自由軟體運動相關的主題，因為可以看到 Richard 知名的「變裝秀」。Richard Stallman 都會在演講後舉行「祈福」儀式。這就是 Richard Stallman 知名的另一個身份 [<a href="http://www.stallman.org/saint.html">Saint IGNUcius</a>]，Saint IGNUcius 是 Emacs 教會聖徒的意思。Emacs 是 Richard Stallman 學生時代所開發的一個知名文字編輯軟體，至今 Emacs 已經成為一種生活與一種信仰（a way of life and a religion）。變身為 Saint IGNUcius 的 Richard 對著大家說「I bless your computer, my child!」（我保佑你們的電腦，我的子民！），想加入這個教會的人，只需要默唸這個懺悔詞三次即可「There is no system but GNU, and Linux is one of its kernels.」。Richard 還有知名的「Free Software Song」，可惜這次沒有機會聽到，他都隨身攜帶笛子，一有機會就會吹起自由軟體之歌，這次我也只能看到這支笛子，沒有機會聽到 Richard 親自表演 free software song。

<img alt="rms_day4_11.jpg" src="http://www.jollen.org/blog/2008/05/22/rms_day4_11.jpg" width="640" height="427" />

<img alt="rms_day4_12.jpg" src="http://www.jollen.org/blog/2008/05/22/rms_day4_12.jpg" width="640" height="427" />

最後，Richard 來了個拍賣會。比起前一天在淡江大學，這次的拍賣會熱烈多了，Richard 親自帶來的原版書，以及 GNU 玩偶，都以高價拍出。

<img alt="rms_day4_13.jpg" src="http://www.jollen.org/blog/2008/05/22/rms_day4_13.jpg" width="640" height="427" />

<img alt="rms_day4_14.jpg" src="http://www.jollen.org/blog/2008/05/22/rms_day4_14.jpg" width="640" height="427" />

散場後，很多人都帶著在場外買的書給 Richard 簽名。他也在一塊活動宣傳的布條上簽名，協助活動的另外二個主辦單位「清華大學資工系」與「清華大學電通中心」也和 Richard 大合照，為這次大師訪台畫下美好句點。

當天標到 GNU 玩偶的 CNET 記者馬冶國先生也做了活動紀錄 [<a href="http://www.zdnet.com.tw/news/pix/0,2000085677,20129415,00.htm">圖片：Richard Stallman在清華</a>]。能參與舉辦這個難得的活動，並近身觀察自由軟體之父，對所有工作人員來講，都是一個難忘的回憶！]]>
      
   </content>
</entry>
<entry>
   <title>Richard Stallman 台灣行第四天紀錄: 5/15 新竹清大行側寫</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/05/richard_stallman_day4.html" />
   <id>tag:www.jollen.org,2008:/blog//2.521</id>
   
   <published>2008-05-21T12:54:14Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>5 月 15 日的行程是帶 Richard Stallman 到新竹清華大學，這一天大師所要發表的演講主題是「The Free Software Movement and the GNU/Linux Operating System」。與 Richard 接觸幾天下來，發現他其實是一個很喜歡「看世界」的老爹，正好，我偏愛人物側寫，因此再度來和大家爆料。 Richard Stallman 喜歡什麼東西？幾天下來，我們知道大師喜歡「民俗傳統音樂」、「中國菜」、「中國茶」、「山」，以及「火車」。因此這一天，我和一位商周的記者特別帶 Richard 搭台灣高鐵。Richard 喜歡靠窗的位子，不過他很有風度地讓座給他的女朋友 Dora。 來到高鐵站後，Richard 和 Dora 都覺得高鐵站真是太漂亮了，又大又寬倘，我們照了幾張照片，就往「玻璃工藝博物館」出發了。沒錯！我們是從高鐵站直接開跋到玻璃工藝博物館，為什麼我們會跑到這裡來呢？因為，大師不知道是怎麼知道新竹有這個地方的，他在前一天就特別交待我們，一定要帶他來這裡！ 參觀完玻璃工藝博物館後，我們終於可以來到真正的目的地「清華大學」了。清華大學資工系的幾位教授，在清大裡的一間咖啡店設席款待大師。Richard 非常熱愛閱讀，我們一帶他進到咖啡店後，他就突然眼睛一亮，因為店裡滿滿地都是原文書。他問道「這裡是書店嗎」，正巧遇到咖啡店的老闆，他為大師解答了這個問題，原來，這裡以前是一家書店。 大師突然興緻一來，逛起書店了。他和咖啡店老闆似乎相當聊得來，聊書、聊音樂，興致大開，還在店裡的牆上留下簽名。聊天簽名還不夠，Richard 還挑了幾本書想要買回去，老闆也很夠意思，打折賣出！用餐後，即將展開今晚的演講。離去前，Richard 還問道「你們店開到什麼時候」，他還想要回來挑書呢！幾天下來，看到了大師非常不一樣的另一面，真是一個意外的收獲。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[5 月 15 日的行程是帶 Richard Stallman 到新竹清華大學，這一天大師所要發表的演講主題是「The Free Software Movement and the GNU/Linux Operating System」。與 Richard 接觸幾天下來，發現他其實是一個很喜歡「看世界」的老爹，正好，我偏愛人物側寫，因此再度來和大家爆料。

<img alt="rms_day4_1.jpg" src="http://www.jollen.org/blog/2008/05/21/rms_day4_1.jpg" width="640" height="427" />

Richard Stallman 喜歡什麼東西？幾天下來，我們知道大師喜歡「民俗傳統音樂」、「中國菜」、「中國茶」、「山」，以及「火車」。因此這一天，我和一位商周的記者特別帶 Richard 搭台灣高鐵。Richard 喜歡靠窗的位子，不過他很有風度地讓座給他的女朋友 Dora。

<img alt="rms_day4_2.jpg" src="http://www.jollen.org/blog/2008/05/21/rms_day4_2.jpg" width="640" height="427" />

來到高鐵站後，Richard 和 Dora 都覺得高鐵站真是太漂亮了，又大又寬倘，我們照了幾張照片，就往「玻璃工藝博物館」出發了。沒錯！我們是從高鐵站直接開跋到玻璃工藝博物館，為什麼我們會跑到這裡來呢？因為，大師不知道是怎麼知道新竹有這個地方的，他在前一天就特別交待我們，一定要帶他來這裡！

<img alt="rms_day4_3.jpg" src="http://www.jollen.org/blog/2008/05/21/rms_day4_3.jpg" width="640" height="427" />

參觀完玻璃工藝博物館後，我們終於可以來到真正的目的地「清華大學」了。清華大學資工系的幾位教授，在清大裡的一間咖啡店設席款待大師。Richard 非常熱愛閱讀，我們一帶他進到咖啡店後，他就突然眼睛一亮，因為店裡滿滿地都是原文書。他問道「這裡是書店嗎」，正巧遇到咖啡店的老闆，他為大師解答了這個問題，原來，這裡以前是一家書店。

<img alt="rms_day4_4.jpg" src="http://www.jollen.org/blog/2008/05/21/rms_day4_4.jpg" width="640" height="427" />

大師突然興緻一來，逛起書店了。他和咖啡店老闆似乎相當聊得來，聊書、聊音樂，興致大開，還在店裡的牆上留下簽名。聊天簽名還不夠，Richard 還挑了幾本書想要買回去，老闆也很夠意思，打折賣出！用餐後，即將展開今晚的演講。離去前，Richard 還問道「你們店開到什麼時候」，他還想要回來挑書呢！幾天下來，看到了大師非常不一樣的另一面，真是一個意外的收獲。]]>
      
   </content>
</entry>
<entry>
   <title>Richard Stallman 結束訪台行程: 5/19 離台</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/05/richard_stallman_departure.html" />
   <id>tag:www.jollen.org,2008:/blog//2.520</id>
   
   <published>2008-05-21T08:43:20Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>Richard Stallman 於前天（5/19）離台，前往香港，正式結束這次的訪台行程。相隔三年，Richard 再度來台，對台灣還是記憶深刻呢。上個週末，Openmoko 同事帶著大師品嘗台灣的知名餐廳「鼎泰豐」，以及別具特色的茶料理「喫茶趣」；後者是大師欽點，他在三年前到台灣時曾經品嘗過，這次來台灣特別點名要我們帶他去呢！ 這天早上大約八點來到 Openmoko 公寓找大師，大師給了我一堆貼紙以及胸針，要我分給有需要的朋友。Richard 搭乘港龍航空到香港，接下來的行程如下： * 2008-05-24: 上海復旦大學 - Free Software in Ethics and in Practice * 2008-05-28: 西安交通大學 - Free Software in Ethics and in Practice * 2008-05-30: 北京清華大學 - Free Software in Ethics and...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Richard Stallman 於前天（5/19）離台，前往香港，正式結束這次的訪台行程。相隔三年，Richard 再度來台，對台灣還是記憶深刻呢。上個週末，Openmoko 同事帶著大師品嘗台灣的知名餐廳「鼎泰豐」，以及別具特色的茶料理「喫茶趣」；後者是大師欽點，他在三年前到台灣時曾經品嘗過，這次來台灣特別點名要我們帶他去呢！

這天早上大約八點來到 Openmoko 公寓找大師，大師給了我一堆貼紙以及胸針，要我分給有需要的朋友。Richard 搭乘港龍航空到香港，接下來的行程如下：

* 2008-05-24: 上海復旦大學 - Free Software in Ethics and in Practice
* 2008-05-28: 西安交通大學 - Free Software in Ethics and in Practice
* 2008-05-30: 北京清華大學 - Free Software in Ethics and in Practice
* 2008-05-31: 北京清華大學 - The Danger of Software Patents

需要更詳細資訊的朋友可查詢 Free Software Foundation 的 [<a href="http://www.fsf.org/events/rms-speeches.html">活動公告</a>]。Richard 本次訪台共發表了二場公開演講，後續會補上其他行程及活動紀錄，我們也會進行演講的逐字稿工作，以及照片分享。希望能將自由軟體大師這次的訪台紀錄與大家完整分享。]]>
      
   </content>
</entry>
<entry>
   <title>Richard Stallman 台灣行第三天：下課後</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/05/richard_stallman.html" />
   <id>tag:www.jollen.org,2008:/blog//2.502</id>
   
   <published>2008-05-16T14:23:52Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>大師第三天除了到淡江大學演講外，下午還有私人行程，現在就由我來為大家大爆料，瞧瞧大師的另一面！這天，結束公開演講行程後，一行人加大師一共五個人，驅車來到淡水老街裡的一家海鮮餐廳，準備替 Richard 安排一頓豐富的海鮮大餐。 不說您不知道，Richard 是個美食愛好者，而且特愛中國菜，這次來到台灣，我們帶他品嘗了好幾家各具特色的餐廳，遇到他喜歡的菜時，還會眯著眼睛細細品味，一副陶醉樣呢。Richard 今天出門特別帶了一包從義大利帶來的麵包條，午餐時，他把麵包條拿了出來，然後分給大家吃。嗯！這麵包條的味道還真不錯，酥酥脆脆，還有點甜甜的，不過，大師可不是想把麵包條拿來配飯，他把麵包條當筷子用！據大師說，這樣在吃完飯後，可以直接把筷子吃掉！ 午餐後，我們帶 Richard 來到關渡的華碩總公司，他今天有一個拜訪 EeePC 的行程。大師跟 EeePC 的幾位工程師，討論了一些技術議題，其中最重要的就是有關「Free BIOS」的討論。大師的工作配備是一台 OLPC（One Laptop Per Child）再加上一個外接鍵盤，為什麼他要用 OLPC 呢？「因為 OLPC 用的是 Free BIOS」，Richard 說。 當然，自由軟體之父來到此寶地，最重要的工作莫過於推廣自由軟體的理念。「希望 EeePC 能協助推廣自由軟體，並告訴大家，EeePC 用的是 GNU/Linux 系統，而不是 Linux 系統」，Richard Stallman 說。現場 EeePC 的朋友也表達高度的誠意，以及協助推廣自由軟體的意願，「或許我們可以先將 Web 上的內容做修改」（將 Linux...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[大師第三天除了到淡江大學演講外，下午還有私人行程，現在就由我來為大家大爆料，瞧瞧大師的另一面！這天，結束公開演講行程後，一行人加大師一共五個人，驅車來到淡水老街裡的一家海鮮餐廳，準備替 Richard 安排一頓豐富的海鮮大餐。

<img alt="rms_day3_06.jpg" src="http://www.jollen.org/blog/2008/05/16/rms_day3_06.jpg" width="640" height="427" />

不說您不知道，Richard 是個美食愛好者，而且特愛中國菜，這次來到台灣，我們帶他品嘗了好幾家各具特色的餐廳，遇到他喜歡的菜時，還會眯著眼睛細細品味，一副陶醉樣呢。Richard 今天出門特別帶了一包從義大利帶來的麵包條，午餐時，他把麵包條拿了出來，然後分給大家吃。嗯！這麵包條的味道還真不錯，酥酥脆脆，還有點甜甜的，不過，大師可不是想把麵包條拿來配飯，他把麵包條當筷子用！據大師說，這樣在吃完飯後，可以直接把筷子吃掉！

<img alt="rms_day3_07.jpg" src="http://www.jollen.org/blog/2008/05/16/rms_day3_07.jpg" width="640" height="427" />

午餐後，我們帶 Richard 來到關渡的華碩總公司，他今天有一個拜訪 EeePC 的行程。大師跟 EeePC 的幾位工程師，討論了一些技術議題，其中最重要的就是有關「Free BIOS」的討論。大師的工作配備是一台 OLPC（One Laptop Per Child）再加上一個外接鍵盤，為什麼他要用 OLPC 呢？「因為 OLPC 用的是 Free BIOS」，Richard 說。

<img alt="rms_day3_08.jpg" src="http://www.jollen.org/blog/2008/05/16/rms_day3_08.jpg" width="640" height="427" />

當然，自由軟體之父來到此寶地，最重要的工作莫過於推廣自由軟體的理念。「希望 EeePC 能協助推廣自由軟體，並告訴大家，EeePC 用的是 GNU/Linux 系統，而不是 Linux 系統」，Richard Stallman 說。現場 EeePC 的朋友也表達高度的誠意，以及協助推廣自由軟體的意願，「或許我們可以先將 Web 上的內容做修改」（將 Linux 改成 GNU/Linux），EeePC 的朋友說。

<img alt="rms_day3_09.jpg" src="http://www.jollen.org/blog/2008/05/17/rms_day3_09.jpg" width="640" height="427" />

<img alt="rms_day3_10.jpg" src="http://www.jollen.org/blog/2008/05/17/rms_day3_10.jpg" width="640" height="427" />

Richard 此行挺有收獲的，除了得到友善的回應外，也拿到一台免費的 EeePC。我想，Richard 的第一個念頭應該是把 EeePC 的 BIOS 換成 Free BIOS 吧！

<img alt="rms_day3_11.jpg" src="http://www.jollen.org/blog/2008/05/17/rms_day3_11.jpg" width="640" height="427" />

<img alt="rms_day3_12.jpg" src="http://www.jollen.org/blog/2008/05/17/rms_day3_12.jpg" width="640" height="427" />

貼有「Free Software Foundation」以及「GNU/Linux Inside」貼紙的 EeePC。]]>
      
   </content>
</entry>
<entry>
   <title>Richard Stallman 台灣行第三天：演講「The Danger of Software Patent」</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/05/richard_stallman_day3_tku.html" />
   <id>tag:www.jollen.org,2008:/blog//2.501</id>
   
   <published>2008-05-14T15:01:05Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>大師今天的行程是到台北的淡江大學發表公開演說，我的同事 tick 今天充當地陪，到 Openmoko 公寓帶 Richard 到淡江大學。今天的場地大約有200個座位，因為反應熱烈，連講座的樓梯也都快坐滿人了！ 今天的講題是「The Danger of Software Patent」，Richard 主要在談論軟體專利是如何危害「創意與想法」的進步，他並且在黑板上畫了一個圖，來講解軟體專利的危險，以及與藥品或其它工程專利的不同。這是一個很有想法的見解，過去我只知道自由軟體基金會是非常「反專利」的，但從未深入了解其原因，今天大師親自到場為大家解釋「為什麼軟體專利不合理」的想法，非常有收獲，因為讓我了解到其實 Richard Stallman 並不是在「反專利體系」，而是強調「軟體專利」的不合理性。 今天在會場遇到了ZDNet Taiwan的馬培治記者，他也寫了一篇相關的報導 [自由軟體基金會創辦人：軟體專利有害無益] 簡單紀錄了 Richard Stallman 今天的演說主軸，是一篇很有參考價值的報導。 Richard 提到「軟體是一個很大的設計專案、需要數以千計的想法（idea）」，他又說道「一個功能就需要由許多的想法所構成（one feature, lots of ideas）」，所以，如果所有的想法都被專利所禁箇，對使用者（也就是我們）其實是一種傷害，我們（也就是使用者）應該站出來悍衛軟體的「自由」不被商業利益所危害。若軟體無法自由修改或變更，使用者也就失去這樣享受「軟體無限創意」的自由了。 「The Danger of Software Patent」軟體專利的危害，在於讓我們無法將「各種不同的想法加以組合」。因為，若想法被專利所限制，人類（使用者）將無法享受軟體多樣化的自由。「想法若透過專利來加以限制，時間一久，將會造成無限的危害」，Richard Stallman 說。 大師將於15日晚間於清華大學發表第二場公開演說，這是大師訪台的最後一場演講，想要一睹大師風采的朋友，可要好好把握機會了！活動訊息請參閱：[http://wiki.openmoko.org/wiki/Richard_Stallman/zh_tw]。 延伸閱讀 2008.05.12: Richard...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[大師今天的行程是到台北的淡江大學發表公開演說，我的同事 tick 今天充當地陪，到 Openmoko 公寓帶 Richard 到淡江大學。今天的場地大約有200個座位，因為反應熱烈，連講座的樓梯也都快坐滿人了！

今天的講題是「The Danger of Software Patent」，Richard 主要在談論軟體專利是如何危害「創意與想法」的進步，他並且在黑板上畫了一個圖，來講解軟體專利的危險，以及與藥品或其它工程專利的不同。這是一個很有想法的見解，過去我只知道自由軟體基金會是非常「反專利」的，但從未深入了解其原因，今天大師親自到場為大家解釋「為什麼軟體專利不合理」的想法，非常有收獲，因為讓我了解到其實 Richard Stallman 並不是在「反專利體系」，而是強調「軟體專利」的不合理性。

<img alt="rms_day3_01.jpg" src="http://www.jollen.org/blog/2008/05/15/rms_day3_01.jpg" width="640" height="427" />

今天在會場遇到了ZDNet Taiwan的馬培治記者，他也寫了一篇相關的報導 [<a href="http://www.zdnet.com.tw/news/software/0,2000085678,20129320,00.htm">自由軟體基金會創辦人：軟體專利有害無益</a>] 簡單紀錄了 Richard Stallman 今天的演說主軸，是一篇很有參考價值的報導。

<img alt="rms_day3_02.jpg" src="http://www.jollen.org/blog/2008/05/15/rms_day3_02.jpg" width="640" height="427" />

Richard 提到「軟體是一個很大的設計專案、需要數以千計的想法（idea）」，他又說道「一個功能就需要由許多的想法所構成（one feature, lots of ideas）」，所以，如果所有的想法都被專利所禁箇，對使用者（也就是我們）其實是一種傷害，我們（也就是使用者）應該站出來悍衛軟體的「自由」不被商業利益所危害。若軟體無法自由修改或變更，使用者也就失去這樣享受「軟體無限創意」的自由了。

<img alt="rms_day3_03.jpg" src="http://www.jollen.org/blog/2008/05/15/rms_day3_03.jpg" width="640" height="427" />

「The Danger of Software Patent」軟體專利的危害，在於讓我們無法將「各種不同的想法加以組合」。因為，若想法被專利所限制，人類（使用者）將無法享受軟體多樣化的自由。「想法若透過專利來加以限制，時間一久，將會造成無限的危害」，Richard Stallman 說。

<img alt="rms_day3_04.jpg" src="http://www.jollen.org/blog/2008/05/15/rms_day3_04.jpg" width="640" height="427" />

大師將於15日晚間於清華大學發表第二場公開演說，這是大師訪台的最後一場演講，想要一睹大師風采的朋友，可要好好把握機會了！活動訊息請參閱：[<a href="http://wiki.openmoko.org/wiki/Richard_Stallman/zh_tw">http://wiki.openmoko.org/wiki/Richard_Stallman/zh_tw</a>]。

<strong>延伸閱讀</strong>

2008.05.12: <a href="http://www.jollen.org/blog/2008/05/richard_stallman_day1.html">Richard Stallman 台灣行第一天</a>
2008.05.03: <a href="http://www.jollen.org/blog/2008/05/richard_stallman_speech_taiwan.html">自由軟體基金會創辦人 Richard Stallman 來台演講</a>]]>
      
   </content>
</entry>
<entry>
   <title>Richard Stallman 台灣行第一天</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/05/richard_stallman_day1.html" />
   <id>tag:www.jollen.org,2008:/blog//2.500</id>
   
   <published>2008-05-12T15:09:36Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>自由軟體基金會創辦人 Richard Stallman 今天下午抵達台灣。這次 Richard Stallman 來台，有一位美麗的小姐 Dora 隨行。到機場接機時，一眼就認出站在路邊等候的大師。大鬍子是大師的特色，非常地容易辨認。 一行人先將 Richard 接到 Openmoko apartment，沒錯！這是「Openmoko 公寓」，是專門「招待」外國工程師的「行館」，Openmoko 公寓非常靠近 Taipei 101。來的路上，Richard 在高速公路上看到 Taipei 101 時，發出了讚嘆的聲音。Richard 的女友 Dora 小姐，對於 101 的外觀則是感到興趣，她覺得 101 大樓長的真是奇怪呢！ 大師是一位非常依賴電子郵件的人，他所有的工作幾乎都是透過電子郵件完成的。在 Richard 來台前，我們也都是完全依靠電子郵件和 Richard 討論行程，以及確認每一個細節。在電子郵件往來過程發現，大師就是大師，對每一個細節都很注重以及重視，這可不是台灣人講的「龜毛」，而是對於工作的認真態度，以及對理念的執著。Richard 在「自由軟體運動」的道路上，一路走來，始終如一。 Richard Stallman 對於自由軟體運動理念相當執著，因此可能有人會認為他是一個不好相處的人，但是今天和大師相處一天下來，我覺得，大師並沒有大師的感覺。不要誤會我的意思了，我指的是，Richard 是一個沒有大師架子的「老爹」，也就沒有那種難以接近，或是言語交談時的壓迫感。除了有些地方，大師有他的「堅持」外，其他事情都很容易和他溝通。但其實，Richard 所堅持的，也只是在表達他的想法，希望能讓我們都能聽聽他的觀念。能親自聽到大師述說他的觀念，這真是一個難得的經驗。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[自由軟體基金會創辦人 Richard Stallman 今天下午抵達台灣。這次 Richard Stallman 來台，有一位美麗的小姐 Dora 隨行。到機場接機時，一眼就認出站在路邊等候的大師。大鬍子是大師的特色，非常地容易辨認。

<img alt="rms_dinner.JPG" src="http://www.jollen.org/blog/2008/05/13/rms_dinner.JPG" width="613" height="246" />

一行人先將 Richard 接到 Openmoko apartment，沒錯！這是「Openmoko 公寓」，是專門「招待」外國工程師的「行館」，Openmoko 公寓非常靠近 Taipei 101。來的路上，Richard 在高速公路上看到 Taipei 101 時，發出了讚嘆的聲音。Richard 的女友 Dora 小姐，對於 101 的外觀則是感到興趣，她覺得 101 大樓長的真是奇怪呢！

大師是一位非常依賴電子郵件的人，他所有的工作幾乎都是透過電子郵件完成的。在 Richard 來台前，我們也都是完全依靠電子郵件和 Richard 討論行程，以及確認每一個細節。在電子郵件往來過程發現，大師就是大師，對每一個細節都很注重以及重視，這可不是台灣人講的「龜毛」，而是對於工作的認真態度，以及對理念的執著。Richard 在「自由軟體運動」的道路上，一路走來，始終如一。

Richard Stallman 對於自由軟體運動理念相當執著，因此可能有人會認為他是一個不好相處的人，但是今天和大師相處一天下來，我覺得，大師並沒有大師的感覺。不要誤會我的意思了，我指的是，Richard 是一個沒有大師架子的「老爹」，也就沒有那種難以接近，或是言語交談時的壓迫感。除了有些地方，大師有他的「堅持」外，其他事情都很容易和他溝通。但其實，Richard 所堅持的，也只是在表達他的想法，希望能讓我們都能聽聽他的觀念。能親自聽到大師述說他的觀念，這真是一個難得的經驗。

大家可能也都聽過，Richard Stallman 是相當喜歡蝴蝶的。下午我們陪 Richard Stallman 回到 Openmoko 公寓時，大廳裡恰巧有一隻蝴蝶，不斷地衝撞著落地窗。Richard 看到了，他走向前去等到蝴蝶停止，然後很仔細很細心地，捏住蝴蝶的翅膀，將牠放到大門外的樹上。

我說 Richard Stallman 其實是一個「可愛」的老爹。晚上 Openmoko 大批人馬，來到內湖的伍角船板，和大師共進晚餐。Richard 一開始有點嚴肅，我想應該是跟大家都還不熟的關係，不過接下來跟大家可就有說有笑的了，甚致還會開些小玩笑！晚餐時，當然免不了要向大師請益「自由軟體」的一些問題，有同事問到「patent」的議題，Richard 也很願意向大家說明。

第一次見到「傳說中」的自由軟體之父，內心有一點點感動，也有敬佩。因為 Openmoko 公寓是電梯大廈，電梯有保全，需要門禁卡才能操作，沒想到大師說「住戶有進出電梯的『自由』，我了解這是為了安全需要，但讓大家失去了這個自由。」

晚餐後，大師向大家說「謝謝」，離去前，也向大家道別「happy hacking」，很有禮貌。Richard 在回 Openmoko 公寓的路上「再次」問了我「do you like the music?」，老爹分享他帶來的音樂給我們，今天一整天都聽著老爹帶來的音樂。我估計他問了我音樂好不好聽至少有 5 次吧！但說真的，我還蠻喜歡 Richard 帶來的音樂。這音樂非常有民俗風，是傳統音樂，聽起來非常舒服。我計畫向老爹要他的 CD 當紀念品，希望我能成功！

Richard Stallman 將在 5 月 14 日和 5 月 15 日發表公開演說，想要一睹大師風采的朋友，趕快來看這裡：[<a href="http://wiki.openmoko.org/wiki/Richard_Stallman/zh_tw">http://wiki.openmoko.org/wiki/Richard_Stallman/zh_tw</a>]。

<strong>延伸閱讀</strong>

2008.05.03: <a href="http://www.jollen.org/blog/2008/05/richard_stallman_speech_taiwan.html">自由軟體基金會創辦人 Richard Stallman 來台演講</a>]]>
      
   </content>
</entry>
<entry>
   <title>自由軟體基金會創辦人 Richard Stallman 來台演講</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/05/richard_stallman_speech_taiwan.html" />
   <id>tag:www.jollen.org,2008:/blog//2.498</id>
   
   <published>2008-05-03T03:55:48Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>學生時代就相當敬佩的自由軟體精神領袖 Richard Stallman 要來台灣了。Richard Stallman 在就讀哈佛大學時，於麻省理工人工智能實驗室發展 Emacs 軟體，也就是在這個時期，他體驗到駭客文化的可貴與精神，從此成為悍衛自由軟體的鬥士。Sam Williams 也寫了一本「自由軟體的聖戰」[1]，內容在描述 Richard Stallman 的自由軟體運動。 以下引述 Openmoko 的新聞稿： 自由軟體基金會創辦人、同時也是知名軟體 GNU Compiler Collection (GCC) 與 GNU Debugger (GDB) 的原始作者與開發者 Richard Stallman 將於 5 月 12 日來台並發表演說。Richard 於 1984 年發動 GNU operating system 發展計畫，並在...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[學生時代就相當敬佩的自由軟體精神領袖 Richard Stallman 要來台灣了。Richard Stallman 在就讀哈佛大學時，於麻省理工人工智能實驗室發展 Emacs 軟體，也就是在這個時期，他體驗到駭客文化的可貴與精神，從此成為悍衛自由軟體的鬥士。Sam Williams 也寫了一本「自由軟體的聖戰」[1]，內容在描述 Richard Stallman 的自由軟體運動。

以下引述 Openmoko 的新聞稿：

自由軟體基金會創辦人、同時也是知名軟體 GNU Compiler Collection (GCC) 與 GNU Debugger (GDB) 的原始作者與開發者 Richard Stallman 將於 5 月 12 日來台並發表演說。Richard 於 1984 年發動 GNU operating system 發展計畫，並在 1985 年成立 Free Software Foundation（自由軟體基金會），接著在 1989 年寫出第一個 GPL （GNU General Public License）條款。GPL 至今已是最重要的自由軟體授權條款，至今有超過 60% 的自由軟體都是採取 GPL 授權規範。因應商業化需要，GPLv3 在經過長時間的討論後，也於 2007 年 6 月正式釋出，並受到產業界高度重視與討論。

睽違三年，Richard Stallman 再度來台，將在台北與新竹各發表一場公開演說。Richard 提到「希望能讓大家了解 GNU operating system，以及自由軟體（free software）的真正意義。」除了發表與自由軟體相關之演說外，Richard Stallman 也會和現場聽眾進行公開討論，這是一個向 Richard 當面請益的好機會。

Richard 本次來台預計將發表與「自由軟體運動」以及「軟體專利威脅」有關之演說。所有活動都是免費參加，Richard 同時也非常想聽到來自各界對自由軟體的聲音。詳細活動資訊請參閱 Openmoko Wiki 活動頁面。

    * 活動頁面：<a href="http://wiki.openmoko.org/wiki/Richard_Stallman/zh_tw ">http://wiki.openmoko.org/wiki/Richard_Stallman/zh_tw 
</a>
<strong>延伸閱讀</strong>

2008.04.30: <a href="http://www.jollen.org/blog/2008/04/foss_gplv3_business_embedded_systems.html">嵌入式系統廠商不能不懂的自由軟體授權 GPLv3</a>

[1] Free as in Freedom: Richard Stallman's Crusade for Free Software, http://www.faifzilla.org/]]>
      
   </content>
</entry>
<entry>
   <title>嵌入式系統廠商不能不懂的自由軟體授權 GPLv3</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/04/foss_gplv3_business_embedded_systems.html" />
   <id>tag:www.jollen.org,2008:/blog//2.497</id>
   
   <published>2008-04-30T07:14:53Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>Richard Stallman[1] 是 Free Software Foundation[2]（自由軟體基金會）的創始人。FSF 成立於 1985 年，致力於爭取電腦使用者的軟體使用自由。Richard 也在 1989 年寫出了第一個 GPL （GNU General Public License）[3] 條款，並在 1991 年 6 月份時釋出 GPLv2（GPL version 2）。 GPL 是現今最重要的 Free and Open Source Software（FOSS）授權條款，至今有超過 60% 的自由軟體都是採取 GPL 授權規範。因應時勢需要，GPLv3 在經過長時間的討論後，也於 2007 年 6...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Richard Stallman[1] 是 Free Software Foundation[2]（自由軟體基金會）的創始人。FSF 成立於 1985 年，致力於爭取電腦使用者的軟體使用自由。Richard 也在 1989 年寫出了第一個 GPL （GNU General Public License）[3] 條款，並在 1991 年 6 月份時釋出 GPLv2（GPL version 2）。

GPL 是現今最重要的 Free and Open Source Software（FOSS）授權條款，至今有超過 60% 的自由軟體都是採取 GPL 授權規範。因應時勢需要，GPLv3 在經過長時間的討論後，也於 2007 年 6 月正式釋出。由於過去的 FOSS（Free and Open Source Software）是採用 GPLv2 授權，因此在 GPLv3 釋出後，大家最關心的便是 GPLv2 與 GPLv3 的差異。由於 GPLv2 與 GPLv3 是不相容的，而且目前資訊工業也大量採用 FOSS 解決方案，再加上嵌入式系統（Embedded System）的應用所帶出的「firmware 與 hardware 不可分割」議題，因此不管是軟體開發商或是嵌入式系統廠商，無不積極針對相關的法律議題進行了解，以釐清 GPL 在商業運用方面議題。

中研院「自由軟體鑄造場」在今年三月份舉辦「自由軟體法律研討會：嵌入式應用專題」[4]，當天有許多台灣的科技大廠以及政府單位參與，可見大家對自由軟體法律問題的重視。對商業運作而言，特別是嵌入式系統廠商來說，GPLv2 與 GPLv3 的議題會是最重要的部份。了解 GPL 授權規範，以及釐清 v2 與 v3 的差異，將是當前最重要的功課。

Richard Stallman 也親自寫了一份「Why Upgrade to GPL Version 3」文件 [5]，向大家說明 GPLv2 與 GPLv3 的主要差異。大致整理 GPLv2 與 GPLv3 的主要差異如下：

* GPLv2 與 GPLv3 是不相容的，沒有法律上的方式將 GPLv2 的程式碼與 GPLv3 的程式碼組合成單一程式。

* GPLv2 與 GPLv3 都是「copyleft」的授權，在自已的程式裡引用使用此授權的程式碼，則自已的程式同樣要引用相同的授權。

* 只在我們需要連結（link）、合併（merge）或組合（combine）二個不同授權的桯式成為一個單一程式時，才會引發授權不相容的議題。但是，GPLv3 的程式與 GPLv2 的程式在一個作業系統裡各自執行時，就不會有什麼問題。例如，TeX 與 Apache 授權都是與 GPLv2 不相容的授權，但我們仍可以在同一個系統裡執行這些程式。因為這些程式都是獨立的程式。又如，如果 Bash 與 GCC 都改採 GPLv3 授權，但 Linux 仍然採用 GPLv2 授權時，這也是沒有衝突的。

* 解決「tivoization」問題。有些裝置以硬體的方式限制使用者，讓使用者無法在該裝置上執行經過修改的軟體。像是 DRM（數位內容管理 - Digital Restrictions Management），如 DVD 撥放器，就會限制 DVD 的撥放。但 GPLv3 並不是想禁止 DRM 的使用，而是確保使用者能有修改軟體的自由，例如：加入一個功能到軟體裡。

* 試圖解決軟體專利問題。但目前仍然無法有效地單獨以 GPLv3 解決此問題。

* GPLv3 與 Apache 授權相容。

原文法律條文有點艱澀難懂，這裡有一份社群協作的「GPLv3 中文翻譯」: <a href="http://wiki.debian.org.hk/w/GPLv3">http://wiki.debian.org.hk/w/GPLv3</a>， 或許可以提供一些幫助。Richard Stallman 去年接受 Linux Link Tech Show 的訪談，也親自說明 GPLv3 的觀念，值得一聽。

許多嵌入式裝置，如：smartphone、router、media player 等，都廣泛使用 FOSS 做為解決方案。因此，當我們不斷討論自由軟體與開源軟體在商業化的應用時，GPL 授權這個最重要的「許可證」以及相關法律問題，也不能忽略。

<strong>延伸閱讀</strong>

2006.11.12: <a href="http://www.jollen.org/blog/2006/11/linux_link_tech_show_gplv3.html">Linux Link TEch Show 的訪談：理查史都曼談 GPLv3</a>

[1] Richard Stallman, http://en.wikipedia.org/wiki/Richard_Stallman
[2] Free Software Foundation, http://www.fsf.org/
[3] GPL, http://en.wikipedia.org/wiki/GNU_General_Public_License
[4] 自由軟體鑄造場『自由軟體法律研討會：嵌入式應用專題』, http://www.openfoundry.org/component/option,com_docman/Itemid,112/gid,230/task,cat_view/
[5] Richard Stallman, Why Upgrade to GPL Version 3, http://gplv3.fsf.org/rms-why.html]]>
      
   </content>
</entry>
<entry>
   <title>Qt 4.4 在 Neo1973 與 HTC Touch Cruise 上展示 iPhone-Like 介面</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/04/qt_iphone_like_graphics.html" />
   <id>tag:www.jollen.org,2008:/blog//2.496</id>
   
   <published>2008-04-24T06:00:31Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>前一篇日記「iPhone 改變工程師設計嵌入式裝置的思惟」提到 iPhone 在 UI 方面的卓越表現。稍早前，[Trolltech Labs] 發表一項新的實驗項目：新的 Qt 4.4 已經可以在 Windows Mobile 以及 Embedded Linux 二個平臺上執行了。 (圖片來源：http://dist.trolltech.com/video/wince/qtembedded44video.html) Trolltech Labs 提供一段 demo 影片，Windows Mobile 平臺使用 HTC Touch Cruise 手機，Embedded Linux 平臺則是使用 Openmoko 的 Neo1973 手機。不過，最引人注目的不是「Qt Everywhere」的表現。新的 Qt 在 UI 方面最令人驚豔的是它的「iPhone...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[前一篇日記「<a href="http://www.jollen.org/blog/2008/04/iphone_reconsider_embedded_design.html">iPhone 改變工程師設計嵌入式裝置的思惟</a>」提到 iPhone 在 UI 方面的卓越表現。稍早前，[<a href="http://labs.trolltech.com/blogs/">Trolltech Labs</a>] 發表一項新的實驗項目：新的 Qt 4.4 已經可以在 Windows Mobile 以及 Embedded Linux 二個平臺上執行了。

<img alt="neo1973_iphone_ui.png" src="http://www.jollen.org/blog/2008/04/24/neo1973_iphone_ui.png" width="629" height="426" />
(圖片來源：http://dist.trolltech.com/video/wince/qtembedded44video.html)

Trolltech Labs 提供一段 demo 影片，Windows Mobile 平臺使用 HTC Touch Cruise 手機，Embedded Linux 平臺則是使用 Openmoko 的 Neo1973 手機。不過，最引人注目的不是「Qt Everywhere」的表現。新的 Qt 在 UI 方面最令人驚豔的是它的「iPhone like graphics」。

我們都知道，未來的智慧型手機開發方法論，會是以使用者為導向的一個體系，包含如何讓應用程式之間更緊密地結合（coherent）以及如何提昇使用性（usability），因此 UI 將會是決定這個部份的關鍵。Nokia 在收購 Trolltech 公司後，在 UI 這一段看來已經有一些不錯的成果了。

]]>
      
   </content>
</entry>
<entry>
   <title>iPhone 改變工程師設計嵌入式裝置的思惟</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/04/iphone_reconsider_embedded_design.html" />
   <id>tag:www.jollen.org,2008:/blog//2.495</id>
   
   <published>2008-04-22T15:45:59Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>嵌入式系統發展的標準化平臺正在加速進行。嵌入式裝置的確和桌上型系統（desktop）很不一樣，iPhone 的成功展示了以使用者為中心（user-centered）的設計模式，Patrick Mannion 稱 iPhone 是一種軟體設計的工藝（feat）。(*1) 去年（2007年）十月份於 San Francisco 所舉辦的「Mobile 2.0」研討會上，討論了「Mobile 2.0」（例如：開發式手機平臺）的三大重要課題：user experience、usability 與 design。user-centered 設計模式即是一種收集使用者經驗，並透過使用者經驗工程，設計使用性（usability）更佳的操作介面（UI）。UI 的設計是使用性的重要一環，iPhone 的 UI 設計已經不用再多說了，使用性要佳，裝置必須更聰明（smarter）。應用程式之間是否能緊密地整合，是決定使用性良劣的另外一個重要的因素，「緊密整合」稱之為 coherence 而不是 integration。 Coherence 才能讓裝置更聰明，而不是 integration。 一般的嵌入式裝置都有多層的應用程式架構（layers），也有很多功能層，將許多不同的程式庫、軟體元件等整合在一起，稱之為「integration」，並不是 coherence。甚致，目前的嵌入式裝置雖然有複雜的多分層設計，但之中完全沒有緊密性（coherence）可言。 「iPhone 是一項偉大的創舉與成功，它全部都是軟體。它是一個開放標準（open-standard）的平臺、很可靠，並且有很好的 user interface。」(*1) iPhone 是一個「以使用者為中心的設計典範」並且強力展示了「嵌入式軟體的設計工藝」。要把軟體設計得較複雜，很簡單！但要把軟體設計簡單化，就不容易了！這就是 iPhone 軟體工藝技術的表現。在莫耳定律的影響下，科技業無不卯足全力提升技術，並加速創新流程，但「Apple 則是很滿意他的慢步化表現」（*2)。 [1] iPhone nudging...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Open Mobile Platform" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[嵌入式系統發展的標準化平臺正在加速進行。嵌入式裝置的確和桌上型系統（desktop）很不一樣，iPhone 的成功展示了以使用者為中心（user-centered）的設計模式，Patrick Mannion 稱 iPhone 是一種軟體設計的工藝（feat）。<em>(*1)</em>

去年（2007年）十月份於 San Francisco 所舉辦的「Mobile 2.0」研討會上，討論了「Mobile 2.0」（例如：開發式手機平臺）的三大重要課題：user experience、usability 與 design。user-centered 設計模式即是一種收集使用者經驗，並透過使用者經驗工程，設計使用性（usability）更佳的操作介面（UI）。UI 的設計是使用性的重要一環，iPhone 的 UI 設計已經不用再多說了，使用性要佳，裝置必須更聰明（smarter）。應用程式之間是否能緊密地整合，是決定使用性良劣的另外一個重要的因素，「緊密整合」稱之為 coherence 而不是 integration。

Coherence 才能讓裝置更聰明，而不是 integration。

一般的嵌入式裝置都有多層的應用程式架構（layers），也有很多功能層，將許多不同的程式庫、軟體元件等整合在一起，稱之為「integration」，並不是 coherence。甚致，目前的嵌入式裝置雖然有複雜的多分層設計，但之中完全沒有緊密性（coherence）可言。

「iPhone 是一項偉大的創舉與成功，它全部都是軟體。它是一個開放標準（open-standard）的平臺、很可靠，並且有很好的 user interface。」<em>(*1)</em>

iPhone 是一個「以使用者為中心的設計典範」並且強力展示了「嵌入式軟體的設計工藝」。要把軟體設計得較複雜，很簡單！但要把軟體設計簡單化，就不容易了！這就是 iPhone 軟體工藝技術的表現。在莫耳定律的影響下，科技業無不卯足全力提升技術，並加速創新流程，但「Apple 則是很滿意他的慢步化表現」<em>（*2)</em>。

[1] iPhone nudging embedded design toward standard,  http://www.eetimes.com/showArticle.jhtml?articleID=207400109
[2] iPhone impacts CE design, http://www.macworld.co.uk/ipod-itunes/news/index.cfm?newsid=21035&pagtype=allchandate]]>
      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] 關於驅動程式的 private data 與可重覆進入函數</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/04/private_data_and_reentrant_function.html" />
   <id>tag:www.jollen.org,2008:/blog//2.494</id>
   
   <published>2008-04-20T09:09:20Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>今天進行 Linux 驅動程式的教育訓練課程，課堂中提到「多個 process (/dev/debug[0..n]) 同時 invoke 同一個驅動程式 (fops) 的架構觀念與程式設計」，我們也做了一個課堂練習。這是 Linux 驅動程式架構上，很重要的一個觀念。 如圖，當 P 與 Q 二個 process 同時在系統裡執行時，因為開啟的裝置檔不同，因此 kernel（VFS switch）會分別為二個裝置檔建立一個 struct file 的資料結構空間。因為二個裝置檔的 major number 相同，因此如果 P/Q 同時（或非同時）執行 write system call 時，都會引用（invoke）到同一份程式碼（即圖上的 xxx_write）。 VFS Switch 在 callback xxx_write 時，便會將「正確的」struct...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[今天進行 Linux 驅動程式的教育訓練課程，課堂中提到「多個 process (<em>/dev/debug[0..n]</em>) 同時 invoke 同一個驅動程式 (fops) 的架構觀念與程式設計」，我們也做了一個課堂練習。這是 Linux 驅動程式架構上，很重要的一個觀念。

<img alt="Private Data and Reentrant Function" src="http://www.jollen.org/blog/2008/04/20/private_data.png" width="512" height="371" />

如圖，當 P 與 Q 二個 process 同時在系統裡執行時，因為開啟的裝置檔不同，因此 kernel（VFS switch）會分別為二個裝置檔建立一個 <em>struct file</em> 的資料結構空間。因為二個裝置<!--Copyright (C) 2008 www.jollen.org. All rights reserved.-->檔的 major number 相同，因此如果 P/Q 同時（或非同時）執行 write system call 時，都會引用（invoke）到同一份程式碼（即圖上的 <em>xxx_write</em>）。

VFS Switch 在 callback <em>xxx_write</em> 時，便會將「正確的」<em>struct file</em> 結構傳給a write driver function，即圖中的 <em>filp</em> 指標。如此一來，<em>xxx_write</em> 函數<!--Copyright (C) 2008 www.jollen.org. All rights reserved.-->便能「重覆進入」：computation code 一份，但有二份獨立的 data （memory space）。

<em>struct file</em> 裡設計了一個稱為 <em>private_data</em> 的欄位，用來指向「私有資料」，即<!--Copyright (C) 2008 www.jollen.org. All rights reserved.-->保存個別 user process 狀態的資料結構。這是在 Linux 驅動程式中很常見的程式結構，當然也是一個「不可不懂」的觀念。`

<strong>延伸閱讀</strong>

* 2006.09.20: <a href="http://www.jollen.org/blog/2006/09/_reentrant_code_program.html">一篇有關 Reentrant Code Program (可重覆進入程式碼) 的文章</a>


]]>
      
   </content>
</entry>
<entry>
   <title>開放手機：談中國市場的機會</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/04/open_mobile_in_china_new_chance.html" />
   <id>tag:www.jollen.org,2008:/blog//2.492</id>
   
   <published>2008-04-12T05:36:13Z</published>
   <updated>2008-07-13T09:56:17Z</updated>
   
   <summary>開放手機的新機會在中國。過去在日記「開放手機：Linux Mobile Phone」與「開放手機：談東方開源」中提到：「拿掉開放手機這件事不說，中國手機市場，不管是低價或高階手機，都已經被國際大廠佔據，很難從中再找到發揮的空間。」、「中國白牌與黑牌手機的特殊市場，更把中國手機的市場空間壓縮得更小」。 這幾天，恰巧也有新聞指出：「大陸主流手機 台品牌廠全面撤退 難敵國際大廠 紛轉戰智慧型手機」。中國手機市場龐大，相當迷人，但進去走一遭卻發現這個市場的困難度。中國人口眾多，「一人買我一顆包子就夠了」形容中國市場「到處是錢潮」，可是手機廠在這裡卻履踢鐵板。解決策略是什麼？ 以下就市場機會與開放平臺二個方向，發表一些個人想法。 市場機會 「透過開放平臺的Linux手機，在更低價手機端（高度一致性的軟硬體平臺），或是不同市場需求的高階手機市場，會是一個很好的機會。」幾天前在台大晶片中心所舉辦的「開放式手機平台論壇」中，主持人陳良基主任也提到「透過開放式手機進入中國的中低階手機市場，會是一個很好的機會」。 由於中國的手機市場已經是國際大廠的天下了，所以採取弱者策略應是中小型手機廠可參考的做法。怎麼樣的廠商叫中小型手機廠？如果不是在中國的這幾個國際大廠，當然就屬中小型廠商。幾百萬支的量，在中國也不算是大規模。以Openmoko來說，這本來就是一家小規模的手機公司，放到中國，只能以「微型企業」自居，所以行銷策略的目的並不是在搶市佔率，而是建立一個屬於自已的小天地。 高階中階低階手機，在這裡都會有機會。不過，「不同市場需求」的高階手機，會是比較容易的一個方向。所謂的不同市場需求的高階手機，就是「差異化的smartphone」。 開放平臺 從事開放手機的工作，最好可以將「積極尋求open-source社群」協助列為主要的經營策略之一。透過open-source社群、集結眾人智慧、快速累積成果與經驗、建立使用者驗體管道、收集使用者經驗等，都是「開放手機平臺」的新革命。 開放手機是一門「使用者生產」的藝術， 如果只是將Android當作是一個「快速的」、「降低研發成本的」、「免費的」、「現成的」手機平臺，就會忽略掉開放平臺最重要的資源與最強大的武器，就會有一點點可惜囉。正因為社群是「協作」模式，所以有時會感覺到「生產過程缺乏組織與條理」，這個部份，肯定違背專業經理人的思考原則。社群發展原本就是比較「抽象」的藝術， 跟科技的「具象」思考不太一樣。有些時候，就要調整自已的想法，或是建構新的思惟體系，才能適應。畢竟，看似沒有條理的一些行動，最後都可能連結成一股強大的力量。 開放平臺的open-source ecosystem，能協助產品差異化的進行，並加速創新流程。不管是外來廠商，或是中國本土的手機廠，開放平臺都是一個很好的新機會。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Open Mobile Platform" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[開放手機的新機會在中國。過去在日記「<a href="http://www.jollen.org/blog/2008/03/open_mobile_phone_linux.html">開放手機：Linux Mobile Phone</a>」與「<a href="http://www.jollen.org/blog/2008/03/eastern_world_open_source_culture.html">開放手機：談東方開源</a>」中提到：「拿掉開放手機這件事不說，中國手機市場，不管是低價或高階手機，都已經被國際大廠佔據，很難從中再找到發揮的空間。」、「中國白牌與黑牌手機的特殊市場，更把中國手機的市場空間壓縮得更小」。

這幾天，恰巧也有新聞指出：「大陸主流手機  台品牌廠全面撤退  難敵國際大廠  紛轉戰智慧型手機」。中國手機市場龐大，相當迷人，但進去走一遭卻發現這個市場的困難度。中國人口眾多，「一人買我一顆包子就夠了」形容中國市場「到處是錢潮」，可是手機廠在這裡卻履踢鐵板。解決策略是什麼？

以下就市場機會與開放平臺二個方向，發表一些個人想法。

<strong>市場機會</strong>

「透過開放平臺的Linux手機，在更低價手機端（高度一致性的軟硬體平臺），或是不同市場需求的高階手機市場，會是一個很好的機會。」幾天前在台大晶片中心所舉辦的「開放式手機平台論壇」中，主持人陳良基主任也提到「透過開放式手機進入中國的中低階手機市場，會是一個很好的機會」。

由於中國的手機市場已經是國際大廠的天下了，所以採取弱者策略應是中小型手機廠可參考的做法。怎麼樣的廠商叫中小型手機廠？如果不是在中國的這幾個國際大廠，當然就屬中小型廠商。幾百萬支的量，在中國也不算是大規模。以Openmoko來說，這本來就是一家小規模的手機公司，放到中國，只能以「微型企業」自居，所以行銷策略的目的並不是在搶市佔率，而是建立一個屬於自已的小天地。

高階中階低階手機，在這裡都會有機會。不過，「不同市場需求」的高階手機，會是比較容易的一個方向。所謂的不同市場需求的高階手機，就是「差異化的smartphone」。
<strong>
開放平臺</strong>

從事開放手機的工作，最好可以將「積極尋求open-source社群」協助列為主要的經營策略之一。透過open-source社群、集結眾人智慧、快速累積成果與經驗、建立使用者驗體管道、收集使用者經驗等，都是「開放手機平臺」的新革命。

開放手機是一門「使用者生產」的藝術， 如果只是將Android當作是一個「快速的」、「降低研發成本的」、「免費的」、「現成的」手機平臺，就會忽略掉開放平臺最重要的資源與最強大的武器，就會有一點點可惜囉。正因為社群是「協作」模式，所以有時會感覺到「生產過程缺乏組織與條理」，這個部份，肯定違背專業經理人的思考原則。社群發展原本就是比較「抽象」的藝術， 跟科技的「具象」思考不太一樣。有些時候，就要調整自已的想法，或是建構新的思惟體系，才能適應。畢竟，看似沒有條理的一些行動，最後都可能連結成一股強大的力量。

開放平臺的open-source ecosystem，能協助產品差異化的進行，並加速創新流程。不管是外來廠商，或是中國本土的手機廠，開放平臺都是一個很好的新機會。]]>
      
   </content>
</entry>
<entry>
   <title>「開放式手機平台論壇」會後手札</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/04/open_mobile_forum_notes.html" />
   <id>tag:www.jollen.org,2008:/blog//2.491</id>
   
   <published>2008-04-08T15:56:21Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>臺灣大學系統晶片中心（System-on-Chip Center, National Taiwan University）今天舉辦「開放式手機平臺論壇」研討活動，此活動邀請產研界的多位先進，以談話方式針對開放式手機平臺進行看法分享與意見交換。 去年自從Google公開發表「Android」平臺與OHA聯盟現身後，開放手機平臺的概念開始被大量討論，並且受到極大的重視。今天的活動當然也是將主軸放在Android平臺上，由會議中的討論，很明顯地感受到各界對於開放手機概念的重視，許多人對於Android也有高度的期許，希望新概念的出現，能產生新的機會與商機。 已經感冒超過二個星期了，惱人的咳嗽久久不能停止，連講話都有點上氣不接下氣，不過還是很認真地在會場聆聽多位先進的看法。順手寫上一點手札，整理下來和大家分享。最後也加上一點個人看法，請參考指正。 「工研院資通所 林寶樹所長」提到，Android可以幫助廠商減少在軟體方面的投資。而台灣廠商面對未來的開放式手機新挑戰，將會是手機「外觀」與「界面」的議題。此外，開放手機平臺將能整合WiMAX並產生新的服務。林所長也提到，在open source community &amp; project這裡，尚未找到成功的開放手機案例。 「台大資訊系 林風教授」是很資深的行動網路應用研究者，實務上也有很完整的經驗，林教授提到，在他過去的研究經驗中看到，「security」會是開放手機平臺一個重要的議題。「凌陽 林文昌副總」以技術角度分享了一些有趣的看法，林副總認為，從IC design house的角度來看，太多的open source軟體對他們來說也是一種負擔，porting的工作以及來自於客戶端的要求，經常成為沈重的負擔。 「資策會網多所 何寶中所長」表示，「Google的企圖是建立新的手機產業鍊」，何所長也針對台灣完整的產業鍊，提出一份「台灣版OHA對照表」，試著從台灣本土的廠商組織出「台灣版的OHA」，這是個有趣而且值得深思的看法。 「聯發科技 張志偉特助」以比較結論的方式發表看法，同時也大略介紹了聯發科技在手機的佈局，聯發科技在3G與smartphone上也會有些著墨，例如WiMAX phone以及DVB-H的roadmap。 前陣子，與Openmoko的CEO ‘Sean’討論了一些關於Linux手機的研發成本議題。開放手機採用Linux作業系統核心，不管是Openmoko或是Android都是採用2.6的Linux核心，但大家對於「Linux手機」卻有一種「美麗的誤會」，這是建立在「Linux是免費的」（正確來講是自由的、不是免費的）刻板映像上。但使用「開放」的手機平臺，是為了尋找新的機會，更明白來說，是為了建立或尋找新的商業模式（business model）。 「台大系統晶片中心 陳良基主任」一開始也提到「open source需要Q.C.」的技術，才能導入產品化。原因是，大多數的open source軟體都是玩家為了證明一些觀念所實作的程式碼，要將這麼多的open source project成果整合成一個平臺，在此平臺上開發應用程式，原本就不是一件簡單的事情，若要再將這個open source平臺整合到「裝置」上（產品），則需要更多的know-how與工程技術，才能讓軟硬體整合無間。 這些都是使用「Linux」來開發手機，需要付出的成本。 所以說，使用Linux並不是為了降低成本，事實上無形的工程成本是相當龐大的。過去，Openmoko也針對這個部份做了計算，若要將open source的成果整合成開放式手機平臺，並且生產手機，要付出的工程費用，單位是「億」。 使用Linux並不能讓你的研發成本降低。簡單來說，就像在玩樂高積木，你用積木堆出一台酷炫的機器人，但卻希望明天他就變成會飛的無敵鐵金鋼。玩具終究還是玩具，我們可以用樂高堆出「概念」，但要做出一台無敵鐵金鋼，這又是另當別論。 「嵌入式產業聯盟 盧功勳」會長也不約而同提到「Q.C.」是open...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Open Mobile Platform" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[臺灣大學系統晶片中心（System-on-Chip Center, National Taiwan University）今天舉辦「<a href="http://soc.ee.ntu.edu.tw/soc/download/forum_080408.jpg">開放式手機平臺論壇</a>」研討活動，此活動邀請產研界的多位先進，以談話方式針對開放式手機平臺進行看法分享與意見交換。

去年自從Google公開發表「Android」平臺與OHA聯盟現身後，開放手機平臺的概念開始被大量討論，並且受到極大的重視。今天的活動當然也是將主軸放在Android平臺上，由會議中的討論，很明顯地感受到各界對於開放手機概念的重視，許多人對於Android也有高度的期許，希望新概念的出現，能產生新的機會與商機。

已經感冒超過二個星期了，惱人的咳嗽久久不能停止，連講話都有點上氣不接下氣，不過還是很認真地在會場聆聽多位先進的看法。順手寫上一點手札，整理下來和大家分享。最後也加上一點個人看法，請參考指正。

「工研院資通所 林寶樹所長」提到，Android可以幫助廠商減少在軟體方面的投資。而台灣廠商面對未來的開放式手機新挑戰，將會是手機「外觀」與「界面」的議題。此外，開放手機平臺將能整合WiMAX並產生新的服務。林所長也提到，在open source community & project這裡，尚未找到成功的開放手機案例。

「台大資訊系 林風教授」是很資深的行動網路應用研究者，實務上也有很完整的經驗，林教授提到，在他過去的研究經驗中看到，「security」會是開放手機平臺一個重要的議題。「凌陽 林文昌副總」以技術角度分享了一些有趣的看法，林副總認為，從IC design house的角度來看，太多的open source軟體對他們來說也是一種負擔，porting的工作以及來自於客戶端的要求，經常成為沈重的負擔。

「資策會網多所 何寶中所長」表示，「Google的企圖是建立新的手機產業鍊」，何所長也針對台灣完整的產業鍊，提出一份「台灣版OHA對照表」，試著從台灣本土的廠商組織出「台灣版的OHA」，這是個有趣而且值得深思的看法。

「聯發科技 張志偉特助」以比較結論的方式發表看法，同時也大略介紹了聯發科技在手機的佈局，聯發科技在3G與smartphone上也會有些著墨，例如WiMAX phone以及DVB-H的roadmap。

前陣子，與Openmoko的CEO ‘Sean’討論了一些關於Linux手機的研發成本議題。開放手機採用Linux作業系統核心，不管是Openmoko或是Android都是採用2.6的Linux核心，但大家對於「Linux手機」卻有一種「美麗的誤會」，這是建立在「Linux是免費的」（正確來講是自由的、不是免費的）刻板映像上。但使用「開放」的手機平臺，是為了尋找新的機會，更明白來說，是為了建立或尋找新的商業模式（business model）。

「台大系統晶片中心 陳良基主任」一開始也提到「open source需要Q.C.」的技術，才能導入產品化。原因是，大多數的open source軟體都是玩家為了證明一些觀念所實作的程式碼，要將這麼多的open source project成果整合成一個平臺，在此平臺上開發應用程式，原本就不是一件簡單的事情，若要再將這個open source平臺整合到「裝置」上（產品），則需要更多的know-how與工程技術，才能讓軟硬體整合無間。

這些都是使用「Linux」來開發手機，需要付出的成本。

所以說，使用Linux並不是為了降低成本，事實上無形的工程成本是相當龐大的。過去，Openmoko也針對這個部份做了計算，若要將open source的成果整合成開放式手機平臺，並且生產手機，要付出的工程費用，單位是「億」。

使用Linux並不能讓你的研發成本降低。簡單來說，就像在玩樂高積木，你用積木堆出一台酷炫的機器人，但卻希望明天他就變成會飛的無敵鐵金鋼。玩具終究還是玩具，我們可以用樂高堆出「概念」，但要做出一台無敵鐵金鋼，這又是另當別論。

「嵌入式產業聯盟 盧功勳」會長也不約而同提到「Q.C.」是open source模式的重要一環，Q.C.是產品化的技術，也是軟硬體整合技術的領域。

Android的出現是一件相當好的事情，許多廠商能在這裡找到許多新商機，並且也能激發更多的創新服務。Google台灣工程研究所的簡立峰所長，是今天的神祕嘉賓，簡所長今天也以「非官方」身份提到，他認同「台灣是Android最佳的合作伙伴」這件事情。Android能帶出許多新的機會，這是與會先進都認同的想法。

「Works Systems」的CEO ‘Tom’就是由「服務商」的角度來分享開放手機平臺所帶來的新機會，例如透過Android開發’location-based’的服務。

會議上，Openmoko也分享了一些看法。開放手機除了「一個技術平臺」外，相對重要的元素還有「使用者經驗（user experience）」、「使用性（usability）」與「設計（design）」。使用性就是UI的設計，開放手機與smartphone最重要也是新的挑戰就是UI的設計，資策會網多所的何所長就提到「使用Android平臺必須還有一些差異化」才能找到新機會，「差異化」可由UI做起。

設計（design）這個環節在這次會議中，比較沒有被討論到，不過這卻是開放手機另一個重要的元素。工研院資通所林所長就明白提到，手機「外觀」會是開放手機一個重要的項目，也是廠商的新挑戰。這裡所指的設計，就是ID（工業設計）。Openmoko很久就體認到設計的重要性，因此做出了「開放設計」的大膽嘗試，在今年的二月份，Openmoko將其手機的機構設計原稿（CAD）以創用CC授權公開給社群使用，結果效果出奇地好，很快地就收到來自於社群的回饋。

開放手機是一個新觀念，也是一個新挑戰，不妨以新的腦袋來思考，除了「長知識」外，也增進工作樂趣。
<strong>
延伸閱讀</strong>

2008.02.14: <a href="http://www.jollen.org/blog/2008/02/openmoko_perspective_to_android.html">OpenMoko 對 Android 的「官方」看法</a>
2007.12.02: <a href="http://www.jollen.org/blog/2007/12/android_apache_license_not_gpl.html">Google Android 採用 Apache License: 為什麼不是 GPL？</a>
2007.11.09: <a href="http://www.jollen.org/blog/2007/11/android_gphone.html">Android 與 Gphone 觀察</a>
2007.11.08: <a href="http://www.jollen.org/blog/2007/11/abc_news_openmoko.html">ABC News 報導 OpenMoko</a>]]>
      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] 交叉編譯（cross compile）thttpd</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/03/cross_compile_thttpd.html" />
   <id>tag:www.jollen.org,2008:/blog//2.490</id>
   
   <published>2008-03-30T02:54:26Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>本週進行 root filesystem 相關的教育訓練，今天給的課堂練習是 thttpd 的交叉編譯（cross compile）。thttpd 採用標準的 GNU autoconf 來產生 Makefile，因此，交叉編譯 thttpd 的方式是蠻簡單的。配合課堂提供的 cross toolchain（gcc 3.4.1），我們先定義以下有關 cross toolchain 路徑檔檔名的 Makefile 變數： TOOL_TOP = /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu CC = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-gcc AR = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-ar LD = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-ld AS = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-as STRIP = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-strip...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[本週進行 root filesystem 相關的教育訓練，今天給的課堂練習是 thttpd 的交叉編譯（cross compile）。thttpd 採用標準的 GNU autoconf 來產生 Makefile，因此，交叉編譯 thttpd 的方式是蠻簡單的。配合課堂提供的 cross toolchain（gcc 3.4.1），我們先定義以下有關 cross toolchain 路徑檔檔名的 Makefile 變數：

<blockquote><pre>TOOL_TOP = /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu
CC = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-gcc
AR = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-ar
LD = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-ld
AS = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-as
STRIP = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-strip
RANLIB = $(TOOL_TOP)/bin/arm-9tdmi-linux-gnu-ranlib
TARGET_ARCH = arm-linux</pre></blockquote>

接著再定義與 thttpd 的 'CFLAGS' 參數：

<blockquote><pre>THTTPD_CFLAGS = -Os -Wall -mtune=arm9tdmi -march=armv4 \
                -fomit-frame-pointer -fsigned-char -fPIC</pre></blockquote>

我們希望能有一個比較彈性以及系統化的做法，因此採用 Makefile 的系統來實作，不考慮編寫 script 的方式。接著，再定義一個 target，用來設定 thttpd 的 autoconf：

<blockquote><pre>configured-thttpd:
        (export CC=$(CC); \
        export AR="$(AR)"; \
        export AS=$(AS); \
        export LD=$(LD); \
        export STRIP=$(STRIP); \
        export RANLIB=$(RANLIB); \
        export CFLAGS="$(THTTPD_CFLAGS)"; \
        ./configure \
                --prefix=/ \
                --host=$(TARGET_ARCH) );</pre></blockquote>

我們想要用 'install' 指令來安裝 thttpd 執行檔到 root filesystem，因此 '--prefix' 參數的定義對我們講並不重要。Makefile 有良好的 dependencies 系統，所以我再撰寫一段 rule 如下：

<blockquote><pre>thttpd: configured-thttpd
        make</pre></blockquote>

接著，將以上的 Makefile 內容存檔，例如存成 thttpd.cross，再將這個檔案放到 thttpd 原始碼根目錄下，執行 make 並引用 thttpd.cross 的 'thttpd' target：

<blockquote>$ make -f thttpd.cross thttpd</blockquote>

一轉眼，我們得到 thttpd 的執行檔了。再將此 thttpd 執行檔加到 root filesystem 裡即可，別忘了，thttpd 需要幾個 shared library，把他們也加到 root filesystem 裡！還有，thttpd 會去讀取 user database（/etc/passwd 等），所以也要把 NSS 的 files 程式庫（libnss_files.so）加到 root filesystem 裡！

利用 Makefile 系統取代直接敲命令（或編寫 script）的麻煩做法，讓整個過程看起來簡單又清楚！]]>
      
   </content>
</entry>
<entry>
   <title>開放手機：Linux Mobile Phone</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/03/open_mobile_phone_linux.html" />
   <id>tag:www.jollen.org,2008:/blog//2.489</id>
   
   <published>2008-03-22T13:12:08Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>中國手機市場如此迷人，又該如何切入呢？開放手機平臺便是一個絕佳的機會。拿掉開放手機這件事不說，中國手機市場，不管是低價或高階手機，都已經被國際大廠佔據，很難從中再找到發揮的空間。此外，中國白牌與黑牌手機的特殊市場，更把中國手機的市場空間壓縮得更小，在中國，超過5000萬台的黑手機，消滅掉了一些中小型的手機廠的生存空間。 因此，透過開放平臺的Linux手機，在更低價手機端（高度一致性的軟硬體平臺），或是不同市場需求的高階手機市場，會是一個很好的機會。自從去年十一月份， Google 正式公開 Android 計畫後，「開放手機平臺（Open Mobile Platform）」的概念開始受到重視。幾個月下來，隨著媒體的報導，讓開放手機平臺概念的大量且持續的曝光，越來越多人在網路上討論這樣的概念，而真 正的引爆點則是 Android 原型機的現身。今年的 Mobile World Congress 展上出現了 Android 的原型機。 Linux手機的技術議題 Linux 作業系統在開放手機平臺佔有舉足輕重的角色，Android 的系統層使用 Linux 2.6 作業系統核心，OpenMoko 平臺也是採用 Linux 2.6 作業系統核心，另外一個重要的開放手機平臺 GMAE 也是基於 Linux 作業系統。 Linux kernel在技術端有幾個主要的議題，在北京的 Linux Developer Symposium上被提出討論。由於官方的Linux kernel更新速度相當頻繁，因此造成不同版本間的一些相容性問題。此外， Linux kernel的社群對Linux...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Open Mobile Platform" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[中國手機市場如此迷人，又該如何切入呢？開放手機平臺便是一個絕佳的機會。拿掉開放手機這件事不說，中國手機市場，不管是低價或高階手機，都已經被國際大廠佔據，很難從中再找到發揮的空間。此外，中國白牌與黑牌手機的特殊市場，更把中國手機的市場空間壓縮得更小，在中國，超過5000萬台的黑手機，消滅掉了一些中小型的手機廠的生存空間。

因此，透過開放平臺的Linux手機，在更低價手機端（高度一致性的軟硬體平臺），或是不同市場需求的高階手機市場，會是一個很好的機會。自從去年十一月份， Google 正式公開 Android 計畫後，「開放手機平臺（Open Mobile Platform）」的概念開始受到重視。幾個月下來，隨著媒體的報導，讓開放手機平臺概念的大量且持續的曝光，越來越多人在網路上討論這樣的概念，而真 正的引爆點則是 Android 原型機的現身。今年的 Mobile World Congress 展上出現了 Android 的原型機。

<strong>Linux手機的技術議題</strong>

Linux 作業系統在開放手機平臺佔有舉足輕重的角色，Android 的系統層使用 Linux 2.6 作業系統核心，OpenMoko 平臺也是採用 Linux 2.6 作業系統核心，另外一個重要的開放手機平臺 GMAE 也是基於 Linux 作業系統。

Linux kernel在技術端有幾個主要的議題，在北京的 Linux Developer Symposium上被提出討論。由於官方的Linux kernel更新速度相當頻繁，因此造成不同版本間的一些相容性問題。此外， Linux kernel的社群對Linux kernel的貢獻量已經到了一個很可怕的地步，因此還延伸出另外一個問題。許多patch的檢視與提交（commit）需要很長的時間，造成許多非官方的Linux kernel到處流竄。其它問題，包含在會議上幾個重要的Linux kernel開發者討論到的即時性與電源管理問題，以及本土化支援等。

<strong>Linux 開放手機的前景</strong>

開放手機的議題由Google的Android帶起全球性的熱烈討論，根據ABI Research的預測數據指出，在2012年以前（2007-2012），Linux手機將以每年超過75%的複合成長率成長，到2012年時，Linux手機在智慧型手機市場將佔有31%的市佔率，即大約3.31億支的Linux智慧型手機被賣出。

Linux手機未來也會受到微軟系統的正面挑戰，其中包括微軟指出，Linux侵犯了大約235項微軟的專利，這些都是未來開放手機的潛在挑戰。

《待續》]]>
      
   </content>
</entry>
<entry>
   <title>開放手機：談東方開源</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/03/eastern_world_open_source_culture.html" />
   <id>tag:www.jollen.org,2008:/blog//2.487</id>
   
   <published>2008-03-20T03:34:07Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>今年的2月19到20日，中國開源軟件推廣聯盟（COPU, China OSS Promotion Union）與Linux基金會（the Linux Foundation）在北京共同舉辦「Linux Developer Symposium（Linux開發者研討會）」。全球三大手機聯盟LiPS、LiMO與OhA都到場發表演說。LiPS在會中提到「中國目前已經是全球最大的手機市場了。」顯見未來中國在手機產業，不管是消費者端、技術端或是規格標準面，都扮演重要的角色。 在手機市場策略方面，鎖定中國市場會是很好的做法，但是若想要由龐大的中國市場分享利益（market share），恐怕並不是一件簡單的事情。 去年全球手機出貨量大約11億支，其中有5.5億支是被賣到中國，佔了將近一半的數量，這還不包括「無法統計」的部份。中國市場由於受「在地文化」的影響很深，因此外來的手機廠商比較難以切入中國市場。中國的開源軟件風氣也很興盛，但與西方的開源文化確有很大的不同。 中國的開源軟件文化主要是由國家單位以及軟件公司推動，再加上本地文化的影響，造就出一個中國自已的特殊開放源碼文化。中國很重視「本地化」這件事情，所謂的本地化，只做「中文化」是不夠的，心須是中國本土「製作」的才是本地化軟件。 許多公司想要運用開放源碼策略進軍中國，但總是吃閉門𡙡。根本原因在於「開放源碼這件事情在中國已經自成體系」，直接拿西方那套策略套用在中國是行不通的。西方的開源是由社群（community）驅動，由社群裡發展出商業模式；但在中國或是台灣，開源是直接拿取開源軟件進行商業用途，直接透過企業或聯盟驅動。 《待續》...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Open Mobile Platform" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      今年的2月19到20日，中國開源軟件推廣聯盟（COPU, China OSS Promotion Union）與Linux基金會（the Linux Foundation）在北京共同舉辦「Linux Developer Symposium（Linux開發者研討會）」。全球三大手機聯盟LiPS、LiMO與OhA都到場發表演說。LiPS在會中提到「中國目前已經是全球最大的手機市場了。」顯見未來中國在手機產業，不管是消費者端、技術端或是規格標準面，都扮演重要的角色。

在手機市場策略方面，鎖定中國市場會是很好的做法，但是若想要由龐大的中國市場分享利益（market share），恐怕並不是一件簡單的事情。

去年全球手機出貨量大約11億支，其中有5.5億支是被賣到中國，佔了將近一半的數量，這還不包括「無法統計」的部份。中國市場由於受「在地文化」的影響很深，因此外來的手機廠商比較難以切入中國市場。中國的開源軟件風氣也很興盛，但與西方的開源文化確有很大的不同。

中國的開源軟件文化主要是由國家單位以及軟件公司推動，再加上本地文化的影響，造就出一個中國自已的特殊開放源碼文化。中國很重視「本地化」這件事情，所謂的本地化，只做「中文化」是不夠的，心須是中國本土「製作」的才是本地化軟件。

許多公司想要運用開放源碼策略進軍中國，但總是吃閉門𡙡。根本原因在於「開放源碼這件事情在中國已經自成體系」，直接拿西方那套策略套用在中國是行不通的。西方的開源是由社群（community）驅動，由社群裡發展出商業模式；但在中國或是台灣，開源是直接拿取開源軟件進行商業用途，直接透過企業或聯盟驅動。

《待續》
      
   </content>
</entry>
<entry>
   <title>[教育訓練紀錄] nonblocking wait: try lock</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/03/nonblocking_wait_try_lock.html" />
   <id>tag:www.jollen.org,2008:/blog//2.486</id>
   
   <published>2008-03-15T10:13:17Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>今天在進行 GNU Toolchains 與 Embedded Linux Programming 教育訓練課程時，提及以 shared memory 實作 IPC 時的同步問題。針對 unrelated process 的同步存取控制，一種古老的做法「locking」能簡單地應用在此同步問題上。 當寫入端做出 locking（如：lock file）時，讀取端便要等待 locking 被解除，因此這是一個 blocking wait 的架構。不過，若將「wait for unlucking」改成「try lock」，便能在中間的空閒時間「做點事情」，程式也不會晾著沒事做。 一種簡單的程式架構，以「try lock」來做同步控制，讓程式閒著也要想辦法幹點活兒。另一個類似的觀念為 pthread semaphore 的 sem_trywait()。 延伸閱讀 2007.01.16: Shared Memory 的 Race Condition...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="教育訓練紀錄" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[今天在進行 GNU Toolchains 與 Embedded Linux Programming 教育訓練課程時，提及以 shared memory 實作 IPC 時的同步問題。針對 unrelated process 的同步存取控制，一種古老的做法「locking」能簡單地應用在此同步問題上。

當寫入端做出 locking（如：lock file）時，讀取端便要等待 locking 被解除，因此這是一個 blocking wait 的架構。不過，若將「wait for unlucking」改成「try lock」，便能在中間的空閒時間「做點事情」，程式也不會晾著沒事做。

<img alt="lock_trylock.png" src="http://www.jollen.org/blog/2008/03/15/lock_trylock.png" width="423" height="266" />

一種簡單的程式架構，以「try lock」來做同步控制，讓程式閒著也要想辦法幹點活兒。另一個類似的觀念為 pthread semaphore 的 <em>sem_trywait()</em>。

<strong>延伸閱讀</strong>

2007.01.16: <a href="http://www.jollen.org/blog/2007/01/shared_memory_race_condition.html">Shared Memory 的 Race Condition</a>

]]>
      
   </content>
</entry>
<entry>
   <title>Openmoko 開放 Neo 手機工業設計</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/03/openmoko_unlocks_neo_mobile_phone_industrial_design.html" />
   <id>tag:www.jollen.org,2008:/blog//2.484</id>
   
   <published>2008-03-05T03:47:41Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>過去，手機的工業設計（Industrial Design）都是封閉的，設計原稿走不出深宮大院，設計師拿不到設計原稿，一般人也很難一探手機工業設計的原始樣貌。不過，現在事情不一樣了。在 open source 手機軟體平臺深耕許久的 Openmoko 今天正式發佈一則新聞「Openmoko Unlocks Neo Mobile Phone Industrial Design」，Openmoko 以 ShareAlike Creative Commons （創用CC）授權開放 Neo 手機的工業設計原稿，讓設計師可以自由修改 Neo 工業設計。 創用CC不是一件新鮮事，但是將產品的工業設計原稿以創用CC授權對外公開，還是史上頭一遭。這次所公開的工業設計是 Neo1973 的設計，並提供 CAD 檔供下載 [http://downloads.openmoko.org/CAD/]。 不過早在此新聞稿發佈的幾個禮拜前，Openmoko 早就已經將 CAD 檔公開在首頁上（openmoko.com），社群上的人也很快得到這個消息並下載 CAD 檔，其中也有大學教授，將 Neo 的 CAD 應用在實務教學上。在這則新聞稿發佈的幾天前，一位大學教授 Guillermo 也將他所設計的...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[過去，手機的工業設計（Industrial Design）都是封閉的，設計原稿走不出深宮大院，設計師拿不到設計原稿，一般人也很難一探手機工業設計的原始樣貌。不過，現在事情不一樣了。在 open source 手機軟體平臺深耕許久的 Openmoko 今天正式發佈一則新聞「<a href="http://www.businesswire.com/portal/site/home/?newsLang=en&viewID=news_view_popup&epi-content=NEWS_VIEW_POPUP_TYPE&beanStrID=reportcenterndm&newsId=20080304005158">Openmoko Unlocks Neo Mobile Phone Industrial Design</a>」，Openmoko 以 ShareAlike Creative Commons （創用CC）授權開放 Neo 手機的工業設計原稿，讓設計師可以自由修改 Neo 工業設計。

創用CC不是一件新鮮事，但是將產品的工業設計原稿以創用CC授權對外公開，還是史上頭一遭。這次所公開的工業設計是 Neo1973 的設計，並提供 CAD 檔供下載 [<a href="http://downloads.openmoko.org/CAD/">http://downloads.openmoko.org/CAD/</a>]。

不過早在此新聞稿發佈的幾個禮拜前，Openmoko 早就已經將 CAD 檔公開在首頁上（openmoko.com），社群上的人也很快得到這個消息並下載 CAD 檔，其中也有大學教授，將 Neo 的 CAD 應用在實務教學上。在這則新聞稿發佈的幾天前，一位大學教授  Guillermo 也將他所設計的 Neo 概念機回饋給 Openmoko；Guillermo 教授也提到：

<blockquote>"I am amazed at the depth of your commitment to open design. This must be the first time in history that a company has opened its intellectual property to this extent. Openmoko's revolutionary posting of the CAD files gives a whole new generation of Industrial Design students incredible insight into how it's done as well as an opportunity to contribute with new concepts."</blockquote>

「這是人類歷史上第一次有公司將他們寶貴的智財開放」。]]>
      
   </content>
</entry>
<entry>
   <title>Linux 驅動程式的中斷處理, #3: Bottom Half 的觀念</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/03/interrupt_handling_bottom_half.html" />
   <id>tag:www.jollen.org,2008:/blog//2.483</id>
   
   <published>2008-03-03T15:36:14Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>為了能寫出很棒的 interrupt handle，Linux 採用一種稱為 bottom half 的觀念來實作 interrupt handler。 Linux 將完整的 interrupt handler 切成2個部份（half）：top half 與 bottom half。Top half 是在呼叫 request_irq() 時所指定的 interrupt handler 函數，bottom half 則是由 top half 所排程（scheduling），真正負責回應中斷的 task。 一般來說，top half 的基本實作原則如下： 1. 儲存裝置相關資料，這個部份會涉及「中斷不同步」的議題，在這裡先不做解釋。 2. 將 bottom half...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Linux Device Drivers &amp; Kernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[為了能寫出很棒的 interrupt handle，Linux 採用一種稱為 bottom half 的觀念來實作 interrupt handler。

<img alt="bottom_half.PNG" src="http://www.jollen.org/blog/2008/03/03/bottom_half.PNG" width="595" height="143" />

Linux 將完整的 interrupt handler 切成2個部份（half）：top half 與 bottom half。Top half 是在呼叫 <em>request_irq()</em> 時所指定的 interrupt handler 函數，bottom half 則是由 top half 所排程（scheduling），真正負責回應中斷的 task。

一般來說，top half 的基本實作原則如下：

1. 儲存裝置相關資料，這個部份會涉及「中斷不同步」的議題，在這裡先不做解釋。
2. 將 bottom half 排程後結束執行。

Top half 是真正接受中斷請求的 task，因此應避免執行過久。由 top half 的實作原則可以看出，top half 真正要做的工作其實只有排程 bottom half，因此執行的速度將會非常快。Top half 與 bottom half 的最大差別為，bottom half 在執行時，interrupt 是開啟的，因此 CPU 仍然可以接受中斷請求。

由此也可以看出另外一個 bottom half 機制的特點：當 bottom half 尚未結束執行時，top half 仍然可以處理中斷請求。另外，bottom half 就是 interrupt handler，因此「也視為」在 interrupt mode 下執行。]]>
      
   </content>
</entry>
<entry>
   <title>Linux 驅動程式的中斷處理, #2: 深入淺出中斷模式</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/03/interrupt_handling_semaphore.html" />
   <id>tag:www.jollen.org,2008:/blog//2.482</id>
   
   <published>2008-03-02T14:09:11Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>Interrupt handler 的工作是負責處理裝置的中斷請求，並將結果回報（feedback）給裝置。一般而言，裝置產生中斷時，都是與資料讀寫有關的請求。Interrupt handler 便要根據中斷的特性，來判斷此中斷是要請求驅動程式將資料寫入至裝置，或是由裝置讀取資料。 Linux 驅動程式的 interrupt handler 實作原則如下： 1. 在 interrupt handler 裡，叫醒真正負責此中斷的 task 後立即結束執行。 2. Interrupt handler 應儘量執行最少的程式碼。 3. Interrupt handler 若執行過久，會造成中斷的關閉時間過長，因此可能會遺失緊接著產生的中斷請求。 4. 若 interrupt handler 裡有過長的計算動作或執行過久的程式碼，則應使用 tasklet 或 task queue 將該段程式碼做排程，留待其它時間再執行。如此便可避免interrupt handler執行時間過久。 此外，在中斷模式下做同步控制時，還要考慮是否會佔用過久 CPU 時間的問題。為什麼中斷模式下寫 code...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Linux Device Drivers &amp; Kernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Interrupt handler 的工作是負責處理裝置的中斷請求，並將結果回報（feedback）給裝置。一般而言，裝置產生中斷時，都是與資料讀寫有關的請求。Interrupt handler 便要根據中斷的特性，來判斷此中斷是要請求驅動程式將資料寫入至裝置，或是由裝置讀取資料。

Linux 驅動程式的 interrupt handler 實作原則如下：

1. 在 interrupt handler 裡，叫醒真正負責此中斷的 task 後立即結束執行。
2. Interrupt handler 應儘量執行最少的程式碼。
3. Interrupt handler 若執行過久，會造成中斷的關閉時間過長，因此可能會遺失緊接著產生的中斷請求。
4. 若 interrupt handler 裡有過長的計算動作或執行過久的程式碼，則應使用 tasklet 或 task queue 將該段程式碼做排程，留待其它時間再執行。如此便可避免interrupt handler執行時間過久。

此外，在中斷模式下做同步控制時，還要考慮是否會佔用過久 CPU 時間的問題。為什麼中斷模式下寫 code 需要注意這個議題呢？請看以下的說明。

<strong>Counting Semaphore</strong>

在作業系統教科書中，提及二種 semaphore 的做法：

1. blocking counting semaphore，即 Linux 的 down/up 版本。
2. spinlock counting semaphore，即 Linux 的 spinlock。

Spinlock counting semaphore 屬於傳統作法，spinlock 讓 waiting 的動作（P operation）以 busy-loop 方式實作，因此會佔用 CPU 資源；blocking counting semaphore 則是將 waiting 的動作以 blocking（sleeping） 的方式來進行。

在Linux kernel 裡，blocking counting semaphore 採用 wait queue 來實作，即以 sleep 方式做P operation。Wait queue 機制對驅動程式來說，原始用意為實作 process（user-space）的 blocking read 與 blocking write，這樣的 behavior 機制經常出現在實作 process 讀取裝置資料的場合；當 process 進行 blocking I/O 讀寫（synchronous I/O）時，由於 kernel-space 是以 sleeping 方式進行等待，因此能把 CPU 交給其它人使用，並將 process 排程到 I/O queue（waiting queue），因此不獨佔或浪費 CPU 時間。

在中斷模式下，因為不能使用 sleeping 版本的 semaphore，所以必須使用 spinlock，在此情況下，便會遭遇到 interrupt handler 佔用 CPU 時間太久的問題。]]>
      
   </content>
</entry>
<entry>
   <title>Linux 驅動程式的中斷處理, #1: request_irq 基本觀念</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/03/interrupt_handling_1.html" />
   <id>tag:www.jollen.org,2008:/blog//2.481</id>
   
   <published>2008-03-01T15:58:26Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>在Linux device driver 中，名為 “interrupt handler” 的 routine 負責處理（回應）實體的硬體中斷。當裝置中斷被觸發時，interrupt handler 便會執行，而 interrupt handler 就工作便是回應該中斷的請求（request）。 Interrupt handler 執行於 interrupt mode，並無 process context 資訊，因此，在 interrupt mode 下執行的執行碼需注意以下 3 點： 1. 由於沒有 process context 的關係，因此無法存取 user space。 2. 無法存取 current 巨集。current 巨集是一個指向自己的 kernel...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Linux Device Drivers &amp; Kernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[在Linux device driver 中，名為 “interrupt handler” 的 routine 負責處理（回應）實體的硬體中斷。當裝置中斷被觸發時，interrupt handler 便會執行，而 interrupt handler 就工作便是回應該中斷的請求（request）。

Interrupt handler 執行於 interrupt mode，並無 process context 資訊，因此，在 interrupt mode 下執行的執行碼需注意以下 3 點：

1. 由於沒有 process context 的關係，因此無法存取 user space。
2. 無法存取 <em>current</em> 巨集。<em>current</em> 巨集是一個指向自己的 kernel symbol。
3. 不能呼叫 scheduler 做排程，也不能做 sleeping waiting。由於 down/up 的 semaphore API 是 sleeping waiting 的版本，因此在 interrupt mode 必須改用 spinlock，spinlock 是以 busy waiting 的方式做 wait operation。

Linux device driver 安裝 interrupt handler 的方式是呼叫 <em>request_irq()</em> 函數，透過此函數來佔用 IRQ，並且安裝interrupt handler。

<strong>Request IRQ</strong>

request_irq() 用法如下：

<pre>int request_irq( unsigned int   irq,
                 void           (*handler)(int, void *, struct pt_regs *),
                 unsigned long  irqflags,
                 const char    *devname,
                 void          *dev_id);</pre>

irqflags 參數說明：

1.	SA_INTERRUPT
2.	SA_SHIRQ
3.	SA_SAMPLE_RANDOM

在 Linux 驅動程式的 framework 中，呼叫 <em>request_irq()</em> 安裝 interrupt handler 的位置為：

1.	<em>init_module()</em>
2.	<em>fops->open</em>

若是「共用中斷」（shared IRQ），只能在<em> fops->open</em> 裡呼叫 <em>request_irq()</em>。在 <em>fops->open</em> 裡請求 IRQ ，相對的也要在 <em>fops->release</em> 裡呼叫 <em>free_irq()</em> 將佔用的 IRQ 釋放。
]]>
      
   </content>
</entry>
<entry>
   <title>[科技資訊] 日本嵌入式系統技術協會（JASA）介紹</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/02/jasa_introduction.html" />
   <id>tag:www.jollen.org,2008:/blog//2.479</id>
   
   <published>2008-02-21T08:45:20Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>嵌入式系統是目前熱門的科技之一，各地也都有相關的產業協會。日本是嵌入式技術的大國，特別是日本的機器人技術更是全球知名的項目。JASA（Japan Embedded Systems Technology Association ）是日本的嵌入式技術協會，可參考 JASA 官方網站的介紹 [JASA Introduction]。由 JASA 的介紹發現，JASA 提供一個稱為「ETEC」（Embedded Technology Engineer Certification）的認證制度，以及一個年度的機器人大賽，可見日本在嵌入式技術產業上，有相當良好的組織運作。以下是 JASA 簡介的日中對照。 JASA 介紹 * 原文引用自 JASA 網站 [http://www.jasa.or.jp/top/intro/information.html]。 * 日文翻譯及中文編修由 ViYi 提供。 JASAは、組込み業界の基盤を作るべく、以下のような事業を行なっています。 会員、業界の方々に、事業参加への門戸を広く開放していますので、是非、一緒に活動して下さるようお誘いします。 JASA乃是日本社團法人嵌入式系統技術協會(Japan Embedded Systems Technology Association )的英文簡稱 。JASA成立於1986年8月7日，總部設在東京都中央區，分布則有札幌、東京、名古屋、金沢、大阪、福岡。目前會員數包括正會員: 148家企業 以及贊助會員:35家企業。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[嵌入式系統是目前熱門的科技之一，各地也都有相關的產業協會。日本是嵌入式技術的大國，特別是日本的機器人技術更是全球知名的項目。JASA（Japan Embedded Systems Technology Association ）是日本的嵌入式技術協會，可參考 JASA 官方網站的介紹 [<a href="http://www.jasa.or.jp/top/intro/information.html">JASA Introduction</a>]。由 JASA 的介紹發現，JASA 提供一個稱為「ETEC」（Embedded Technology Engineer Certification）的認證制度，以及一個年度的機器人大賽，可見日本在嵌入式技術產業上，有相當良好的組織運作。以下是 JASA 簡介的日中對照。

<strong>JASA 介紹</strong>

* 原文引用自 JASA 網站 [<a href="http://www.jasa.or.jp/top/intro/information.html">http://www.jasa.or.jp/top/intro/information.html</a>]。
* 日文翻譯及中文編修由 ViYi 提供。

JASAは、組込み業界の基盤を作るべく、以下のような事業を行なっています。
会員、業界の方々に、事業参加への門戸を広く開放していますので、是非、一緒に活動して下さるようお誘いします。

<blockquote>JASA乃是日本社團法人嵌入式系統技術協會(Japan Embedded Systems Technology Association )的英文簡稱 。JASA成立於1986年8月7日，總部設在東京都中央區，分布則有札幌、東京、名古屋、金沢、大阪、福岡。目前會員數包括正會員: 148家企業 以及贊助會員:35家企業。</blockquote>

事業案內

<blockquote>JASA主要的事業內容</blockquote>

<strong>1. 日本最大の組込み技術展示会 ET（Embedded Technology）ショー</strong>

毎年、秋（11月）に開催する、日本の組込み業界最大の展示会ETショーを主催しています。パシフィコ横浜にて開催し、毎年多くの来場者を集めています。
ET2007は、11月14～16日で開催し、盛況のうちに幕を閉じました。

<blockquote>日本最大的嵌入式技術展示會 ET SHOW (Embedded Technology）

每年11月在橫濱Pacafico Yokohama 舉行的日本業界嵌入式最大的展示會是由JASA所主辦的。而ET2007 也在2007年11月14 - 16日舉行完畢。</blockquote>

<strong>2. 西日本で唯一の組込み技術展示会 ETWest</strong>

2006年からマイドームおおさかにて、西日本地区では初めての組込み技術展示会を開催しています。当初の予想以上の出展社数や来場者数を得て、西日本地区での組込みシステム技術に対する関心度の高さが実証されました。
次回のETWest2008は会場をインテックス大阪に移し、6月5日（木）・6日（金）の開催となります。是非、ご来場ください。

<blockquote>西日本地區唯一的嵌入式技術展示會 ETWest

西日本地區首屆以及第二屆的嵌入式系統技術展示會均於2006年和2007年在大阪Mydome Osaka會場舉行。不論是參展廠商及觀展人數均大幅超出大會預期，也顯示了西日本地區對於嵌入式系統技術的高度關心與注目。今年(2008年)西日本嵌入式系統技術展示會將移到大阪Intex Osaka會場舉行。展出日期為2008/6/5(Thu) - 6/6(Fri)。</blockquote>

<strong>3. 組込み技術者試験制度「ETEC」(Embedded Technology Engineer Certification)</strong>

「質の高い教育と技術範囲の標準化指標を提供し、業界全体の活性化を図るべき」との方向性に基づいてJASAが実施する試験です。クラス２（エントリレベル）とクラス１（ミドルレベル）から構成され、受験者にはJASAから点数の証明書が発行されます。
<blockquote>
嵌入式技術工程師認證制度「ETEC」(Embedded Technology Engineer Certification)

JASA亦同時提供嵌入式技術工程師認證制度「ETEC」。這個認證制度主要目的在於「提供高教育的品質與標準化的技術範圍指標，同時希能促進嵌入式系統在業界的活躍度」。認證分為兩個等級，Class 2 初階  與 Class 1 中階，參加認證考試者將可得到JASA發行的證書。</blockquote>

<strong>4. ETソフトウェアデザインロボットコンテスト（ETロボコン）</strong>

組 込みソフトウェア分野における技術教育をテーマに、レゴブロックの車体で決められたコースを自律走行する競技です。同一のハードウェア（車体）のもと、 UML等で分析・設計したソフトウェアの技術を競うコンテストです。夏に行われる競技会のほか、ET会期中に展示会場内でチャンピオンシップ大会が開催さ れています
<blockquote>

ET軟體設計機器人比賽 (ET Robo )

ET軟體設計機器人比賽是以嵌入式軟體領域的技術教育為主題，且以樂高積木為車體，在既定走道上自動競速的一種比賽。並使用同一硬體(車體)，來進行UML等分析以及軟體設計的比賽。除了在夏季舉行的競技賽之外，在ET會期期間也會在展示會場內舉辦冠軍大賽。</blockquote>

<strong>5. 海外の組込み団体・会社との提携</strong>

JASA では、海外の組込み業界との連携・協力関係を推進するため、タイ、インドなどの海外団体を招聘したり、現地の会社を視察したり、積極的に海外交流を図っています。2006年11月15日には、台北市コンピュータ協会（TCA）とMOU協定を締結しました。海外への進出を考えておられる業界の方は、是非、 JASAにご相談下さい。
<blockquote>

與海外的嵌入式相關團體・企業之結盟提攜

JASA為促進提升與海外嵌入式業界的合作關係，除了邀請泰國，印度等海外嵌入式系統團體，前往當地廠商視察之外，也積極推動海外交流，因此在2006年11月15日JASA也與台北市電腦協會(TCA)締結MOU協定。</blockquote>

<strong>6. 組込み教育関連</strong>

組込み技術者育成のための教育を、IPA（SEC）の組込み技術者のスキルスタンダード（ETSS）にそって行なうための枠組み作り、スキル認定のための実証実験などを行なう準備を進めています。業界の有識者を集めてWGを構成し、検討を行なっています。

<blockquote>嵌入式系統技術教育相關

JASA也以嵌入式技術者的 Skill Standard(ETSS)為評量基準，建立培育嵌入式系統技術者(工程師)的基礎架構，並逐步進行Skill認定的實證實驗等相關準備階段。同時並網羅業界相關人士組成工作小組(WG)進行相關研究。</blockquote>

<strong>7. 組込み技術者教育</strong>

組込み技術者養成のための技術教育、新人教育を年に数回行なっています。企業内教育を補完するために、ご活用下さい。

<blockquote>嵌入式技術者教育養成

JASA提供嵌入式技術的專門技術教育以及新人入門教育。期能在企業內訓之外，發揮補強機能。</blockquote>


]]>
      
   </content>
</entry>
<entry>
   <title>開放手機平臺（Open Mobile Platform）的革命</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/02/open_smartphone_mobile_platform.html" />
   <id>tag:www.jollen.org,2008:/blog//2.478</id>
   
   <published>2008-02-19T15:14:00Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>自從去年十一月份，Google 正式公開 Android 計畫後，「開放手機平臺（Open Mobile Platform）」的概念開始受到重視。幾個月下來，隨著媒體的報導，讓開放手機平臺概念的大量且持續的曝光，越來越多人在網路上討論這樣的概念，而真正的引爆點則是 Android 原型機的現身。今年的 Mobile World Congress 展上出現了 Android 的原型機，這裡有一些 Android 原型機的照片 [Google attacks: Android at Mobile World Congress]，如果您希望了解更多有關 Android 原型機的資訊，這篇也是入口文。 「開放手機平臺」（或精確來說「開放式智慧型手機作業系統與平臺」）在二零零八年正式引爆。[Android] 是 Google 所提出的開放手機軟體平臺，根據 [Open Handset Alliance]（OHA）的報導，Android 提供 mobile device 完整的軟體環境，包含：作業系統（Linux）、中介軟體（middleware）與主要的 mobile applications。Open Handset Alliance...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Open Mobile Platform" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[自從去年十一月份，Google 正式公開 Android 計畫後，「開放手機平臺（Open Mobile Platform）」的概念開始受到重視。幾個月下來，隨著媒體的報導，讓開放手機平臺概念的大量且持續的曝光，越來越多人在網路上討論這樣的概念，而真正的引爆點則是 Android 原型機的現身。今年的 Mobile World Congress 展上出現了 Android 的原型機，這裡有一些 Android 原型機的照片 [<a href="http://www.engadget.com/2008/02/11/google-attacks-android-at-mobile-world-congress/">Google attacks: Android at Mobile World Congress</a>]，如果您希望了解更多有關 Android 原型機的資訊，這篇也是入口文。

「開放手機平臺」（或精確來說「開放式智慧型手機作業系統與平臺」）在二零零八年正式引爆。[<a href="http://code.google.com/android/">Android</a>] 是 Google 所提出的開放手機軟體平臺，根據 [Open Handset Alliance]（OHA）的報導，Android 提供 mobile device 完整的軟體環境，包含：作業系統（Linux）、中介軟體（middleware）與主要的 mobile applications。Open Handset Alliance 是由 Google 登高一呼所成立的行動裝置開放平臺聯盟，聯盟成員包含電信業者、手機廠造商、手機軟體公司、半導體公司等，共計三十四個會員。

Linux 作業系統在開放手機平臺佔有舉足輕重的角色，Android 的系統層使用 Linux 2.6 作業系統核心，OpenMoko 平臺也是採用 Linux 2.6 作業系統核心，另外一個重要的開放手機平臺 GMAE 也是基於 Linux 作業系統。這次不只一家廠商在 Mobile World Congress 上展示 Android 原型機，其中有一款是採用 TI OMAP 3430 處理器（執行速度 500 MHz），這款原型機平臺，即將在二個月內對開發者（developer）販售，這是一個令人興奮的好消息！

另外還有二個知名的商業導向開放手機平臺，分別是 OpenMoko 與 Trolltech Qtopia。Trolltech 公司日前被 Nokia 以1.5 億美金的代價收購，Trolltech 是一家知名的跨平臺 GUI 軟體製造商，同時也在 Linux 手機領域中享有盛名。Trolltech 的 Qtopia 產品是專門針對行動與嵌入式裝置所開發的行動裝置平臺，由於 Trolltech 採取雙授權的商業模式，因此開發者也能取得以 GPLv2 授權的 Qtopia 原始碼。

開放手機的概念出現後，宣告「Mobile 2.0」時代的來臨。去年（二零零七年）十月十五日於 San Francisco 所舉行的「 Mobile 2.0」研討上，討論了幾個重要的 Mobile 2.0 革命性新觀念：

1. 使用者參與開發（developing）與設計（design）
2. 使用者經驗（user experience）的回饋
3. 資料（data）傳輸
4. 相異於過去的商業模式

此外，Mobile 2.0 與「網路服務（web service）」的整合也將會是相當重要的項目。早在二年前（二零零六年），Nokia 就公佈一種稱為 WidSets 的手機元件平臺，「<a href="http://www.widsets.com">WidSets</a>」是一種手機資料傳輸的新技術，透過 Widsets 上的元件，我們能將 web 上的  email、blog、RSS、video 等內容傳送到手機上，並在手機上閱讀。目前 Widsets 網站上提供超過 2000 種不同的元件，並且支持超過 300 支不同型號手機。

Android 平臺於二月十三日釋出 RC14，這次的釋出版本裡包含最新的 Linux kernel（linux 2.6.23）以及 Android Emulator 原始碼，其它 Android 平臺的原始碼還包含：Android 開發工具原始碼（Eclipse plugin）以及 Webkit 原始碼，程式可由 [<a href="http://code.google.com/p/android/downloads/list">Android - Google Code</a>] 下載。]]>
      
   </content>
</entry>
<entry>
   <title>OpenMoko 對 Android 的「官方」看法</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/02/openmoko_perspective_to_android.html" />
   <id>tag:www.jollen.org,2008:/blog//2.477</id>
   
   <published>2008-02-14T09:09:22Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>OpenMoko 的 project lead &apos;Sean Moss-Pultz&apos; 今天接受專訪時，正式提出他對開放手機以及對其他競爭對手的看法。其中，關於 Android 的出現對同樣也是開放平臺的 OpenMoko 有何影響，以及對 OpenMoko 會有什麼衝擊，Sean 今天也都提出他的看法。 首先，對於開放手機這件事情來說，Sean 認為這是不相衝突的二件事情，其觀念在於：一、OpenMoko 本身是一家做「產品」的公司；Google 的 Android 是提供「平臺」的方案。二、OpenMoko 想要做的是 100% 開放源碼的手機平臺，並透過開放平臺建立可獲利的商業模式；但 OHA 旨在發掘商業機會，並不是專注在製作一個 100% 開放源碼的手機軟體平臺。總合來說，Sean 提到「OpenMoko 與 Android 是二個商業模式、二個不相干的東西」。 此外，專訪過程也問到一個根本的問題「OpenMoko 與 Android 軟體的比較與差異」，這是一個技術面的問題，早在一月二十二日，由 Wolfgang Spraul（OpenMoko 工程部門副總）對內部所發出的一封 email 提到「So...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[OpenMoko 的 project lead 'Sean Moss-Pultz' 今天接受專訪時，正式提出他對開放手機以及對其他競爭對手的看法。其中，關於 Android 的出現對同樣也是開放平臺的 OpenMoko 有何影響，以及對 OpenMoko 會有什麼衝擊，Sean 今天也都提出他的看法。

首先，對於開放手機這件事情來說，Sean 認為這是不相衝突的二件事情，其觀念在於：一、OpenMoko 本身是一家做「產品」的公司；Google 的 Android 是提供「平臺」的方案。二、OpenMoko 想要做的是 100% 開放源碼的手機平臺，並透過開放平臺建立可獲利的商業模式；但 OHA 旨在發掘商業機會，並不是專注在製作一個 100% 開放源碼的手機軟體平臺。總合來說，Sean 提到「OpenMoko 與 Android 是二個商業模式、二個不相干的東西」。

此外，專訪過程也問到一個根本的問題「OpenMoko 與 Android 軟體的比較與差異」，這是一個技術面的問題，早在一月二十二日，由 Wolfgang Spraul（OpenMoko 工程部門副總）對內部所發出的一封 email 提到「So we are trying to position OpenMoko as a superset of Android. Android is just a GUI toolkit.」，意即「就技術面而言，我們可以讓 Android 在 OpenMoko 平臺上執行」，這是 OpenMoko 對 Android 的官方看法。Wolfgang 在他的 email 提到，這項看法並不是 OpenMoko 的內部機密。今天透過專訪由 Sean 本人親口提出這項看法，因此終於可以正式公諸於世。

從技術面來看，Sean 也提到「OpenMoko 是一個平臺，由底層 kernel 到上層 application 都可以被修改」，但「Android 只是一個 GUI toolkit」，因此，若由這個角度來看，Sean 也說「OpenMoko 與 Android 是沒有衝突的二個技術平臺」。

<strong>延伸閱讀</strong>

* 2008.01.09: <a href="http://www.jollen.org/blog/2008/01/first_android_phone.html">First Android Phone？</a>
* 2007.12.02: <a href="http://www.jollen.org/blog/2007/12/android_apache_license_not_gpl.html">Google Android 採用 Apache License: 為什麼不是 GPL？</a>
* 2007.11.09: <a href="http://www.jollen.org/blog/2007/11/android_gphone.html">Android 與 Gphone 觀察</a>]]>
      
   </content>
</entry>
<entry>
   <title>MontaVista Mobilinux 5.0 入圍 EDN 年度創新獎</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/02/montavista_edn_innovation_award.html" />
   <id>tag:www.jollen.org,2008:/blog//2.475</id>
   
   <published>2008-02-07T05:47:58Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>MontaVista 的 Mobilinux 5.0 入圍 [EDN（Electronics Design, Strategy, News）] 舉辦的 [第 18 屆創新獎（Innovation Award）]。第 18 屆 EDN 創新獎共分為 20 個類別，Mobilinux 入圍的是軟體類，除了 Mobilinux 外，另外三個軟體類的入圍名單如下： * Graphics library (Microchip Technology) * LabView 8.5 (National Instruments) * Robotics Studio (Microsoft) MontaVista 指出，目前有 90%...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[MontaVista 的 Mobilinux 5.0 入圍 [<a href="http://www.edn.com">EDN（Electronics Design, Strategy, News）</a>] 舉辦的 [<a href="http://www.edn.com/info/CA6522717.html?industryid=48661">第 18 屆創新獎（Innovation Award）</a>]。第 18 屆 EDN 創新獎共分為 20 個類別，Mobilinux 入圍的是軟體類，除了 Mobilinux 外，另外三個軟體類的入圍名單如下：

 * Graphics library (Microchip Technology)
 * LabView 8.5 (National Instruments)
 * Robotics Studio (Microsoft)

MontaVista 指出，目前有 90% 的 Linux smartphone 都是採用 MontaVista Linux Professional Edition。最後的年度創新獎得主將在四月十四日公佈。此外，MontaVista 也將在 2/11~2/14 於西班牙所舉辦的「<a href="http://www.mobileworldcongress.com/homepage.htm">GSMA Mobile World Congress</a>」展覽上參與展示。

GSMA Mobile World Congress 是全球行動通訊業的年度大拜拜，這是全球最大的行動產業展覽，現場將會集各大手機製造商、電信業者、以及內容供應商等等，各路人馬都會在這裡展示最新的產品以及概念。這是 CES 後另一個重要的科技展，GSMA Mobile World Congress 滿足單點購足的需求，走一趟就能網羅全球行動通訊產業的重要資訊，是一場不可錯過的展覽。

MontaVista 的產品能入圍 EDN 年度創新獎，並參與全球最大行動通訊業的展覽，足以表示 MontaVista 在 Linux smartphone 領域上的代表地位，同時，我們也看見開放源碼的 Linux 手機軟體走入了行動與電信業的生態系裡。從 MontaVista 的活動軌跡來看， Mobilinux 走的方向是「正規戰」，也就是由「聯盟」、「標準」以及「供應商」的角度前進；與 OpenMoko 比較的話，OpenMoko 本身並不是從這三個角度切入，而是由社群以及個人用戶的角度切入，與正規戰相較，OpenMoko 比較像是「街頭賣藝」的模式。

<strong>延伸閱讀</strong>

2006.11.16: <a href="http://www.jollen.org/blog/2006/11/montavista_dev_rock_5_linux_id.html">MontaVista 推出 Dev Rock 5 嵌入式 Linux 開發工具之《殺手級 IDE 快快出現！》</a>]]>
      
   </content>
</entry>
<entry>
   <title>Nokia 收購 Trolltech</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/01/nokia_acquire_trolltech.html" />
   <id>tag:www.jollen.org,2008:/blog//2.474</id>
   
   <published>2008-01-29T12:16:57Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>今天來自 linuxdevices.com 上的一則消息 [Nokia to acquire Trolltech for $150 million] 表示，Nokia 將以 1.5 億美金的代價收購 [Trolltech] 公司。Trolltech 是一家知名的跨平臺 GUI 軟體製造商，同時也在 Linux 手機領域中享有盛名。 Symbian 是一家獨立的手機軟體公司，Nokia 擁有將近五成（47.9%）的持股，Nokia 過去大多以 [symbian] 作業系統來製造手機，近年來也有少量使用 Linux 的產品問世。Trolltech 的 Qtopia 產品是專門針對行動與嵌入式裝置所開發的 application platform 與 UI，Qtopia 能夠支援 Linux 與 Windows...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Open Mobile Platform" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[今天來自 linuxdevices.com 上的一則消息 [<a href="http://linuxdevices.com/news/NS8066582994.html">Nokia to acquire Trolltech for $150 million</a>] 表示，Nokia 將以 1.5 億美金的代價收購 [<a href="http://trolltech.com/">Trolltech</a>] 公司。Trolltech 是一家知名的跨平臺 GUI 軟體製造商，同時也在 Linux 手機領域中享有盛名。

Symbian 是一家獨立的手機軟體公司，Nokia 擁有將近五成（47.9%）的持股，Nokia 過去大多以 [<a href="http://www.symbian.com">symbian</a>] 作業系統來製造手機，近年來也有少量使用 Linux 的產品問世。Trolltech 的 Qtopia 產品是專門針對行動與嵌入式裝置所開發的 application platform 與 UI，Qtopia 能夠支援 Linux 與 Windows CE 平臺，並且能讓製造廠完整客製化 UI。

Nokia 在收購 Trolltech 後，將會持續開發 Trolltech 的產品線，並且也會持續保持授權的商業模式。原有的手機製造商，以及有意願採用 Qtopia 的新客戶，都能向 Trolltech 取得商業授權。此外，可以預料的是，Qt 以及 Qtopia 也將能支援 Symbian 平臺，未來搭載 Symbian 作業系統的智慧型手機，都會有更棒的 UI。

Nokia 在行動裝置軟體以及桌面應用軟體採取跨平臺的策略，在收購 Trolltech 後，將可以加速此項策略的推行；同時，可以預期 Nokia 將會製造更多 Linux 平臺的手機。過去 Nokia 在 Linux 平臺的努力有目共睹，[<a href="http://maemo.org/">maemo</a>] 專案以 Linux 以及 GTK+ 打造的 maemo SDK 已成為知名的 Linux 開放源碼專案，maemo 的開發者社群也相當熱絡，Nokia 的 [<a href="http://www.nseries.com/products/n800/#l=products,n800">N800</a>] 就是採用 maemo 平臺所開發的產品 。]]>
      
   </content>
</entry>
<entry>
   <title>libusb 簡介與第一個範例</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/01/libusb_hello_world.html" />
   <id>tag:www.jollen.org,2008:/blog//2.469</id>
   
   <published>2008-01-25T07:49:43Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>[libusb] 是一個 user-space 的 USB 程式庫，在 embedded linux 應用實作上，我們會使用 libusb 實作一個 host 端的應用程式，並透過 USB 介面存取或控制 target device。 找到所有 USB bus 與 USB device 要撰寫一支 user-space 的 USB device 控制程式，最首要的工作就是找到自己的 USB 裝置。這個工作主要透過以下 4 個函數來進行： usb_init: 初始化 libusb usb_find_busses: 尋找系統裡的所有 USB bus...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="GNU Toolchains &amp; Linux Systems Programming" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[<p>[<a href="http://libusb.sourceforge.net/">libusb</a>] 是一個 user-space 的 USB 程式庫，在 embedded linux 應用實作上，我們會使用 libusb 實作一個 host  端的應用程式，並透過 USB 介面存取或控制 target device。</p>

<strong>找到所有 USB bus 與 USB device</strong>

<p>要撰寫一支 user-space 的 USB device 控制程式，最首要的工作就是找到自己的 USB 裝置。這個工作主要透過以下 4 個函數來進行：</p>

<ul>
<li>usb_init: 初始化 libusb</li>
<li>usb_find_busses: 尋找系統裡的所有 USB bus</li>
<li>usb_find_devices: 尋找所有的 USB bus 上的所有 USB device</li>
<li>usb_get_busses: 傳回找到的 USB bus</li>
</ul>

<p>程式一開始必須先呼叫 usb_init 將 libusb 做初始化，這是 libusb 程式第一個要呼叫的函數。接著依序呼叫 usb_find_busses 與 usb_find_devices 找到所有的 USB bus 與 USB device。</p>

<p>最後，呼叫 usb_get_busses 取得所有找到的 USB bus。程式如下：</p>

<pre>
    usb_init();
    usb_find_busses();
    usb_find_devices();

    struct usb_bus *busses;
    busses = usb_get_busses();
</pre>

<p>*busses 指向一個串列資料結構（struct usb_bus），訪問這個串列即可找到所有的 USB 裝置。</p>

<strong>偵測 USB 裝置</strong>

<p>接下來，我們要在所有的 USB bus 上偵測系統是否有我們的 USB device。以下是這段程式的框架：</p>

<pre>
    struct usb_bus *bus;
    for (bus = busses; bus; bus = bus->next) {
	    struct usb_device *dev;

	    for (dev = bus->devices; dev; dev = dev->next) {
               struct usb_device_descriptor *desc;

               desc = &(dev->descriptor);
               printf("Vendor/Product ID: %04x:%04x\n", desc->idVendor, desc->idProduct);
	    }
    }
</pre>

<p>這段演算法可以將系統上所有 USB device 的 vendor id 與 product id 印出來。假如，我們想找到特定的 USB 裝置，這時就可以設計一個這樣的函數（假設我們想要找的 USB 裝置是 0xffff/0x0001）：</p>

<pre>
struct usb_device *usbio_probe()
{
    struct usb_bus *busses, *bus;
    int c, i, a;

    usb_init();
    usb_find_busses();
    usb_find_devices();

    busses = usb_get_busses();

    for (bus = busses; bus; bus = bus->next) {
	struct usb_device *dev;

	for (dev = bus->devices; dev; dev = dev->next) {
	    struct usb_device_descriptor *desc;

	    desc = &(dev->descriptor);
	    printf("Vendor/Product ID: %04x:%04x\n", desc->idVendor,
		   desc->idProduct);
	    if ((desc->idVendor == 0xffff) && (desc->idProduct == 0x0001)) {
		return dev;
	    }
	}
    }

    return NULL;
}
</pre>

<strong>開始操作 USB 裝置</strong>

<p>找到我們的 USB device 後，接著就可以對它進行操作（讀/寫）。如同操作檔案般，我們要先對 USB device 做開啟的動作，方式是呼叫 usb_open 函數：</p>

<blockquote>usb_dev_handle *usb_open(struct *usb_device dev);</blockquote>

<p>開啟成功後，會傳回此裝置的 <strong>handle</strong>。</p>

<strong>第一個 libusb 程式</strong>

<p>以下提供學習 libusb 的第一個範例程式：</p>

<pre>
/*
 * findusb.c - A libusb sample program.
 *
 *  Authored by Jollen Chen <jollen@jollen.org>
 *
 *  Copyright (C) 2008 www.jollen.org
 *  Copyright (C) 2008 Jollen's Consulting, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Public License as published by
 *  the Free Software Foundation; version 2 of the license.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser Public License for more details.
 *
 */

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;usb.h&gt;
#include &lt;libusb.h&gt;

void usbio_main(struct usb_device *dev)
{
    usb_dev_handle *dev_handle;

    dev_handle = usb_open(dev);

    if (dev_handle == NULL) {
	printf("USB IO open failed.\n");
	return;
    }

    usb_close(dev_handle);
}

struct usb_device *usbio_probe()
{
    struct usb_bus *busses, *bus;
    int c, i, a;

    usb_init();
    usb_find_busses();
    usb_find_devices();

    busses = usb_get_busses();

    for (bus = busses; bus; bus = bus->next) {
	struct usb_device *dev;

	for (dev = bus->devices; dev; dev = dev->next) {
	    struct usb_device_descriptor *desc;

	    desc = &(dev->descriptor);
	    printf("Vendor/Product ID: %04x:%04x\n", desc->idVendor,
		   desc->idProduct);
	    if ((desc->idVendor == 0xffff) && (desc->idProduct == 0x0001)) {
		return dev;
	    }
	}
    }

    return NULL;
}

int main()
{
    struct usb_device *dev;
    struct usb_device_descriptor *desc;

    dev = usbio_probe();
    desc = &(dev->descriptor);

    if (dev == NULL) {
	printf("USB IO Card not found.\n");
	return -1;
    }

    printf("SUB IO Card found.\n");
    printf("Vendor/Product ID: %04x:%04x\n", desc->idVendor,
	   desc->idProduct);

    usbio_main(dev);
}
</pre>

<p>檔案可由 [<a href="http://tw.jollen.org/findusb/">http://tw.jollen.org/findusb/</a>] 下載。這裡提供一個 Makefile 檔案；編譯時，請記得安裝 libusb 並與 libusb 做連結。</p>

<strong>網路資源</strong>

<p>* libusb API 文件. <a href="http://libusb.sourceforge.net/doc/">http://libusb.sourceforge.net/doc/</a></p>]]>
      
   </content>
</entry>
<entry>
   <title>OpenMoko 近況更新：Neo FreeRunner、Job Positions 與 Education</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/01/openmoko_fresh_news_2008.html" />
   <id>tag:www.jollen.org,2008:/blog//2.468</id>
   
   <published>2008-01-21T03:48:55Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>自從先前分享了 OpenMoko 的 OpenLab 活動後，己經很久沒有再跟大家更新相關消息了。在這裡一次將 OpenMoko 的近況做更新。 Neo FreeRunner OpenMoko 在今年的 [CES 2008]（美國消費性電子大展）上，正式揭露新一代產品 Neo FreeRunner。新的 Neo FreeRunner 的對象是終端消費者，並且在硬體端加入了 WiFi、motion sensor 以及 3D 處理器。Neo FreeRunner 的軟體也是基於 OpenMoko，不過以現在的軟體狀況來看，要面對真正的消費者，還需要一些時間。 OpenMoko Open Job Positions 在臺灣的朋友有福了，OpenMoko 正式提供工作機會，詳情可參考 [OpenMoko Visits and Hiring Day]。這是 OpenMoko 首次提供公開的工作機會，過去 OpenMoko...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Openmoko" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[自從先前分享了 OpenMoko 的 OpenLab 活動後，己經很久沒有再跟大家更新相關消息了。在這裡一次將 OpenMoko 的近況做更新。

<strong>Neo FreeRunner</strong>

OpenMoko 在今年的 [<a href="http://www.cesweb.org/">CES 2008</a>]（美國消費性電子大展）上，正式揭露新一代產品 Neo FreeRunner。新的 Neo FreeRunner 的對象是終端消費者，並且在硬體端加入了 WiFi、motion sensor 以及 3D 處理器。Neo FreeRunner 的軟體也是基於 OpenMoko，不過以現在的軟體狀況來看，要面對真正的消費者，還需要一些時間。

<strong>OpenMoko Open Job Positions</strong>

在臺灣的朋友有福了，OpenMoko 正式提供工作機會，詳情可參考 [<a href="http://wiki.openmoko.org/wiki/OpenMoko_Visits_and_Hiring_Day/zh_tw">OpenMoko Visits and Hiring Day</a>]。這是 OpenMoko 首次提供公開的工作機會，過去 OpenMoko 的開發者都是在 open source 社群裡找來的高手，或是透過朋友介紹。

<strong>OpenMoko Education</strong>

OpenMoko 因為開放源碼的特性，因此也很適合應用在教學或研究用途。OpenMoko 將在下學期支持幾個學校的研究計畫，並提供學生實習機會，讓學生也能在學校進行「手機軟體」的研究計畫。

<strong>延伸閱讀 </strong>

2007.11.21: <a href="http://www.jollen.org/blog/2007/11/openmoko_openlab_intro_v1.html">OpenMoko 專案介紹與 OpenLab</a>]]>
      
   </content>
</entry>
<entry>
   <title>Linux 驅動程式的 Semaphore 觀念小談</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/01/linux_device_driver_semaphore_discussion.html" />
   <id>tag:www.jollen.org,2008:/blog//2.466</id>
   
   <published>2008-01-20T02:53:22Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>這二天在進行 Linux 驅動程式的訓練，課程裡談論到 semaphore 可以用來宣告 critical section。在作業系統所述敘的 critical section 觀念中提及，critical section 具備互斥性（mutual exclusive）與單一性（atomic）。對單一性來講，我們必須確保在 critical section 裡不會發生任何的排程（scheduling）動作，wait queue 的使用就是一個例子。Linux kernel 提供的 wait queue 可以讓驅動程式在進行 I/O polling 時，以睡覺（sleep）方式進行，以讓出系統時間；若以 busy-loop 方式進行，是不正確的做法。 所以，sleep 的動作就不能寫在 critical section 裡面，必須先做一個釋放的動作，再呼叫 wait queue 的 API 做睡覺的動作，醒來後再進入 critical section。但是，事情並沒有這麼單純，若是驅動程式的架構設計，能支援多個...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Linux Device Drivers &amp; Kernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[這二天在進行 Linux 驅動程式的訓練，課程裡談論到 semaphore 可以用來宣告 critical section。在作業系統所述敘的 critical section 觀念中提及，critical section 具備互斥性（mutual exclusive）與單一性（atomic）。對單一性來講，我們必須確保在 critical section 裡不會發生任何的排程（scheduling）動作，wait queue 的使用就是一個例子。Linux kernel 提供的 wait queue 可以讓驅動程式在進行 I/O polling 時，以睡覺（sleep）方式進行，以讓出系統時間；若以 busy-loop 方式進行，是不正確的做法。

所以，sleep 的動作就不能寫在 critical section 裡面，必須先做一個釋放的動作，再呼叫 wait queue 的 API 做睡覺的動作，醒來後再進入 critical section。但是，事情並沒有這麼單純，若是驅動程式的架構設計，能支援多個 minor device，就必須考慮可重覆進入的問題，這個時候，semaphore 的信號燈（semaphore variable）就要放在私有空間裡，Linux 驅動程式用 <em>struct file</em> 裡的 <em>private_data</em> 欄位來實作。對 wait queue 來講，我們也是將 wait queue 變數擺放在私有空間裡。

從互斥性的角度來講，semaphore 的使用可能是要用來保護資料，以避免資源衝突，因此將程式碼互斥。只是，kernel 所提供的睡覺 API，在真正重做排程前，還有對傳入的參數做存取，而這個參數就是擺在私有空間裡的 wait queue，於是便可能仍有同步（race condition）的問題。
]]>
      
   </content>
</entry>
<entry>
   <title>下週二的嵌入式系統大拜拜：DTF 2008 Embedded World</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/01/go_to_dtf_2008.html" />
   <id>tag:www.jollen.org,2008:/blog//2.464</id>
   
   <published>2008-01-17T05:29:22Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>下週二即將舉行的 DTF 2008 Embedded World 是嵌入式系統年度的大拜拜，當天的議程相當精采，還沒報名的朋友要趕快把握機會喔！全程都是免費參加，有興趣的朋友可參考 [詳細的活動說明]。 當天的議程之一是「嵌入式系統發展機會－我們能做什麼?」，這是由教育部嵌入式軟體聯盟召集人金仲達教授所帶來的演說。[嵌入式軟體聯盟] 多年來致力於規劃嵌入式系統課程，在校園培育許多嵌入式軟體的人才。金教授的演說我想會由教育層面切入，這是一個了解目前嵌入式系統在校園紮根狀況的很好機會。 x86 架構近來在嵌入式系統應用佔用非常重要的角色，Track I 的議題針對 x86 嵌入式解決方案做介紹，也是很不錯的議題規劃。Graphics solution 一直是嵌入式系統應用的關鍵技術，許多應用都需要 graphics 的解決方案。 Track II 的議題偏向 SOC 的設計，我自己對「Natural Evolution in the embedded world」這個議程相當感興趣，這是由 ARM 公司行銷部門的經理 Tom Wang 所帶來的演說，ARM 一直是嵌入式 SOC 的領導者，這場演說必定可以吸收到許多新觀念。 Track III 的議題則是著重在嵌入式應用與服務，觸控面板在嵌入式的應用佔用重要地位，圖形化設計也是我自己很感興趣的主題。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[下週二即將舉行的 DTF 2008 Embedded World 是嵌入式系統年度的大拜拜，當天的議程相當精采，還沒報名的朋友要趕快把握機會喔！全程都是免費參加，有興趣的朋友可參考 [<a href="http://edu.jollen.org/2008/01/dtf_2008_embedded_world.html">詳細的活動說明</a>]。

當天的議程之一是「嵌入式系統發展機會－我們能做什麼?」，這是由教育部嵌入式軟體聯盟召集人金仲達教授所帶來的演說。[<a href="http://esw.cs.nthu.edu.tw/">嵌入式軟體聯盟</a>] 多年來致力於規劃嵌入式系統課程，在校園培育許多嵌入式軟體的人才。金教授的演說我想會由教育層面切入，這是一個了解目前嵌入式系統在校園紮根狀況的很好機會。

x86 架構近來在嵌入式系統應用佔用非常重要的角色，Track I 的議題針對 x86 嵌入式解決方案做介紹，也是很不錯的議題規劃。Graphics solution 一直是嵌入式系統應用的關鍵技術，許多應用都需要 graphics 的解決方案。

Track II 的議題偏向 SOC 的設計，我自己對「Natural Evolution in the embedded world」這個議程相當感興趣，這是由 ARM 公司行銷部門的經理 Tom Wang 所帶來的演說，ARM 一直是嵌入式 SOC 的領導者，這場演說必定可以吸收到許多新觀念。

Track III 的議題則是著重在嵌入式應用與服務，觸控面板在嵌入式的應用佔用重要地位，圖形化設計也是我自己很感興趣的主題。]]>
      
   </content>
</entry>
<entry>
   <title>First Android Phone？</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/01/first_android_phone.html" />
   <id>tag:www.jollen.org,2008:/blog//2.458</id>
   
   <published>2008-01-09T04:14:25Z</published>
   <updated>2008-07-13T09:56:47Z</updated>
   
   <summary>來自台灣的 [啟碁科技（WNC）] 在 CES 上展示一支 GSM/VoWiFi 的雙模手機，並且是採用 Linux 作業系統核心，同時，也有小道消息指出，Google Android 平臺也會移植到該手機，並且可能的時間是在今年三月，若消息屬於，WNC 將會是第一個發佈 Android 相容手機的廠商。新聞全文 [First Android phone?]。 同一時間，另一個也是開放手機平臺的 OpenMoko 也公佈 Dash Express 的消息，以及 Neo FreeRunner（GTA02）的產品規格。單純以「開放手機系統」來講的話，雖然這二個被廣為注目的開放手機產品有機會同時現身，但嚴格來講，Google Android 平臺似乎己經佔了上風，因為目前尚沒有其他廠商能夠利用 OpenMoko 平臺來生產 end-user 手機，但 Android 己經快做到了。 延伸閱讀 2007.11.09: Android 與 Gphone 觀察 2007.12.02:...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Open Mobile Platform" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[來自台灣的 [<a href="http://www.wneweb.com.tw/chinese/index.htm">啟碁科技（WNC）</a>] 在 CES 上展示一支 GSM/VoWiFi 的雙模手機，並且是採用 Linux 作業系統核心，同時，也有小道消息指出，Google Android 平臺也會移植到該手機，並且可能的時間是在今年三月，若消息屬於，WNC 將會是第一個發佈 Android 相容手機的廠商。新聞全文 [<a href="http://www.linuxdevices.com/news/NS6697265909.html">First Android phone?</a>]。

同一時間，另一個也是開放手機平臺的 OpenMoko 也公佈 Dash Express 的消息，以及 Neo FreeRunner（GTA02）的產品規格。單純以「開放手機系統」來講的話，雖然這二個被廣為注目的開放手機產品有機會同時現身，但嚴格來講，Google Android 平臺似乎己經佔了上風，因為目前尚沒有其他廠商能夠利用 OpenMoko 平臺來生產 end-user 手機，但 Android 己經快做到了。

<strong>延伸閱讀</strong>

2007.11.09: <a href="http://www.jollen.org/blog/2007/11/android_gphone.html">Android 與 Gphone 觀察</a>
2007.12.02: <a href="http://www.jollen.org/blog/2007/12/android_apache_license_not_gpl.html">Google Android 採用 Apache License: 為什麼不是 GPL？</a>]]>
      
   </content>
</entry>
<entry>
   <title>1/8 tossug 分享活動：用中文寫 Python / 周蠎</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/01/zhpy_python.html" />
   <id>tag:www.jollen.org,2008:/blog//2.457</id>
   
   <published>2008-01-08T13:13:46Z</published>
   <updated>2008-02-19T21:38:02Z</updated>
   
   <summary>今天 [tossug] 的分享主題是 [使用 Python 與周蟒]，周蠎（zhpy）是一個可以執行中文 Python 程式的軟體，周蠎讓我們可以用中文來寫 Python 程式，真是一個有趣的主題。zhpy 的下載位址是： http://code.google.com/p/zhpy/ 現場 gasolin 展示了一個用 Python 設計的文字遊戲編輯引擎，叫做 [Ren&apos;Py]，這是一個可以製作類似角色扮演遊戲的編輯器。 最後 gasolin 也提到，Python 是去年（2007）成長速度最快的程式語言，也是目前相當受到重視的程式語言。網路上常見的「懶人包」就是利用 Python 撰寫的工具製作的，最近 Google 也在招募 Python 高手，顯見 Python 真的是一個重要的程式語言。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[今天 [<a href="http://tossug.org">tossug</a>] 的分享主題是 [<a href="http://tossug.org/pipermail/hojia/2008-January/000162.html">使用 Python 與周蟒</a>]，周蠎（zhpy）是一個可以執行中文 Python 程式的軟體，周蠎讓我們可以用中文來寫 Python 程式，真是一個有趣的主題。zhpy 的下載位址是：

<blockquote><a href="http://code.google.com/p/zhpy/">http://code.google.com/p/zhpy/</a></blockquote>

現場 gasolin 展示了一個用 Python 設計的文字遊戲編輯引擎，叫做 [<a href="http://www.renpy.org/wiki/renpy/Home_Page">Ren'Py</a>]，這是一個可以製作類似角色扮演遊戲的編輯器。

最後 gasolin 也提到，Python 是去年（2007）成長速度最快的程式語言，也是目前相當受到重視的程式語言。網路上常見的「懶人包」就是利用 Python 撰寫的工具製作的，最近 Google 也在招募 Python 高手，顯見 Python 真的是一個重要的程式語言。]]>
      
   </content>
</entry>
<entry>
   <title>2008 開工了！</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2008/01/2008_101_fireworks.html" />
   <id>tag:www.jollen.org,2008:/blog//2.453</id>
   
   <published>2007-12-31T19:51:20Z</published>
   <updated>2008-02-19T21:38:02Z</updated>
   
   <summary>新的 2008 年，「Jollen&apos;s Blog」會把重點放在「Linux kernel」與「Linux device driver」，並且也會將一些時間放在 Embedded Linux 教育訓練的課程規劃上；期待您的意見與指教。 延伸閱讀 2007.01.01: 2007 開工了！...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="其它" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[新的 2008 年，「Jollen's Blog」會把重點放在「Linux kernel」與「Linux device driver」，並且也會將一些時間放在 Embedded Linux 教育訓練的課程規劃上；期待您的意見與指教。

<img src="http://tw.jollen.org/photos/2008_101_fireworks/2008_101_fireworks_01.jpg" />

<img src="http://tw.jollen.org/photos/2008_101_fireworks/2008_101_fireworks_02.jpg" />

<img src="http://tw.jollen.org/photos/2008_101_fireworks/2008_101_fireworks_03.jpg" />

<img src="http://tw.jollen.org/photos/2008_101_fireworks/2008_101_fireworks_04.jpg" />

<img src="http://tw.jollen.org/photos/2008_101_fireworks/2008_101_fireworks_05.jpg" />

<strong>延伸閱讀</strong>

2007.01.01: <a href="http://www.jollen.org/blog/2007/01/2007_new_year.html">2007 開工了！</a>]]>
      
   </content>
</entry>
<entry>
   <title>qemu + Linux kernel 模擬與除錯環境實習</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2007/12/qemu_linux_kernel_debug.html" />
   <id>tag:www.jollen.org,2007:/blog//2.451</id>
   
   <published>2007-12-31T07:41:48Z</published>
   <updated>2008-02-19T21:38:02Z</updated>
   
   <summary>Qemu 是一個功能強大的「processor emulator」，qemu system emulator 還能模擬開發板的週邊。此外，qemu 還包含一個 gdb server 的實作，配合 gdb client 能組合出一個很棒的 kernel &amp; device driver「source-level debug」環境。 Jollen-Kit! Pro. 是由 jollen.org 所推出的 ARM9 開發板，主要用途是拿來做 Embedded Linux 的教育訓練。在前一陣子的 Linux Device Driver 訓練課程中，特別規劃了一個時段的「qemu + Linux kernel 模擬與除錯環境實習」的操作課程，此課程所採用的 qemu 能模擬我們的 Jollen-Kit! Pro....</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="GNU Toolchains &amp; Linux Systems Programming" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Qemu 是一個功能強大的「processor emulator」，qemu system emulator 還能模擬開發板的週邊。此外，qemu 還包含一個 gdb server 的實作，配合 gdb client 能組合出一個很棒的 kernel & device driver「source-level debug」環境。

Jollen-Kit! Pro. 是由 jollen.org 所推出的 ARM9 開發板，主要用途是拿來做 Embedded Linux 的教育訓練。在前一陣子的 Linux Device Driver 訓練課程中，特別規劃了一個時段的「qemu + Linux kernel 模擬與除錯環境實習」的操作課程，此課程所採用的 qemu 能模擬我們的 Jollen-Kit! Pro. 開發板，同時也介紹如何設定 breakpoint 以進行 kernel debug。

在此提供實習簡報電子檔 [<a href="http://tw.jollen.org/slides/qemu_jk2410_cgdb.pdf">qemu_jk2410_cgdb</a>] 供下載。由於這是帶領操作的課程，簡報內容可能帶不到一些細節，但主要的內容大多能帶出，還請見諒。本月即將於台北開班的 [<a href="http://www.jollen.org/consulting/training.html">Linux Device Driver 課程</a>]，也會介紹 qemu 除錯環境的安裝與操作指導。

若台北教室時段許可，或許可以提供免費的 seminar 課程。

<strong>延伸閱讀</strong>

2007.04.19: <a href="http://www.jollen.org/blog/2007/04/qemu_hw_emulation_how.html">Qemu 模擬週邊的兩三事</a>
2007.04.18: <a href="http://www.jollen.org/blog/2007/04/cpustate_qemu_gdbserver.html">再聊 CPUState、qemu 的 gdbserver</a>
2007.04.11: <a href="http://www.jollen.org/blog/2007/04/qemu_cpustate_object.html">小聊 qemu 的 CPUState</a>
2007.04.08: <a href="http://www.jollen.org/blog/2007/04/qemu_neo1973_openmoko_jk2410.html">qemu-neo1973 / openmoko-emulator / jk2410-emulator</a>
2006.09.28: <a href="http://www.jollen.org/blog/2006/09/qemu.html">QEMU 虛擬機器</a>
]]>
      
   </content>
</entry>
<entry>
   <title>新的 Linux Wireless Stack 現身</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2007/12/new_linux_wireless_stack.html" />
   <id>tag:www.jollen.org,2007:/blog//2.450</id>
   
   <published>2007-12-29T15:14:22Z</published>
   <updated>2008-02-19T21:38:02Z</updated>
   
   <summary>Linux 2.6.22 有一個重要的更新，就是改進了過去對於 wireless 支持的不足。一家叫做 [Devicespace] 的公司，為 open source 做了一項重要的貢獻，他們將一份新的 wireless stack 實作提交給 kernel，並正式收錄於 Linux 2.6.22。詳情可參考 kernelnewbies.org 上的說明 [New Wireless stack]。 Linux 在 wireless stack 上的功能並不是很充份，在 Devicespace 貢獻 kernel 更好的全新 wireless stack 實作後，對 Linux 在無線網路上的支援與應用，將是一個重要的進展。由 Devicespace 所提交的新一代 wireless stack 包含的實作有（引述...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Linux Device Drivers &amp; Kernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Linux 2.6.22 有一個重要的更新，就是改進了過去對於 wireless 支持的不足。一家叫做 [<a href="http://www.devicescape.com/pub/">Devicespace</a>] 的公司，為 open source 做了一項重要的貢獻，他們將一份新的 wireless stack 實作提交給 kernel，並正式收錄於 Linux 2.6.22。詳情可參考 kernelnewbies.org 上的說明 [<a href="http://kernelnewbies.org/Linux_2_6_22#head-1498b990e997cc0e95dbfa9047e7ebe8d84847cc">New Wireless stack</a>]。

Linux 在 wireless stack 上的功能並不是很充份，在 Devicespace 貢獻 kernel 更好的全新 wireless stack 實作後，對 Linux 在無線網路上的支援與應用，將是一個重要的進展。由 Devicespace 所提交的新一代 wireless stack 包含的實作有（引述 kernelnewbies.org 原文）：

<blockquote>This wireless stack has many features, like a complete software MAC implementation, WEP, WPA, a "link-layer" bridging module, hostapd, QoS support to prioritize things like VoIP, 802.11g support, and full debug capabilities.</blockquote>

此外，另一個重要的改進則是：

<blockquote>Another feature of this stack is a completely new user interface. </blockquote>

這裡所指的「全新 user interface」指的是新的 user-space interface 實作。過去的 wireless stack 是採取 ioctl-based interface，新的 user-space interface 實作則是 netlink-based，並且能與舊有的 ioctl-based interface 相容。

另外，kernelnewbies.org 上也提到：

<blockquote>The disadvantage is the lack of drivers using this stack: the drivers that have been in the tree for a long time do not support this stack, and will need to be ported.</blockquote>

目前長久存在於 "tree"（kernel tree，kernel 原始碼目錄樹）裡的驅動程式並不支援新的 stack，必須要做 porting 的工作。不過，kernelnewbies.org 也提到，這個工作從技術角度來講並不困難，而且以現在的 kernel community 來說，這些工作不久的將來就會完成。
]]>
      
   </content>
</entry>
<entry>
   <title>Linux 2.6.22 新增 display class</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2007/12/linux_display_class.html" />
   <id>tag:www.jollen.org,2007:/blog//2.449</id>
   
   <published>2007-12-29T12:22:07Z</published>
   <updated>2008-02-19T21:38:02Z</updated>
   
   <summary>Linux 2.6.22 於 2007 年 7 月 8 日正式釋出，這個版本的 kernel 有一個令我感興趣的新功能。Linux 2.6.22 新增一個 class driver，稱為「display class」。顧名思義，這個新的 class driver 是用來管理與 &quot;display&quot; 有關 device driver。以下引用自 [include/linux/display.h]： 28 struct display_device; 29 30 /* This structure defines all the properties of a Display. */...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Linux Device Drivers &amp; Kernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[Linux 2.6.22 於 2007 年 7 月 8 日正式釋出，這個版本的 kernel 有一個令我感興趣的新功能。Linux 2.6.22 新增一個 class driver，稱為「display class」。顧名思義，這個新的 class driver 是用來管理與 "display" 有關 device driver。以下引用自 [<a href="http://lxr.linux.no/linux+v2.6.22/include/linux/display.h">include/linux/display.h</a>]：

<blockquote><pre>
28 struct display_device;
29
30 /* This structure defines all the properties of a Display. */
31 struct display_driver {
32         int  (*set_contrast)(struct display_device *, unsigned int);
33         int  (*get_contrast)(struct display_device *);
34         void (*suspend)(struct display_device *, pm_message_t state);
35         void (*resume)(struct display_device *);
36         int  (*probe)(struct display_device *, void *);
37         int  (*remove)(struct display_device *);
38         int  max_contrast;
39 };
40
41 struct display_device {
42         struct module *owner;                   /* Owner module */
43         struct display_driver *driver;
44         struct device *parent;                  /* This is the parent */
45         struct device *dev;                     /* This is this display device */
46         struct mutex lock;
47         void *priv_data;
48         char type[16];
49         char *name;
50         int idx;
51 };
52
53 extern struct display_device *display_device_register(struct display_driver *driver,
54                                         struct device *dev, void *devdata);
55 extern void display_device_unregister(struct display_device *dev);
</pre></blockquote>

在 Kconfig 選單中，可以找到一個 "Display device support" 的項目。根據 display class 的規劃，這個新的驅動程式界面除了支援 LCD 外，也會支援 CRT、TVout 以及其它的顯示界面。

2007 年下半年度因為工作特別忙碌，或者說，工作項目比較繁雜，無法將時間有效利用，便堆積了許多未讀的資料。正好利用 2007 結束前的幾個放假日，將這半年來累積的資料一次消化完畢，並將一些紀錄和大家分享。

<strong>延伸閱讀</strong>

2007.08.29: <a href="http://www.jollen.org/blog/2007/08/linux_frame_buffer_lecture.html">Linux frame buffer 驅動程式開發簡報下載</a>]]>
      
   </content>
</entry>
<entry>
   <title>簡報下載：Linux 驅動程式的 read/write 觀念解析</title>
   <link rel="alternate" type="text/html" href="https://www.jollen.org/blog/2007/12/linux_device_driver_read_write.html" />
   <id>tag:www.jollen.org,2007:/blog//2.448</id>
   
   <published>2007-12-21T08:15:25Z</published>
   <updated>2008-02-19T21:38:02Z</updated>
   
   <summary>12/19（三） 下午於 [OpenMoko] 的 [OpenLab] 發表了一場演說，時間是一個小時。這是一場有關 Linux 驅動程式的演講訓練活動，本次演講主要在解析 Linux 驅動程式的 read/write 程式碼框架（framework）與觀念解析。大綱如下： * read/write system call * vfs switch * user-space vs. kernel-space: I/O data * short discussion on wait queue: blocking I/O * cdata example 時間只有一個小時，因此在規劃簡報時，決定採取範例導向的方式做介紹。當天以一個 cdata 的範例做主軸，直接透過程式碼來做講解。在此提供簡報電子檔供參考 [linux-device-drivers-read-write]。...</summary>
   <author>
      <name>jollen</name>
      <uri>http://www.jollen.org</uri>
   </author>
         <category term="Linux Device Drivers &amp; Kernel" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="en" xml:base="https://www.jollen.org/blog/">
      <![CDATA[12/19（三） 下午於 [<a href="http://www.openmoko.org">OpenMoko</a>] 的 [<a href="http://wiki.openmoko.org/wiki/OpenLab_2nd_Event/zh_tw">OpenLab</a>] 發表了一場演說，時間是一個小時。這是一場有關 Linux 驅動程式的演講訓練活動，本次演講主要在解析 Linux 驅動程式的 read/write 程式碼框架（framework）與觀念解析。大綱如下：

* read/write system call
* vfs switch
* user-space vs. kernel-space: I/O data
* short discussion on wait queue: blocking I/O
* cdata example

時間只有一個小時，因此在規劃簡報時，決定採取範例導向的方式做介紹。當天以一個 cdata 的範例做主軸，直接透過程式碼來做講解。在此提供簡報電子檔供參考 [<a href="http://tw.jollen.org/slides/linux-device-drivers-read-write.pdf">linux-device-drivers-read-write</a>]。]]>
      
   </content>
</entry>

</feed>