<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>更夜 &#187; Android</title>
	<atom:link href="http://blog.aztaru.com/category/mobile/android/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.aztaru.com</link>
	<description>聞こえる？言葉が宙に舞う 叶えた時に出会う</description>
	<lastBuildDate>Thu, 12 Aug 2010 07:23:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>

   <image>
    <title>更夜</title>
    <url>http://1.gravatar.com/avatar/37c2b15c99950508697223c975d46f09?s=48&amp;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536</url>
    <link>http://blog.aztaru.com</link>
   </image>
		<item>
		<title>如何使用Acer Liquid S100 在 Eclispe上開發偵錯程式</title>
		<link>http://blog.aztaru.com/2010/08/12/539/</link>
		<comments>http://blog.aztaru.com/2010/08/12/539/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 07:21:12 +0000</pubDate>
		<dc:creator>lachesis</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[電腦]]></category>

		<guid isPermaLink="false">http://blog.aztaru.com/?p=539</guid>
		<description><![CDATA[感謝同事B被我逼迫一篇心得文&#8230; 如何使用Acer Liquid S100 在 Eclispe上開發偵錯程式]]></description>
			<content:encoded><![CDATA[<p>感謝同事B被我逼迫一篇心得文&#8230;</p>
<p><a href="http://www.dotblogs.com.tw/yuanchien/archive/2010/08/12/17156.aspx">如何使用Acer Liquid S100 在 Eclispe上開發偵錯程式</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aztaru.com/2010/08/12/539/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[筆記]讓Android上的browser用你寫的app開啟連結</title>
		<link>http://blog.aztaru.com/2010/07/07/%e7%ad%86%e8%a8%98%e8%ae%93android%e4%b8%8a%e7%9a%84browser%e7%94%a8%e4%bd%a0%e5%af%ab%e7%9a%84app%e9%96%8b%e5%95%93%e9%80%a3%e7%b5%90/</link>
		<comments>http://blog.aztaru.com/2010/07/07/%e7%ad%86%e8%a8%98%e8%ae%93android%e4%b8%8a%e7%9a%84browser%e7%94%a8%e4%bd%a0%e5%af%ab%e7%9a%84app%e9%96%8b%e5%95%93%e9%80%a3%e7%b5%90/#comments</comments>
		<pubDate>Tue, 06 Jul 2010 16:17:13 +0000</pubDate>
		<dc:creator>lachesis</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[電腦]]></category>

		<guid isPermaLink="false">http://blog.aztaru.com/?p=512</guid>
		<description><![CDATA[真是落落長的標題，不過因為沒有要仔細討論 intent filter 還是不要用什麼『極祕！Android的 intent filter萬萬強』這類聳動的 title 比較好，免得點進來一看大失所望。 當網站上有 market://xxx.ooo 這樣的連結出現，用 Android 瀏覽器點下去，就會自動打開 market下載應用程式，相當便利。如果連結是 tel:012345678 就會叫出撥號畫面，而且號碼已經帶好了，Google Map 則是 Geo:經緯度 這種形式。 我們自己開發的 Android 程式，要怎麼支援這種功能？比如說我的網站上提供這樣的連結 tarutaru://dance 希望點下去就會帶出我們的app，出現塔魯跳舞動畫.. 方法: 1. 請打開 AndroidManifest.xml 2. 找到塔魯跳舞的Activity 3. 請參考下面的寫法 這樣不管你是 tarutaru:dance 還是 tarutaru://dance 還是 tarutaru:///dance 都會叫出目標activity 如果 data 這行寫成: 這樣就只有 tarutaru://mysite/xxx 才會對應到你的跳舞Activity. 也可以利用這樣來把連結導到不同Activity。 比方說 tarutaru://dance/xxx, tarutaru://panic/ooo 就可以分別對應到不同兩個Activities。 其他更多細節就請自行參考官方文件啦age ヽ(￣∀￣)ノ]]></description>
			<content:encoded><![CDATA[<p>真是落落長的標題，不過因為沒有要仔細討論 intent filter 還是不要用什麼『極祕！Android的 intent filter萬萬強』這類聳動的 title 比較好，免得點進來一看大失所望。<br />
當網站上有 market://xxx.ooo 這樣的連結出現，用 Android 瀏覽器點下去，就會自動打開 market下載應用程式，相當便利。如果連結是 tel:012345678 就會叫出撥號畫面，而且號碼已經帶好了，Google Map 則是 Geo:經緯度 這種形式。<br />
我們自己開發的 Android 程式，要怎麼支援這種功能？比如說我的網站上提供這樣的連結 </p>
<p><code>tarutaru://dance</code></p>
<p>希望點下去就會帶出我們的app，出現塔魯跳舞動畫..</p>
<p>方法:<br />
1. 請打開 AndroidManifest.xml<br />
2. 找到塔魯跳舞的Activity<br />
3. 請參考下面的寫法</p>
<pre class="brush:xml">
<activity android:name=".TaruDanceActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data  android:scheme="tarutaru"></data>
</intent-filter>
</activity>
</pre>
<p>這樣不管你是 tarutaru:dance 還是 tarutaru://dance 還是 tarutaru:///dance 都會叫出目標activity<br />
如果 data 這行寫成:</p>
<pre class="brush:xml">
<data  android:host="mysite" android:scheme="tarutaru"></data>
</pre>
<p>這樣就只有 tarutaru://mysite/xxx 才會對應到你的跳舞Activity. 也可以利用這樣來把連結導到不同Activity。<br />
比方說 tarutaru://dance/xxx,  tarutaru://panic/ooo 就可以分別對應到不同兩個Activities。<br />
其他更多細節就請自行參考官方文件啦age ヽ(￣∀￣)ノ</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aztaru.com/2010/07/07/%e7%ad%86%e8%a8%98%e8%ae%93android%e4%b8%8a%e7%9a%84browser%e7%94%a8%e4%bd%a0%e5%af%ab%e7%9a%84app%e9%96%8b%e5%95%93%e9%80%a3%e7%b5%90/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[筆記]讓Android emulator連intranet</title>
		<link>http://blog.aztaru.com/2010/03/09/%e7%ad%86%e8%a8%98%e8%ae%93android-emulator%e9%80%a3intranet/</link>
		<comments>http://blog.aztaru.com/2010/03/09/%e7%ad%86%e8%a8%98%e8%ae%93android-emulator%e9%80%a3intranet/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 03:46:41 +0000</pubDate>
		<dc:creator>lachesis</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://blog.aztaru.com/?p=473</guid>
		<description><![CDATA[先說明，這算是某種特殊情況，一般Android開發者不見得會遇到同樣情形。總之在公司內部使用Android emu時，打開browser可以使用內部IP連上內部網站，但如果是使用domain name就會失敗，說是無法解析DN。試過使用官方說明的emulator下 -dns-server參數，但直接就在開模擬器時收到無法解析的錯誤了，當然browser一樣不認得內部網站的名稱。強者小Y同事建議改 hosts 檔看看，不過會得到 "failed to copy 'hosts' to '/system/etc/hosts': Read-only file system" 這樣的訊息。找到一篇blog文章提供的解法：Configure hosts File in Android。一開始嘗試是失敗的，後來小Y大人又給了些建議之後成功了。事實上，直接參考該文的做法對 Android 1.5, 1.6 的模擬器都是有效的，但偏偏我剛好正在用來測的是2.1。直接把作法寫在下面： [通用部分] 如果開了一個以上的模擬器的話請自行加adb參數 0a. 先adb pull /system/etc/hosts hosts抓回local來修改。 0b. 在原本的 127.0.0.1 localhost 加上新的行，寫入你需要的對應如 192.168.1.15 mytestsite，存檔。 1. adb remount (才不會發生Read-only file system錯誤) 2. adb push hosts /system/etc/hosts [2.0.1, 2.1 only] 這兩個版本會在這邊丟出錯誤訊息，分別為 failed to [...]]]></description>
			<content:encoded><![CDATA[<p>先說明，這算是某種特殊情況，一般Android開發者不見得會遇到同樣情形。總之在公司內部使用Android emu時，打開browser可以使用內部IP連上內部網站，但如果是使用domain name就會失敗，說是無法解析DN。試過使用官方說明的emulator下 -dns-server參數，但直接就在開模擬器時收到無法解析的錯誤了，當然browser一樣不認得內部網站的名稱。強者小Y同事建議改 hosts 檔看看，不過會得到 <code>"failed to copy 'hosts' to '/system/etc/hosts': Read-only file system"</code> 這樣的訊息。找到一篇blog文章提供的解法：<a href="http://sacoskun.blogspot.com/2009/06/configure-hosts-file-in-android.html">Configure hosts File in Android</a>。一開始嘗試是失敗的，後來小Y大人又給了些建議之後成功了。事實上，直接參考該文的做法對 Android 1.5, 1.6 的模擬器都是有效的，但偏偏我剛好正在用來測的是2.1。直接把作法寫在下面：</p>
<p>[通用部分]<br />
如果開了一個以上的模擬器的話請自行加adb參數<br />
0a. 先<code>adb pull /system/etc/hosts hosts</code>抓回local來修改。<br />
0b. 在原本的 127.0.0.1  localhost 加上新的行，寫入你需要的對應如 192.168.1.15  mytestsite，存檔。<br />
1. <code>adb remount</code>  (才不會發生Read-only file system錯誤)<br />
2. <code>adb push hosts /system/etc/hosts</code></p>
<p>[2.0.1, 2.1 only]<br />
這兩個版本會在這邊丟出錯誤訊息，分別為<br />
<code>failed to copy 'hosts' to '/system/etc/hosts': No space left on device</code><br />
<code>failed to copy 'hosts' to '/system/etc/hosts': Out of memory</code><br />
解決方法是，開啟模擬器時不要直接從 AVD Manager介面開，請下指令:<br />
<code>$ emulator -avd youravdname -partition-size 128</code><br />
接著再對這個模擬器使用上面的 hosts修改大法就不會出現錯誤了。</p>
<p>partition size的單位是MB，預設似乎是64。從adb shell 用 df 指令觀察的結果，/system 和 /data 都會被這個設定成這邊指定的值。而1.5, 1.6 的 image 因為剛好沒超過 64MB，還剩下一點空間，所以 hosts 還寫得進去，而 2.x 的 image 有 七萬多K，mount之後 /system 這個 partition 看起來就是全滿，剩下空間 0K。因此 hosts變肥後無法寫入，真的是因為partition爆了。事實上正常的手機確實也不需要留空間給user hack&#8230;模擬器還讓我們調參數已經很偷笑了，可惜AVD Manager 的 Start 沒地方可以設定 partition size。若有此需求的話只好麻煩一點手動下指定開emulator囉。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aztaru.com/2010/03/09/%e7%ad%86%e8%a8%98%e8%ae%93android-emulator%e9%80%a3intranet/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>[筆記]Android emulator常用指令與技巧</title>
		<link>http://blog.aztaru.com/2010/02/24/%e7%ad%86%e8%a8%98android-emulator%e5%b8%b8%e7%94%a8%e6%8c%87%e4%bb%a4%e8%88%87%e6%8a%80%e5%b7%a7/</link>
		<comments>http://blog.aztaru.com/2010/02/24/%e7%ad%86%e8%a8%98android-emulator%e5%b8%b8%e7%94%a8%e6%8c%87%e4%bb%a4%e8%88%87%e6%8a%80%e5%b7%a7/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 06:50:19 +0000</pubDate>
		<dc:creator>lachesis</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://blog.aztaru.com/?p=437</guid>
		<description><![CDATA[1. 切換 Layout為 Landscape or Protrait: Ctrl + F11 or Ctrl + F12 2. 模擬網路 ON/OFF: F8 3. 模擬有電話打進來的情形: 開兩個模擬器即可互打，電話號碼就是模擬器上的 5554, 5556 etc。 4. 把檔案放到 emu 的 sdcard 或系統目錄 adb push my_song.mp3 /sdcard/my_song.mp3 5. 從 emu 把檔案 copy出來 adb pull /data/data/com.example.android.notepad/databases/note_pad.db note_pad.db 6. 安裝 apk 到 emu 上 adb install c:/android-apk/myapp.apk 7. 進入 emu 的 [...]]]></description>
			<content:encoded><![CDATA[<p>1. 切換 Layout為 Landscape or Protrait:  <code>Ctrl + F11 or Ctrl + F12</code></p>
<p>2. 模擬網路 ON/OFF: <code> F8</code></p>
<p>3. 模擬有電話打進來的情形: 開兩個模擬器即可互打，電話號碼就是模擬器上的 5554, 5556 etc。</p>
<p>4. 把檔案放到 emu 的 sdcard 或系統目錄<br />
<code>adb push my_song.mp3 /sdcard/my_song.mp3</code></p>
<p>5. 從 emu 把檔案 copy出來<br />
<code>adb pull /data/data/com.example.android.notepad/databases/note_pad.db  note_pad.db</code></p>
<p>6. 安裝 apk 到 emu 上<br />
<code>adb install c:/android-apk/myapp.apk</code></p>
<p>7. 進入 emu 的 shell ，可執行 ls, rm 等動作，有root權<br />
<code>adb shell</code></p>
<p>8. 進入sqlite3 shell，先進入 shell之後<br />
<code># sqlite3 /data/data/com.example.android.notepad/databases/note_pad.db</code></p>
<p>以上指令如果在開啟了超過一個模擬器的狀態下，必須指定要針對哪個模擬器<br />
<code>adb -s emulator-5554 shell</code><br />
列出所有模擬器代號:<br />
<code>adb devices</code></p>
<p>附註: SQLite資料檔可以使用 push pull 拉到 emu外來使用輔助工具 <a href="http://sourceforge.net/projects/sqlitebrowser/" target="_blank">SQLite Database Browser</a> 來瀏覽或管理，對開發很有幫助。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aztaru.com/2010/02/24/%e7%ad%86%e8%a8%98android-emulator%e5%b8%b8%e7%94%a8%e6%8c%87%e4%bb%a4%e8%88%87%e6%8a%80%e5%b7%a7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[筆記] Android 使用httpclient對self-signed certificate網站進行SSL連線</title>
		<link>http://blog.aztaru.com/2009/12/11/%e7%ad%86%e8%a8%98-android-%e4%bd%bf%e7%94%a8httpclient%e5%b0%8dself-signed-certificate%e7%b6%b2%e7%ab%99%e9%80%b2%e8%a1%8cssl%e9%80%a3%e7%b7%9a/</link>
		<comments>http://blog.aztaru.com/2009/12/11/%e7%ad%86%e8%a8%98-android-%e4%bd%bf%e7%94%a8httpclient%e5%b0%8dself-signed-certificate%e7%b6%b2%e7%ab%99%e9%80%b2%e8%a1%8cssl%e9%80%a3%e7%b7%9a/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 05:45:42 +0000</pubDate>
		<dc:creator>lachesis</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://blog.aztaru.com/?p=404</guid>
		<description><![CDATA[Android SDK 在進行 https 連線時，對於自簽署的憑證是會拒絕連線的，會得到 Not trusted server certificate 的例外。如果使用 HttpsURLConnection 來連線，網路上可以找到一些破解方法，在此不多談。使用 apache httpclient 其實執行效率比較差一點，但是他最大的好處就是有內建的機制儲存cookie，並且也可以跟隨 server 作自動轉址。網路上資料比較多的是 httpclient 3.x版，Android 使用 httpclient 4 (而且還有些實作被拿掉) 唯一找到比較可信的來源是 apache httpclient 官方的 example。節錄重點段落如下： KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); FileInputStream instream = new FileInputStream(new File("my.keystore")); try { trustStore.load(instream, "nopassword".toCharArray()); } finally { instream.close(); } SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore); Scheme sch = [...]]]></description>
			<content:encoded><![CDATA[<p>Android SDK 在進行 https 連線時，對於自簽署的憑證是會拒絕連線的，會得到 Not trusted server certificate 的例外。如果使用 HttpsURLConnection 來連線，網路上可以找到一些破解方法，在此不多談。使用 apache httpclient 其實執行效率比較差一點，但是他最大的好處就是有內建的機制儲存cookie，並且也可以跟隨 server 作自動轉址。網路上資料比較多的是 httpclient 3.x版，Android 使用 httpclient 4 (而且還有些實作被拿掉) 唯一找到比較可信的來源是 apache httpclient 官方的 <a href="http://svn.apache.org/repos/asf/httpcomponents/httpclient/branches/4.0.x/httpclient/src/examples/org/apache/http/examples/client/ClientCustomSSL.java">example</a>。節錄重點段落如下：</p>
<pre class="brush:java">
        KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());
        FileInputStream instream = new FileInputStream(new File("my.keystore"));
        try {
            trustStore.load(instream, "nopassword".toCharArray());
        } finally {
            instream.close();
        }

        SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore);
        Scheme sch = new Scheme("https", socketFactory, 443);
        httpclient.getConnectionManager().getSchemeRegistry().register(sch);
</pre>
<p>直接把這段拿去用當然只有一個死字。本來看討論以為是要製造一個假的空憑證騙過 httpclient，從 Android 檔案系統有點微妙開始改來改去，一連串不同的例外或直接crash就不多談了。解決了檔案路徑，到底有沒有建立等等方面的問題之後才終於發現，假憑證是不行的&#8230; </p>
<p>1. 所以首先，開啟你PC或Mac上的瀏覽器連上目標網站，從憑證管理的地方把該網站的憑證匯出。每個瀏覽器做法都不同，請各位發揮正常工程師的水準做完這件事。以Firefox為例，找到site名後選匯出，多半是會得到一個檔名為 your_site_name.crt 的 X509(PEM) 憑證檔。為了之後使用方便，先把這檔案複製一份並把檔名改為 your_site_name.pem。</p>
<p>2. <strong>將這個憑證格式從 PEM 轉為 BKS 格式。</strong> 這是關鍵性的一步啊。</p>
<pre class="brush:java">KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());</pre>
<p>這行中的 getDefaultType 到底會 get到什麼 type 呢？答案：在 Android 中是 BKS。有 J2ME 經驗的人會想說，我看多半是跟 J2ME 一樣的 Sun JKS 格式吧，而且，我不要用 getDefaultType 就好了，我可以自己指定為 PEM, JKS格式啊。是的，你可以。只是你會得到錯誤訊息說 KeyStore JKS implementation not found。測了半天，看起來 Android 的 httpclient 只吃 BKS 就對了，其他都沒實作。</p>
<p>3. 那格式要怎麼轉？根據網路上找到的資料，可以使用 <a href="http://yellowcat1.free.fr/index_ktl.html">KeyTool IUI</a> 這個Java工具。打開後從介面選 create →　KeyStore，格式選 BKS，自己命名一下，要不要設密碼都可。接著選 import → Keystore&#8217;s entry → Trusted certificate → Regular certificate。 Source 的部分選 PEM 並選到剛剛瀏覽器得到的那個檔，Target 當然選 BKS 和剛 create 出來的檔。按OK之後會跳出Entries視窗，下方提示你enter new alias，隨便取個名字後ok連打，順利的話你應該就會有一個 your_keystore.bks 之類的檔案了。</p>
<p>4. 要把憑證檔放在 Android app 能讀到的地方，做法有兩種，放在 SD card 中，或直接放在 resources 中。</p>
<p>[方案一] 放在 SD card 的情形：首先模擬器要掛上SD card，這在 Eclipse 用 AVD 工具產生 avd 時就可以順便指定SD了。如果習慣用指令的話，也可以用如下指令產生 image 並 mount 上：</p>
<pre class = "brush:bash">
$ mksdcard 512M my_sdcard.so
$ emulator -sdcard ./my_sdcard.so
</pre>
<p>再來要把憑證檔 copy 到 SD card 中，目前只知道指令的做法：</p>
<pre class = "brush:bash">
$ adb push file_path/your_keystore.bks /sdcard
</pre>
<p>如果有顯示類似 ftp 傳輸速度之類的訊息應該就是成功了。<br />
接著把 android 程式碼中檔案部分改一改</p>
<pre class="brush:java">
        FileInputStream instream = new FileInputStream(new File("/sdcard/your_keystore.bks"));
        ...
            trustStore.load(instream, null);
</pre>
<p>如果沒設密碼，可以把 keystore load 的第二個密碼參數改成 null，有設的話當然就把 &#8220;nopassword&#8221; 改成你的密碼。<br />
基本上這樣應該就大功告成了。</p>
<p>[方案二] 再講講憑證放在 resources 的方法。首先把檔案複製到專案下的 res/raw/your_keystore.bks 。Eclipse 沒有錯誤的話就 ok，否則多半是你檔名不合規格，稍微改改。接著取用方法是把 android 程式碼改成：</p>
<pre class="brush:java">
InputStream instream = getResources().openRawResource(R.raw.your_keystore);
</pre>
<p>其它同SD card。</p>
<p>5. 還有一個地方要注意，就是 SSL port。</p>
<pre class="brush:java">
        Scheme sch = new Scheme("https", socketFactory, 443);
</pre>
<p>如果你要連的網站不是用 port 443，這邊請記得改掉。</p>
<p>6. 另外如果要使用檔案放在 resources 的做法，getResources() 應該只能在 Activity class 中執行，如果另外包裝連線類別的話請不要直接服用上面的程式碼，要自行從 context 抓到資源再傳過去。</p>
<p>看起來不太複雜的事情我其實還鬼打牆了滿久才解決，希望對各位有點幫助。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aztaru.com/2009/12/11/%e7%ad%86%e8%a8%98-android-%e4%bd%bf%e7%94%a8httpclient%e5%b0%8dself-signed-certificate%e7%b6%b2%e7%ab%99%e9%80%b2%e8%a1%8cssl%e9%80%a3%e7%b7%9a/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[筆記]Android 的 Activity Lifecycle</title>
		<link>http://blog.aztaru.com/2009/12/10/%e7%ad%86%e8%a8%98android-%e7%9a%84-activity-lifecycle/</link>
		<comments>http://blog.aztaru.com/2009/12/10/%e7%ad%86%e8%a8%98android-%e7%9a%84-activity-lifecycle/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 03:19:25 +0000</pubDate>
		<dc:creator>lachesis</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://blog.aztaru.com/?p=372</guid>
		<description><![CDATA[Activity Lifecycle實驗：1 = Root Activity， 2 = Sub Activity started by 1 Scenario A 先測單一Activity時，程式啟動，進入主畫面 onCreate 1 onStart 1 onResume 1 按 BACK，螢幕跑回桌面 onPause 1 onStop 1 onDestroy 1 選程式icon再進入主畫面 onCreate 1 onStart 1 onResume 1 結論：在 Root 按 BACK 等於結束程式。 Scenario B 程式啟動進入主畫面 onCreate 1 onStart 1 onResume 1 按 HOME，螢幕跑回桌面 onSaveInstanceState 1 onPause [...]]]></description>
			<content:encoded><![CDATA[<p>Activity Lifecycle實驗：1 = Root Activity， 2 = Sub Activity started by 1</p>
<p><strong>Scenario A</strong></p>
<ol>
<li>先測單一Activity時，程式啟動，進入主畫面<br />
onCreate 1<br />
onStart 1<br />
onResume 1</li>
<li>按 BACK，螢幕跑回桌面<br />
onPause 1<br />
onStop 1<br />
onDestroy 1</li>
<li>選程式icon再進入主畫面<br />
onCreate 1<br />
onStart 1<br />
onResume 1</li>
</ol>
<p>結論：在 Root 按 BACK 等於結束程式。</p>
<p><strong>Scenario B</strong></p>
<ol>
<li>程式啟動進入主畫面<br />
onCreate 1<br />
onStart 1<br />
onResume 1</li>
<li>按 HOME，螢幕跑回桌面<br />
onSaveInstanceState 1<br />
onPause 1<br />
onStop 1</li>
<li>選程式icon再進入主畫面<br />
onRestart 1<br />
onStart 1<br />
onResume 1</li>
</ol>
<p>結論：在 Root 按 HOME 只是把程式放到背景，重新進入後不會執行 onCreate。</p>
<p><strong>Scenario C</strong></p>
<ol>
<li>程式啟動進入主畫面<br />
onCreate 1<br />
onStart 1<br />
onResume 1</li>
<li>按下按鈕，進入畫面2<br />
onSaveInstanceState 1<br />
onPause 1<br />
onCreate 2<br />
onStart 2<br />
onResume 2<br />
onStop 1</li>
<li>按BACK 返回主畫面<br />
onPause 2<br />
onRestart 1<br />
onStart 1<br />
onResume 1<br />
onStop 2<br />
onDestroy 2</li>
</ol>
<p>結論：在 Sub 按 BACK，Sub活動會消滅，另外看起來Android滿仔細的，停掉2重開1的流程是有巧妙的安排。</p>
<p><strong>Scenario D</strong></p>
<ol>
<li>程式啟動進入主畫面<br />
onCreate 1<br />
onStart 1<br />
onResume 1</li>
<li>按下按鈕，進入畫面2<br />
onSaveInstanceState 1<br />
onPause 1<br />
onCreate 2<br />
onStart 2<br />
onResume 2<br />
onStop 1</li>
<li>在畫面2，按HOME 返回桌面<br />
onSaveInstanceState 2<br />
onPause 2<br />
onStop 2</li>
<li>選程式icon，會直接進入畫面2<br />
onRestart 2<br />
onStart 2<br />
onResume 2
</li>
</ol>
<p>結論：在 Sub活動按 HOME 會暫停Sub (Root早就暫停了)，再回到程式是直接 Reactivate Sub畫面</p>
<p><strong>Scenario E</strong></p>
<ol>
<li>補充：在 textbox 打字到一半，按POWER鎖住螢幕<br />
onSaveInstanceState x<br />
onPause x</li>
<li>解除鎖定，會直接回app畫面，並且之前的輸入到一半的文字不會消失<br />
onResume x</li>
</ol>
<p><strong>Scenario F</strong></p>
<ol>
<li>補充：打字到一半，有電話進來<br />
onSaveInstanceState x<br />
onPause x<br />
onStop x</li>
<li>掛斷電話，畫面及游標回到原來的 textbox，輸入的文字還在<br />
onRestart x<br />
onStart x<br />
onResume x</li>
</ol>
<p>這裡面有個更讓我在意的事情，就是我在兩個Activity都有overwrite onRestoreInstanceState，並加入message，但是從來都沒有被呼叫過。官方手冊在提到 onSaveInstance 的時候，也是說明這儲存的bundle是讓你在下次onCreate時使用，並沒有提到 onRestoreInstanceState。不論如何，這兩個method並不是在 Lifecycle 中必定會呼叫的程序，不要依賴它們來儲存使用者輸入到一半的資料，照設計目的看來比較像是記住上一次是看到第二頁之類的功能。之後如果有讀到相關說明再補充上來。</p>
<p>上面的實驗雖然 onPause 和 onStop 總是在一起，但根據手冊，Pause 狀態跟 Stop狀態確實是不同。Pause狀態下，使用者不能與這個活動互動，但是仍然看的見它。也就是說如果你產生了一個透明的或不占到全螢幕的子活動，則主活動有可能只會 Pause，而不會 Stop。而Pause狀態對系統來說仍然是alive，只有系統資源真的太低時才會kill它，而Stop的活動相對來說很有機會被殺掉。(不知道 Alert Dialog 與 Parent是不是這種關係)</p>
<p>關於保存狀態或傳遞資料方面，官方SDK手冊強調，如果需要回傳結果給主活動，<strong>不要</strong>在 onDestroy 加入 setResult function! ，之前被 google 到的某論壇文章騙了，說可以在 onDestroy setResult，怒。根據手冊說，想要做保存資料，例如 user 輸入之類的事情應該放在 onPause，onDestroy 應該只做釋放資源之類的動作，因為 oPause是唯一一個保證會在系統 kill process 之前呼叫並且等待其return的function。實際上測試的結果，確實在 onDestroy 試圖 setResult 是沒有用的，intent 應該是會隨著此sub Activity 被消滅，onActivityResult 的地方會得到 null intent。一般來說返回鍵表示要放棄現在的動作返回，不保留狀態還算合理，但看了一下Android的通訊錄app，按下返回鍵時，其實還是當作 submit 立刻儲存了打到一半的資料，這可能是為了防止編輯到一半電話進來，資料全被清空的滿腔怒火。另外已經在背景的Activity是有機會被kill process的。萬一發生了這事情，在kill process之前會先 onSaveInstanceState(Bundle)，下次再 onCreate(Budle) 時就可以使用這 bundle 的動態暫存資料。</p>
<p>總之，儲存永久性資料的動作可以在 onPause做，onDestroy只能做資源回收，比如 connection close，之後有其他心得會再補充資料。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aztaru.com/2009/12/10/%e7%ad%86%e8%a8%98android-%e7%9a%84-activity-lifecycle/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[筆記]Android 多國語言</title>
		<link>http://blog.aztaru.com/2009/12/09/%e7%ad%86%e8%a8%98android-%e5%a4%9a%e5%9c%8b%e8%aa%9e%e8%a8%80/</link>
		<comments>http://blog.aztaru.com/2009/12/09/%e7%ad%86%e8%a8%98android-%e5%a4%9a%e5%9c%8b%e8%aa%9e%e8%a8%80/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 03:43:37 +0000</pubDate>
		<dc:creator>lachesis</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://blog.aztaru.com/?p=362</guid>
		<description><![CDATA[官網的Hello, L10N，還有 ADT plug-in 都叫大家使用兩個字母的語言代碼，例如 zh, en, ja 來分字串語系檔。圖片則規定要使用語系+地區，例如 zh-rTW。這時候最大的疑惑立刻浮上心頭，那簡體跟繁體字串要怎麼辦（〃*`Д´）。網路上沒有搜到甚麼資料，乾脆自己惡搞看看，直接把/res/values-zh/strings.xml 複製修改成兩份，變成 /res/values-zh-rTW/strings.xml 跟 /res/values-zh-rTW/strings.xml 內容當然分別是簡體跟繁體的。喔! 沒有編譯錯誤，很好。接著開始切換模擬器語系&#8230;おおお！還真的會分簡體跟繁體啊！教學幹嘛不寫啊！（｀・ω・´）總之姊妹們，有需要的話語系分下去就對了（*´∀｀*） ps. 版本的話，SDK 1.1的模擬器只有德文和英文懶的測，SDK 1.5 和 SDK 2.01 是測試OK的，推論應該是只要手機有支援相關語系都可以。]]></description>
			<content:encoded><![CDATA[<p>官網的Hello, L10N，還有 ADT plug-in 都叫大家使用兩個字母的語言代碼，例如 zh, en, ja 來分字串語系檔。圖片則規定要使用語系+地區，例如 zh-rTW。這時候最大的疑惑立刻浮上心頭，那簡體跟繁體字串要怎麼辦（〃*`Д´）。網路上沒有搜到甚麼資料，乾脆自己惡搞看看，直接把/res/values-zh/strings.xml 複製修改成兩份，變成 /res/values-zh-rTW/strings.xml 跟 /res/values-zh-rTW/strings.xml 內容當然分別是簡體跟繁體的。喔! 沒有編譯錯誤，很好。接著開始切換模擬器語系&#8230;おおお！還真的會分簡體跟繁體啊！教學幹嘛不寫啊！（｀・ω・´）總之姊妹們，有需要的話語系分下去就對了（*´∀｀*）<br />
ps. 版本的話，SDK 1.1的模擬器只有德文和英文懶的測，SDK 1.5 和 SDK 2.01 是測試OK的，推論應該是只要手機有支援相關語系都可以。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aztaru.com/2009/12/09/%e7%ad%86%e8%a8%98android-%e5%a4%9a%e5%9c%8b%e8%aa%9e%e8%a8%80/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[筆記]Android的返回鍵</title>
		<link>http://blog.aztaru.com/2009/12/08/%e7%ad%86%e8%a8%98android%e7%9a%84%e8%bf%94%e5%9b%9e%e9%8d%b5/</link>
		<comments>http://blog.aztaru.com/2009/12/08/%e7%ad%86%e8%a8%98android%e7%9a%84%e8%bf%94%e5%9b%9e%e9%8d%b5/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 05:41:29 +0000</pubDate>
		<dc:creator>lachesis</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://blog.aztaru.com/?p=349</guid>
		<description><![CDATA[從Main Activity 使用 startActivity 或 startActivityForResult 產生並切換到 sub Activity之後，如果按下返回鍵，會發生甚麼事? 本來很擔心整個sub Activity只是看不見，但仍然蹲在角落畫圈圈，隨著Main Activity一次一次的再度 startActivity 而產生撿不完的屍體。Google之後再測試一下發現好家在，按下返回鍵系統就會呼叫 onDestroy()，結束掉這個 sub Activity。上以前被寫得很爛的J2ME Midlet 嚇過，真的是很害怕屍體山啊，為了愛護大自然大家一定要做好資源回收喔。∑（´д｀*） 關於 BACK key，HOME key，官方Dev Guide 的 Application Fundamentals 的 Activities and Tasks 這個 session 講得滿清楚的。你的整個 App 是一個TASK，root Activity 和 sub Activity，包括中間呼叫系統地圖在內，跑在同一個 TASK process，一個 TASK 就是一個 STACK。主活動也就是程式載入的第一個活動一定是在堆疊底端，它產生子活動時，子活動就被加入堆疊。按下BACK key 時，子活動就從堆疊中被拿出來(丟掉)。子活動的子活動當然也是相同。所以BACK key做的事情就是把現在這個活動拿去丟:P (各位兄弟姊妹們應該沒有忘記STACK是LIFO吧) 而HOME key又會做甚麼? 他不丟東西，他會把這整個TASK / STACK 放到背景。等你在別人家玩一圈，再度按下app [...]]]></description>
			<content:encoded><![CDATA[<p>從Main Activity 使用 startActivity 或 startActivityForResult 產生並切換到 sub Activity之後，如果按下返回鍵，會發生甚麼事? 本來很擔心整個sub Activity只是看不見，但仍然蹲在角落畫圈圈，隨著Main Activity一次一次的再度  startActivity 而產生撿不完的屍體。Google之後再測試一下發現好家在，按下返回鍵系統就會呼叫 onDestroy()，結束掉這個 sub Activity。上以前被寫得很爛的J2ME Midlet 嚇過，真的是很害怕屍體山啊，為了愛護大自然大家一定要做好資源回收喔。∑（´д｀*）</p>
<p>關於 BACK key，HOME key，官方Dev Guide 的 <a href="http://developer.android.com/intl/zh-TW/guide/topics/fundamentals.html#acttask">Application Fundamentals 的 Activities and Tasks</a> 這個 session 講得滿清楚的。你的整個 App 是一個TASK，root Activity 和 sub Activity，包括中間呼叫系統地圖在內，跑在同一個 TASK process，一個 TASK 就是一個 STACK。主活動也就是程式載入的第一個活動一定是在堆疊底端，它產生子活動時，子活動就被加入堆疊。按下BACK key 時，子活動就從堆疊中被拿出來(丟掉)。子活動的子活動當然也是相同。所以BACK key做的事情就是把現在這個活動拿去丟:P (各位兄弟姊妹們應該沒有忘記STACK是LIFO吧) 而HOME key又會做甚麼? 他不丟東西，他會把這整個TASK / STACK 放到背景。等你在別人家玩一圈，再度按下app icon，背景的那整包 STACK / TASK 就被放回前景。如果剛在是從某個子活動按下HOME，現在應該還是看到剛才的那個子活動才對。BACK key則還是負責殺掉目前的子活動，並不會回到你剛玩過的其他app。謎之聲：不知道為什麼忽然開始覺得好險沒有Forward Key。另外補充一點，就是如果離開去外面玩太久，系統會把TASK中的子活動都殺光，只剩下主活動，下次切回來時看起來就好像新開的應用程式一樣。</p>
<p>上面說的是系統預設行為，TASK 和 Activity 的行為是可以由一些參數設定加以改變的，這邊就不深入討論了。有興趣可以繼續看完上面給的連結。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aztaru.com/2009/12/08/%e7%ad%86%e8%a8%98android%e7%9a%84%e8%bf%94%e5%9b%9e%e9%8d%b5/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
