2012年12月2日 星期日

[Android] Touch events trigger order

  • ViewGroup#onInterceptorTouchEvent()
  • View#onTouchEvent()
  • View#onTouch()


目前了解

以上 method 回傳 true 則表示會處理 event,該 event 則不會再被 dispatcher

若是回傳 false,則表示不會處理,因此也不會再接收到後續 event (這邊有點不確定!)


* Reference
- onInterceptTouchEvent和onTouchEvent调用时序 - ddna的专栏 - 博客频道 - CSDN.NET
- ViewGroup | Android Developers
- MotionEvent事件在onInterceptTouchEvent()、onTouchEvent()中的传递顺序 | 第三极 | 移动开发者
- onTouchEvent 、onInterceptTouchEvent的顺序~
- 两分钟彻底让你明白Android中onInterceptTouchEvent与onTouchEvent(图文)! - Android_Tutor的专栏 - 博客频道 - CSDN.NET

Dynamic Random Access Memory (DRAM)

動態隨機存取記憶體 (Dynamic Random Access Memory,DRAM)
  • 是一種半導體記憶體,主要的作用原理是利用電容內儲存電荷的多寡來代表一個二進制位元(bit)是 1 還是 0。
  • 由於在現實中電容會有漏電的現象,導致電位差不足而使記憶消失,因此除非電容經常周期性地充電,否則無法確保記憶長存。
  • 與大部分的隨機存取記憶體(RAM)一樣,由於存在 DRAM 中的資料會在電力切斷以後很快消失,因此它屬於一種揮發性記憶體(volatile memory)設備。
  • 由於這種需要定時重新整理的特性,因此被稱為「動態」記憶體。


靜態記憶體 (SRAM)
  • 相對來說只要存入資料後,縱使不重新整理也不會遺失記憶。

  • 與 SRAM 相比,DRAM 的優勢在於結構簡單
    • 每一個位元的資料都只需一個電容跟一個電晶體來處理,而 SRAM 上一個位元通常需要六個電晶體。
    • 正因這緣故,DRAM 擁有非常高的密度,單位體積的容量較高因此成本較低。
  • 但相反的,DRAM也有存取速度較慢,耗電量較大的缺點。


Android relative API


* Reference
- 動態隨機存取記憶體 - 维基百科,自由的百科全书
- ActivityManager.MemoryInfo | Android Developers

[Android] Android NDK (Native Development Kit)

Android NDK (Native Development Kit)
能透過 java 直接呼叫 c 程式所做功能的工具。

Android SDK 
是 google 提供 developers 開發的 Java-based API,app 會被執行在 Dalvik virtual machine,類似於 JVM,app 可以在任何裝置上執行,不受硬體 CPU 影響。

這樣 app 的執行速度相對於直接使用 C 來控制慢,尤其是影音方面的運算。所以有了 NDK,透過 NDK 可以直接操作底層功能加快執行速度。

因此形成主程式使用 Java,有速度上要求部份的如驅動程式、繪圖功能則使用 C;Android system 可分為 Java - JNI - C,透過 JNI(java native interface) 間接 Java 與 C


* Reference
- 49歐姆 整機教學: android HAL 層與 android NDK
- 49歐姆 整機教學: android HAL 硬體抽象層
- 49歐姆 整機教學
- What is the NDK?

[AndroidTool] Could not open: C:\Users – Android could not start Emulator

Error Message

PANIC: Could not open: C:\Users – Android could not start Emulator


Solution

因為 emulator 預設被建立在 C:\Users\.....\.android/avd

所以若該路徑下找不到會無法啟動



* Reference
- PANIC: Could not open: C:Users – Android could not start Emulator | Share ChiWai/Share 智慧/智慧分享 – 技術分享/Tech Blog
- 李辉的博客 » android模拟器无法启动的解决

2012年12月1日 星期六

[AndroidLayout] getWidth() and getHeight() return 0

getWidth()
取得 view 的實際所佔寬度。

getMeasuredWidth()
view 在 parent 估計會佔的寬度,是最近一次在 measure() 中計算的值。

Solution1
final TextView tv = (TextView)findViewById(R.id.image_test);
ViewTreeObserver vto = tv.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

    @Override
    public void onGlobalLayout() {
        LayerDrawable ld = (LayerDrawable)tv.getBackground();
        ld.setLayerInset(1, 0, tv.getHeight() / 2, 0, 0);
        ViewTreeObserver obs = tv.getViewTreeObserver();
        obs.removeGlobalOnLayoutListener(this);
    }
});

Solution2
[AndroidLayout] getWidth() and getHeight()


* Reference
- getWidth和getMeasuredWidth的正解 - rui313的专栏 - 博客频道 - CSDN.NET
- android - How do you to retrieve dimensions of a view? Getheight() and Getwidth() always return zero - Stack Overflow
- Android初级教程_获取Android控件的宽和高 **

練就堅強的心 只是一種習慣


<<練就堅強的心 只是一種習慣>>  植西聰

不是真的因為自己太差 卻因為自我要求 外在環境

而自我否定 陷入負面情緒

這本要說的便是如何擺脫負面思考 重建自信


  1. 學習放手 拋開憤怒與嫌惡記憶
  2. 放寬標準 不必急速當下解決
  3. 適時抒發 改變心情 另覓方法


但這本在似乎還沒上市XD

就像是 祕密 這本書 我相信信念所能帶來的影響

或許也是這樣 覺得很難去改變 所以始終沒有動力去了解與閱讀

正向的想法與樂觀 應該能帶來不同的思考

性格很難改變 就...一點點的養成習慣來修正吧!

嗯....



* Reference
- 【經理人月刊 3月號/2012 第88期】高績效主管的8堂必修課

[DesignPattern] Difference between Builder Pattern and Factory Pattern

Design Patterns 是更高階 (抽象) 的 patterns


Builder Pattern
  • 組裝場
  • for composite object


Factory Pattern
  • Create single object




[JPA] transaction annotation values

TRANSACTION
  • support: 依附 transaction 無則沒 transaction
  • required: 裡頭行為綁在一起, 一起成功/失敗
  • never: 行為分開獨立 有些成功 有些失敗

[Web] http request parameter

In http request
  • 沒有該 element: get null.
  • 有該 element 但沒有帶 value: get ""

[Android] adb memory command

adb shell dumpsys meminfo {packageName}

查看 {packageName} 的 memory 訊息

[AndroidLayout] status selector

<item android:state_selected="true" android:state_pressed="true"></item>

selector status 的判斷 是在行為發生時生效

若想維持該狀態下的設定

可藉 APIs

button.setEnabled(true);
button.setSelected(false);

設定 widgets 的狀態 以固定 selector 中的對應結果

[AndroidNet] IllegalArgumentException when http request

Error Message

java.lang.IllegalArgumentException: Illegal character in fragment at index 77: http://host/~!@#@#@$^%^%&2
at java.net.URI.create(URI.java:769)
at org.apache.http.client.methods.HttpPost.(HttpPost.java:79)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1081)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:574)
at java.lang.Thread.run(Thread.java:1020)


Solution

request url + URLEncoder.encode(parameters)

2012年10月21日 星期日

[Reading] 心願清單 - chapter 1

以為還有時間慢慢說 瞬間卻再沒有機會

僥倖的把以為的不重要寄託在之後

能有下一次機會 是幸運是緣份

[Android] Avoid Memory leak

  • 當記憶體不足,system 就必須暫停你的 application,執行 garbage collection,通常暫停的時間很短暫讓 user 感覺不到,但若是在移動 scroll 或是遊戲戰鬥中,可以感覺到效能和回應的下降。
  • "leak" meaning you keep a reference to it thus preventing the GC from collecting it.
  • 在 Android 中,一個 Process 只能使用 16M 記憶體(模擬器為 8M?),若是超過變會引發 Out-of-Memory exception(OOM)。


容易占據大量記憶體的行為:
  • view layout
  • drawing method of a view
  • the logic code of a game


Context Leak
keeping a long-lived reference to a Context.

Context 最常用來載入和存取資源,在 app 中一般會有 Activity and Application 兩種 Context
  • setContentView(new TextView(this));
  • 表示 the entire View hierarchy and all its resources reference 到這個 activity,有可能會使得此 Context leak。

可用以下兩種方式避免 Context leak:
  • 不要將 Context 使用在自己的 scope 之外。
  • 使用 Application context。
    • This context will live as long as your application is alive and does not depend on the activities life cycle. 
    • If you plan on keeping long-lived objects that need a context, remember the application object. You can obtain it easily by calling Context.getApplicationContext() orActivity.getApplication().

In summary, to avoid context-related memory leaks, remember the following:
  • Do not keep long-lived references to a context-activity (a reference to an activity should have the same life cycle as the activity itself)
  • Try using the context-application instead of a context-activity
  • Avoid non-static inner classes in an activity if you don't control their life cycle, use a static inner class and make a weak reference to the activity inside. 
    • The solution to this issue is to use a static inner class with a WeakReference to the outer class, as done in ViewRoot and its W inner class for instance
  • A garbage collector is not an insurance against memory leaks


Bitmap Leak
  • 避免 Bitmap Leak 就必須使用 recycle 機制,適時的將不需要顯示的 Bitmap 物件回收。
  • 但還有另一種狀況: 產生 Bitmap 的時候,明明還有許多記憶體,卻發生了 OOM。
    • 假設現在產生了一個 13MB 的 Int array 物件,在使用完之後立即 recycle,照理說會空出 13MB 的空間,這時候繼續產生一個 10MB 的 Int array 物件不會有任何問題,反而生成一個 4MB 的 Bitmap 卻跳出OOM。
  • 在 Android 中,一個進程的記憶體可以由 2 個部門組成:Java 使用記憶體,C使用記憶體
    • 這兩個記憶體的和必需小於 16 MB,不然就會出現 OOM。
    • 而分配給 Java 使用的記憶體,縱使這塊記憶體被釋放了,也還是只能給Java的使用,所以就算釋放 Java 佔用的佔用了一個大塊記憶體,C 能使用的記憶體 = 16M - Java 某一瞬間占用的最大記憶體。 
    • 而 Bitmap 的生成是路程經過過程 malloc 進行記憶體分配的,佔用的是 C 的記憶體,這個也就說明了,上面所說的的 4MB Bitmap無法生成的原因,因為在 13MB 被Java用過後,剩下 C 能用的只有 3M 了。

補救方式
  • 使用 BitmapFactory.decodeStream() 產生Bitmap。
    • 儘量不要使用 setImageBitmap,setImageResource 或 BitmapFactory.decodeResource 來設置一張大圖,因為這些函數在完成 decode 後,最終都是通過 java 層的 createBitmap 來完成的,需要消耗更多記憶體。
    • 因此,改用先通過 BitmapFactory.decodeStream 方法,創建出一個 bitmap,再將其設為 ImageView 的 source,decodeStream 最大的秘密在於其直接調用 JNI >> nativeDecodeAsset() 來完成 decode,
    • 無需再使用 java 層的 createBitmap,從而節省了 java 層的空間。
    • decodeStream 直接拿的圖片來讀取位元組碼了,不會根據機器的各種解析度來自動適應,使用了 decodeStream 之後,需要在 hdpi 和 mdpi,ldpi 中配置相應的圖片資源,否則在不同解析度機器上都是同樣大小(圖元點數量),顯示出來的大小就不對了。
  • 設定圖片的 Config 參數,可以跟有效減少載入的記憶體。
    • BitmapFactory.Options inSampleSize:值越大解析度越小,佔用memory也越小。
  • 在 onPause/onStop/onDestory 時, 將沒用到的 Bitmap release(用recyle())
BitmapFactory.Options opts = new BitmapFactory.Options();
// Options 只保存图片尺寸大小,不保存图片到内存
// 缩放的比例,缩放是很难按准备的比例进行缩放的,其值表明缩放的倍数
// SDK 中建议其值是2的指数值,值越大会导致图片不清晰
opts.inSampleSize = 4;
Bitmap bmp = BitmapFactory.decodeResource(getResources(), mImageIds[position],opts);                              
 ...               
//回收
bmp.recycle();


* Reference
- Tracking Memory Allocations | Android Developers
- Avoiding memory leaks | Android Developers Blog
- (转)内存溢出的解决办法 Android - 攀升·Uranus - C++博客
- Android開發——解決載入大圖片時記憶體溢出的問題 @ 資訊園 :: 痞客邦 PIXNET ::
- GiveMePasS’s Android惡補筆記: 如何改善Bitmap所帶來的Out of Memory(OOM)問題
- Re: [問題] Bitmap OutOfMemory 永遠的痛 - 看板 AndroidDev - 批踢踢實業坊
- Andorid , Object-C and Java Programming Learning: [Android]Android Out Of Memory(OOM) 的詳細研究

2012年10月20日 星期六

[Android] Dialog error - Unable to add window token null is not for an application

Error Message

Unable to add window token null is not for an application


Occurred when 

使用 getApplication() 去建立 dialog,必須使用 Activity (extends Context) 才行。


* Reference
- AlertDialog显示错误 Unable to add window token null is not for an application - Trinea @Java @Android 体验 技术 营销 - ITeye技术网站

[javascript] Different result of String.length for browsers

javascript 中使用 String.length
  • chrome, FF
    • 換行視為 \n => 1 字元
  • IE
    • 換行視為 \r\n => 2 字元

Solution
在 IE 中,先將 \r\n replace 為 \n 再取得 length。

2012年10月16日 星期二

[Android] layout qualifier

ex: In API 3.1

layout resource...
  • only in layout-w720dp -> crash
  • only in layout-xlarge -> ok (3.2 also ok)

cannot use layout-xlarge-w720dp!

[JPA] @Embedable and @Column

C extends P

If C and P are Embedable...

得 Override getA() method

否則 A 不會 mapping 到 等於沒有寫 @Column 的意思


[Spring] URL decode

Springframework will do URL decoder.


2012年10月11日 星期四

[Hardware] RAM, SSD

RAM Disk
  • 通常是利用軟體的方式,將動態記憶體(Dynamic Random Access Memory,DRAM)模擬成硬碟裝置的一種技術。
  • 斷電時資料會隨之清空、流失,讀寫速度爆快,壽命又很長的存放空間。
    • 資料存放位置就是記憶體,所以斷電後記憶體內的資料就會消失,因此並不算是個穩定的存取空間,只能把它當作是一個超高速暫存空間利用。
  • 不像傳統硬碟採用馬達與磁片等機械裝置,而是靠電子訊號傳輸,因此在分類上也算是固態硬碟。
  • 不像NADA Flash般有寫入次數限制。再加上依靠電子訊號傳輸,沒有機械損耗疑慮,因此壽命比起傳統硬碟或SSD都來得長了許多。只要記憶體不過分加壓超頻,再加上記憶體大多是終身保固的情況下,要說RAM Disk永遠不會壞也是可以的。
  • 效能會受到軟體、記憶體時脈、晶片組的記憶體通道數而有所不同。
  • 扣除軟體差異,記憶體時脈越高則效能越好,而四通道平台又比雙通道來得快一些。


HDD (Hard Disk Drive)
  • 由馬達、磁片與讀寫頭等機械裝置所構成的,因此會有磨損問題


SSD (Solid State Disk)
  • 從前還沒發明積體電路、電晶體的時候,電腦是由真空管所組成,電子在傳遞時,並不是百分之百地經過固體傳導,而是會流過一段真空的路徑。
  • 現今的電晶體其實也就是將矽做成能讓電子在裡頭流動的、交錯複雜的晶體管線,而成份全部都由固體所構成,因此叫做「固態硬碟」也十分名符其實。
  • 與傳統硬碟的要差別在於裡頭完全沒有機械構造,不會有吵雜的馬達運轉聲與磁頭讀取聲,因此有耐震、安靜等特性,而且對比傳統硬碟需要較高電流以啟動馬達運轉,SSD就節能多了。

記憶體顆粒
  • 如果你打開過固態硬碟,可以發現裡面沒馬達、沒碟片、也沒磁頭,就只有一顆一顆像是電腦上插著的記憶體模組般的黑色顆粒一樣,這種晶片稱為NAND Flash。
  • SSD其實它就跟他的近親「USB隨身碟」一樣,是將資料儲存在快閃記憶體中,不過這些顆粒並不像 RAM 一樣,斷電或是重新開機以後,資料就會消失,而是會將內容資料儲存起來。
  • 視顆粒差異,有著幾萬次到十萬次資料寫入限制。

NAND又區分為兩種儲存形式:
  • SLC
    • 是單層式儲存,一個單元只能儲存一個位元,可以表示0及1。
    • 壽命較長,約10萬次左右
    • 存取速度也比 MLC 快
    • 雖然SLC在性能上比MLC優良不少,不過受限於成本過高,常常都是mlc產品的兩倍價格以上。
  • MLC
    • 可以一次儲存2個位元,分別可表示為00、01、10、11,因此儲存密度比SLC高,當然成本也比較低。
    • 壽命較短,只有一萬次的存取次數。
    • 目前由於MLC製成精進,也應用了多通道技術,讓MLC的讀寫速度得以跟上SLC,市場主流產品多是以MLC為主,SSD的價格也不像以往那樣高不可攀了。

控制晶片是SSD的大腦
  • 除了記憶體顆粒以外,SSD中最重要的零組件是控制晶片,控制晶片決定了一顆SSD支援的功能,在控制晶片中主要負責三項工作,分別是:
    • 自動錯誤校正
    • 故障區塊管理
    • 平均抹寫儲存區塊。
  • 目前主要的控制晶片廠牌有Sandforce、Marvell、Samsung、JMicron等。

韌體好壞決定效能穩定性
  • 韌體是SSD效能的靈魂,雖然市售的SSD很多都是採用相同控制器,不過生產廠商調校韌體的功力卻大大影響了效能及穩定性。
  • 所以常常聽到玩家會為了有更好的效能而購買大廠牌的SSD,這也是因為雖然控制器廠商就那幾家,但通常大廠的韌體也寫得比較好,不僅可以修正一些影響速度的bug,也可以增加更多實用的功能,幫助SSD能取得更好的表現。
  • 此外,傳統硬碟買來以後,除非遇到重大缺失,不然其實不太需要更新韌體,不過SSD有沒有更新韌體,表現就會差很多喔。


* Reference
- 比 SSD 更快,RAM Disk 攻略:4種應用、4個實測、軟體效能大車拼
- SSD調教實戰(1):原理篇

2012年10月10日 星期三

[Android] ListView Tips

In order to avoid blending and make the rendering faster while scrolling/flinging, the ListView widget uses a ’scrolling cache’ mechanism.
  • ListView 背景預設為透明色,所以會看到 window 預設的背景色,深灰色 (#FF191919)
  • 為了滑動效能,the Android framework reuses the cache color hint.
  • 若 scrolling cache is true,那麼當 color hint is set,the framework 複製 ListView 中的每個 child 為 bimap 並且設該 hint value.
    • the framework copies each child of the list in a Bitmap filled with the hint value. ListView then blits these bitmaps directly on screen and because these bitmaps are known to be opaque, no blending is required. (?)
    • This mechanism consists on taking an opaque screenshot of all visible child Views (in other words, it draws the content of each itemview in a Bitmap) and directly draws those screenshots when necessary. 
  • 因為預設的 cache color hint is #191919,所以在滑動時會看到 item 的黑色背景。
    • The color used to make those screenshots opaque is the one given by the cache color hint.
    • If your ListView turns opaque (black for instance) when scrolling that because you need to set the cache color hint to the actual color of your ListView background.
若不想看到這黑色(cache color hint)背景(也就是關閉此優化方式),可以在 xml 設置 android:cacheColorHint="#00000000" 即可。


CharArrayBuffer
Cursor#getString() 每次呼叫都會建立 String objects,而且這些 objects 當 user scroll ListView 時就會被回收,所以為避免這樣的建立與回收物件,CharArrayBuffer 儲存 cursor 中的 data,然後直接從 CharArrayBuffer 中存取,reuse。


Using a color as part of your list selector may entirely fill your ListView.
This problem comes from the fact a ColorDrawable does not respect its bounds: it entirely fills the clip rect of the Canvas in which it is drawn into.

Solution
Use a Drawable that respect its bounds such as a GradientDrawable or a NinePatchDrawable.

 
   
* Reference
- AndroidDevBlog » ListView Tips & Tricks #2: Sectioning your ListView
- AndroidDevBlog » ListView Tips & Tricks #3: Create fancy ListViews
- Why is my list black? An Android optimization | Android Developers Blog

[Android] background of android.R.style.Theme_Holo_Light_Dialog

Situation

在 Activity 中設定 android.R.style.Theme_Holo_Light_Dialog

並將此 theme 的背景設為半透明

(Using custom style extends android.R.style.Theme_Holo_Light_Dialog)

開啟畫面時 預設會 focus 在 editText 而跳出 soft keyboard

dialog background 會由半透明變成全黑

But! 相同方式 若是在 AndroidManifest.xml 中設定 theme

即使跳出 soft keyboard 背景也不會變黑?!


Record

soft keyboard is a dialog on window top.

而預設的 soft keyboard dialog style 的背景是黑色的

是否是因為此背景使得 Activity 也轉為黑色背景?


* Reference
- How is the soft keyboard in Android drawn? - Stack Overflow

[Android] Dialog style attributes


@null


true


false


true


@color/transparent


false


* Reference
- android 自定义Dialog背景透明及显示位置设置 - J健 - 博客园

[Android] setContentView of Dialog

Error Message

android.util.AndroidRuntimeException: requestFeature() must be called before adding content

Solution

一定要在 dialog.setContentView() 呼叫 dialog.show()。


* Reference
- android alertdialog布局 dialog布局 - - ITeye技术网站

[AndroidView] Clickable widget in ListView item

Occurred when

如果是 button 則會接收走 click item event,使得 ListView 沒有接收到 click item event; 但若是 TextView 則不會有此現象。


Solution

在 button 設定以下屬性

android:focusable="false"


* Reference
- android - ListView and Buttons inside ListView - Stack Overflow
- [转]ListView事件的研究 - 雪夜&流星 - 博客园

[AndroidDev] Screen Compatibility Mode

Notice:
如果你所開發的 app,是小於 Android 3.0 且已經能在 tablet 上正常顯示,應該關閉此功能以維持 the best user experience。

Definition:
  • 為了幫助不能在大螢幕上正常顯示 layout 的 app 的模式。
  • 但!! Screen compatibility mode 不是作為解決顯示在 larger screen 的根本方法,因為他是放大 layout 因此使得畫面變模糊。


有以下兩種版本:

Version 1 (Android 1.6 - 3.1)
  • 系統以 normal size 來畫 layout,剩餘沒填滿的地方,則都填入黑色。
  • 僅適用於 screen size 320dp x 480dp。
  • To disable this version of screen compatibility mode, you simply need to set 
    • android:minSdkVersion or android:targetSdkVersion to "4" or higher, or
    • android:resizeable = "true".
Version 2 (Android 3.2 and greater)
  • 系統以 normal size 來畫 layout,再放大 layout 填滿 screen,所以可能會顯得模糊。
  • 如果 app 沒有宣告 <supports-screens android:largeScreens="true" />,那在 system bar 會出現選項(an icon with outward-pointing arrows)讓 user 選擇是否開啟此功能;但若 app 有宣告,user 則不能選擇。

Disabling Screen Compatibility Mode

讓 user 自行選擇是否使用(>= Android 3.2):
  • set both android:minSdkVersion and android:targetSdkVersion to "10" or lower and does not explicitly declare support for large screens using the <supports-screens> element.
  • set either android:minSdkVersion or android:tagetSdkVersion to "11" or higher and explicitly declares that it does not support large screens, using the <supports-screens> element.

Easiest:
表示支援所有大小的 screen,系統會 resize layout 每個 screen。


Easy but has other effects:
In your manifest's <uses-sdk> element, set android:targetSdkVersion to "11" or higher:

表示你的 app 支援 Android 3.0 與能正常執行於 larger screen size。

Caution:
When running on Android 3.0 and greater, this also has the effect of enabling the Holographic theme for you UI, adding the Action Bar to your activities, and removing the Options Menu button in the system bar.
If screen compatibility mode is still enabled after you change this, check your manifest's and be sure that there are no attributes set "false".


Enabling Screen Compatibility Mode

  • 如果是開發 Android 3.2 (API level 13) or higher 的 app 可以用 <supports-screens> 決定是否使用次功能。
  • 設定 android:minSdkVersion or android:targetSdkVersion to "11" or higher,user 則不能使用。(?)
If either of these are true and your application does not resize properly for larger screens, you can choose to enable screen compatibility mode in one of the following ways:

表示你 app 支援的 the maximum "smallest screen width" 是 320 dp,也就是說當 device screen 的 smallest screen width 大於 320 dp,user 就能使用 screen compatibility mode。

強制開啟此功能
If your application is functionally broken when resized for large screens and you want to force users into screen compatibility mode (rather than simply providing the option), you can use the android:largestWidthLimitDp attribute:


<supports-screens> 設為 true,表示你的 app 支援該大小的 screen,不使用此功能。


* Reference
- Screen Compatibility Mode
- Screen Compatibility Mode

[Java] final in Inner Class

final in Local Inner Class
建立在 Method 中的 inner class。
Local inner class 所在的 Method 回傳值(return)後,Method 中的變數將會被銷毀,因此在 Method 中,被 Local inner class 所用到的變數會被複製一份來使用,此時,如果該變數不是 final,則複製的變數就可能因為更改而不同步,造成錯亂,因此 Local inner class 所用到的 local variables 必須標記為 final。

final in Anonymous Inner Class
匿名式 Anonymous inner class 所用到的 local variables 也必須須標記為 final,因為 Anonymous Inner Class 在實體化時,會將使用到的 local variables 直接複製並且生成為自己的 private 變數,同樣的,出現拷貝時,就會有同步的問題,因此該變數也必須被標記為 final。


* Reference
- InnerClass 的解析 @ 來喝杯JAVA咖啡 :: 痞客邦 PIXNET ::

2012年10月9日 星期二

[Android] Restart activity after backing from it

Message

Launch timeout has expired, giving up wake lock!

Activity idle timeout for ActivityRecord


Occurred when

當想要開啟的 activity 尚未 destroy 時,則會出現此 warning 且 activity 在 destroy 後不會再次被開啟。



* Reference
- Launch timeout has expired, giving up wake lock! - Google 網上論壇
- android - Launch timeout has expired, giving up wake lock! Activity idle timeout for HistoryRecord. Is this something to worry about? - Stack Overflow

[AndroidTool] HierarachyViewer unable to debug device

Error Message

Unable to get view server protocol version from device
Unable to debug device

Caused by:

因為大部份手機不允許使用 HierarachyViewer,以保護手機上 app 的安全,因此必須在開發機或 emulators 上使用。


* Reference
- android - Why is hierarchyviewer not working for Samsung Galaxy TAB 7.0? - Stack Overflow

Unstructured Supplementary Service Data (USSD)

Introduction
  • 是用戶端(手機)在 GSM 系統上與系統服務商伺服器溝通的一種協定,使用者透過手機撥號程式輸入特定 USSD 指令之後,可以取得系統服務商提供的服務。
    • ex: 查詢預付卡餘額,在手機上按 *#06# 會跳出 IMEI 碼。
  • 部分手機廠商使用自定USSD指令對手機做特殊設定或操作。
    • ex: 恢復為出廠設定、開啟工程模式等。
  • Format:
    • 每一個USSD字串都要以「*」字元開始再以「#」結束。


Compared with SMS

UUSD 和 SMS 都是 GSM 系統用來傳送數據的服務。
  • 操作方式
    • UUSD
      • 發送 USSD 和撥一組電話號碼非常類似,因此不需要依靠手機提供特定的介面。
    • SMS
      • 不同的手機會有不同的操作方式。
  • 傳送方式
    • UUSD
      • 建立一條固定且快速的通道,並沒有任何儲存媒介。
      • 是 Session-oriented 的處理方式,當客戶送出 USSD 需求,此時會有一個 session 建立連結,而且這個 Session 會一直保留直到客戶接收或者 AP time-out 才釋放,因此不需要預留訊息頻道。
      • 指令可以儲存在電話簿或使用快速撥號鍵,當需要重複發送時非常快速且方便。
      • 不保證訊息一定能傳送到目的端,不論由手機發出的申請需求或是應用程式提供的服務傳送。
    • SMS
      • store and forward 的機制,也就是所發出的簡訊會先被儲存在簡訊中心,以便於在適當時機將訊息送達手機上。
      • 是 Transaction-oriented 的方式,先儲存再傳送,所以若傳送失敗則可以由系統自行重送。
  • 處理時間 
    • USSD 1:SMS 7
  • 設計
    • UUSD
      • 為了讓 GSM 網路能提供一種發送指令的方式,所以 USSD 的目的地是後端的應用程式。
    • SMS 
      • 提供了除了通話之外的另一種用戶和用戶之間的溝通方式。
  • USSD 比喻成網頁的瀏覽,而 SMS 則類似 e-mail 的功能。
  • USSD 支援無縫漫遊 (seamless roaming),SMS 則否。


* Reference
- 研究:USSD指令可遠端破壞Android手機資料與SIM卡 | 即時新聞 | iThome online
- USSD功能_小林子_新浪博客
- USSD_百度百科
- USSD1-3ns
- ACE

2012年10月8日 星期一

Supporting Multiple Screens - 換算

算式
  • px = dp * (dpi / 160)
  • dp = px /(dpi/160)
  • dpi type = squrt(xx + yy) / inch
  • sqrt(xx + yy) / dpi type = inch

Examples:
  • not2 5.5" 1280*720 pixels
    • 267 dpi -> xhdpi
  • Amazon Kindle Fire HD 7" 16GB 7" 1280 x 800 pixels
  • Google Nexus 7 16GB 7" 1280 x 800 pixels
    • 191 dpi -> hdpi
  • ASUS Eee Pad Transformer Prime TF201 32GB 10.1" 1280 x 800 pixels
  • SAMSUNG GALAXY Note 10.1 Wi-Fi 10.1" 1280 x 800 pixels
    • 132 dp -> mdpi


dpi
  • ldpi: ~ 120 dpi
  • mdpi: 120 dpi ~ 160 dpi
  • hdpi: 160 dpi ~ 240 dpi
  • xhdpi: 240 dpi ~ 320 dpi

dp to screen size examples:
  • 480 dp
    • 480 mdpi
      • 480 px -> 4" ~ 3"
    • 720 hdpi
      • 1080 px -> 9.5" ~ 6.3"
    • 960 xhdpi
    • 1920 px -> 11.3" ~ 8.4"
  • 600 dp, about 7"
    • 600 mdpi
      • 600 px -> 7" ~ 5.3"
    • 900 hdpi
      • 1350 px -> 11.9" ~ 7.9"
    • 1920 xhdpi
      • 3840 px -> 22.6" ~ 16.9"

[AndroidDev] Supporting Multiple Screens

Android system 用以下方式使得你 App 不因螢幕密度有所改變 (density independence):
  • Scales dp units as appropriate for the current screen density
    • Use wrap_content, fill_parent, or dp units when specifying dimensions in an XML layout file
    • Do not use hard coded pixel values in your application code
    • Do not use AbsoluteLayout (it's deprecated)
  • Scales drawable resources to the appropriate size, based on the current screen density, if necessary.
    • Supply alternative bitmap drawables for different screen densities
=> Android System 依據 screen size/density 調整 layout;依據 screen density 調整 bitmap drawables。


How to Support Multiple Screens
  • Explicitly declare in the manifest which screen sizes your application supports
    • 宣告 <supports -screens="-screens"> 以避免你的 app 被從 google play 下載到不合的裝置。
    • 但當運作在較大的螢幕上時會影響 screen compatibility mode 的運作。
  • Provide different layouts for different screen sizes
    • 提供不同 layout for 不同螢幕大小,利用空間及便於 user 操作。
    • ex: small, normal, large, and xlarge。
    • 但是在 Android 3.2 (API level 13) 以上 screen size groups are deprecated,應改使用 sw-dp configuration qualifier。
  • Provide different bitmap drawables for different screen densities
    • 提供不同大小的圖片資源。
    • ex: ldpi (low), mdpi (medium), hdpi (high), and xhdpi (extra high)。
    • 假如只提供預設大小 (drawable, mdpi),那麼圖片在 hdpi 被放大,ldpi 縮小。

系統選擇 resources 的方式

  • The system uses the appropriate alternative resource
    • 依據螢幕 size and density 和你所提供的 resources 及所設定的 qualifier 對應出最適合的 resources,無則使用預設放大縮小(ex: drawable)。
    • 但在使用預設前,系統會先找是否能使用其他 density resources 的可能。
    • ex: 若需要 ldpi,但只有 hdpi and mdpi,那麼系統會優先選擇 hdpi 的,因為改變較小,hdpi * 0.5 < mdpi * 0.75。 
  • Eliminate resource files that contradict the device configuration. 
    • 依 qulifier 篩選,刪去不合者,但 Screen pixel density 不合時並不會刪去,Android 會選擇最適合 螢幕密度的(most closely matches the device screen density)。 
    • 有以下 qulifier: 
      • MCC and MNC 
      • Language and region 
      • smallestWidth(Added in API level 13.) 
      • Available width(Added in API level 13.) 
      • Available height(Added in API level 13.) 
      • Screen size(Added in API level 4) 
      • Screen aspect
        • long: Long screens, such as WQVGA, WVGA, FWVGA 
        • notlong: Not long screens, such as QVGA, HVGA, and VGA 
      • Screen orientation 
      • UI mode(Added in API level 8, television added in API 13) 
      • Night mode( Added in API level 8.) 
      • Screen pixel density (dpi) 
      • Touchscreen type Keyboard availability 
        • Primary text input method 
        • Navigation key availability 
        • Primary non-touch navigation method 
      • Platform Version (API level) 
Note: 
  • 選擇 size qualifiers 時,系統會選擇較小 screen size 的資源,
    • ex: large screen size 使用 normal screen size resources。 
  • 但如果只有較大 screen size resources 可用時,則會 crash
    • ex: normal screen size,但只有 large size resource。 
Tip: 
如果不想要被放大縮小,則可將圖片放入 nodpi;沒有 qualifier,是預設仍會放大縮小。


New qualifiers in Android 3.2 
  • 在 Android 3.0 時,要提供給 tablet 使用的 layout 可放入 res/layout-xlarge/,但這樣如果想在 7" 上也使用 tablet layout,則大部份都會不合條件,7" tablet 會和 5" handset 一同屬於 large group,這樣開發者變無法藉 screen size group 讓 7" tablet 能使用不同的 layout,因此在 Android 3.2 有了新的 qualifier,swdp
  • qualifiers 上指定的 size 應該為你畫面呈現時所需要的空間 (activity's window, include action bar),因為 Android System 可能會佔掉些空間 (such as the system bar at the bottom of the screen or the status bar at the top),所以系統是扣除 system UI 後的大小才是有效範圍
利用 qualifier 使用不同資源:
  • Create a new directory in your project's res/ directory and name it using the format:
    • <resources_name>-<qualifier>
      • <resources_name> is the standard resource name.
        • ex: drawable, layout, 
      • <qualifier> is a configuration qualifier.
        • ex:  hdpi, xlarge..
    • 可同時使用多個,用 dash (-) 做為分隔即可。
  • 在該指定的 directory 下放入相對應的 configuration-specific resources,resource 命名需和 default resources 相同,系統才能替代。


Scaling Bitmap objects created at runtime
  • a Bitmap object 系統視其為 mdpi,並且會使用 "auto-scaling"。
    • 若是想建立符合 screen density 的 bitmap,使用 setDensity() 指定是 DisplayMetrics#DENSITY_HIGH, DisplayMetrics#DENSITY_LOW...etc。
    • 如果是透過 BitmapFactory 建立 bitmap (ex: from a file or a stream),使用 BitmapFactory.Options 去設定屬性,做為系統是否 scale it 的參考,ex:
      • inDensity: 設定 bitmap density。
      • inScaled: 指定 bitmap 是否縮放以符合 screen size。如果設為 false,則表示關閉 pre-scaling 功能,那麼系統則會 auto-scale it at draw time。
  • auto-scale 會比 pre-scaling 花費較多 CPU 資源但較節省 memory 空間。
Note:
In Android 3.0 and above, there should be no perceivable difference between pre-scaled and auto-scaled bitmaps, due to improvements in the graphics framework.


To summarize, you should be sure that your application layout: 
  • Fits on small screens (so users can actually use your application) 
  • Is optimized for bigger screens to take advantage of the additional screen space 
  • Is optimized for both landscape and portrait orientations 



* Reference
- Supporting Multiple Screens | Android Developers
- Providing Resources | Android Developers

2012年9月26日 星期三

[AndroidDev] New resources selector (>= API 3.2)

Screen density dpi (dots per inch)
ex: 相同 physical area "low" density 會比 a "low" density screen "normal" or "high" density screen 較少 pixel。

dp (density-independent pixel)
  • The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen
  • The baseline density assumed by the system for a "medium" density screen (160 dpi).
  • px = dp * (dpi / 160)
    • ex: on a 240 dpi screen, 1 dp equals 1.5 physical pixels.
  • scaling ratio
    • 3(ldpi) : 4(mdpi) : 6(hdpi) : 8(xhpi)
    • ex: 480 x 800 hdpi/1.5 -> 320 x 533 mdpi in dp's

Screen size
  • Supported from 1.6.
  • 是系統依照 pixel and density 去算出長寬的 dp 然後對應所得。
  • Resolustion convert to dp presentaion of mdpi and decide its size (small, ..)。
  • 分類:
    • xlarge screens are at least 960dp x 720dp. (>= 2.3)
      • approximately-10” tablets, ex: Motorola Xoom
    • large screens are at least 640dp x 480dp.
      • ex: Dell Streak and original 7” Samsung Galaxy Tab
    • normal screens are at least 470dp x 320dp.
    • small screens are at least 426dp x 320dp.
      • Android does not currently support screens smaller than this.
  • 將裝置 dpi 轉至 mdpi,對應上表,長寬最接近且不小於標準之分類。ex:
    • A QVGA screen is 320x240 ldpi.
      • ldpi * 4/3 = mdpi
      • Result: 426dp x 320dp => small
    • The Xoom is a typical 10” tablet with a 1280 x 800 mdpi screen.
      • Result: 1280 x 800 => xlarge
    • The Dell Streak is a 800 x 480 mdpi screen.
      • Result: 800 x 480 => large
    • A typical 7” tablet has a 1024 x 600 mdpi screen.
      • Result: 1024 x 600 => large
      • But!! Exception "Samsung Galaxy Tab"
      • Samsung Galaxy Tab 1024 x 600 7” 應該是為 large,但因為 device configure 視為 hdpi 所以 hdpi * 2/3 = mdpi => 682dp x 400dp => normal!! 所以它應該是 large 但系統會將其視為 normal。
      • This was a mistake in the framework’s computation of the size for that device that we made. Today no devices should ship like this....

新增於 3.2 的屬性:
  • width dp
    • 現在螢幕方向的寬(dp),也就是當方向改變,寬也會隨之改變。
    • the current width available for application layout in “dp” units; changes when the screen switches orientation between landscape and portrait.
  • height dp
    • 現在螢幕方向的高(dp),也就是當方向改變,寬也會隨之改變。
    • the current height available for application layout in “dp” units; also changes when the screen switches orientation.
  • smallest width dp
    • 螢幕高與寬的最小值,此值固定,不會因為螢幕方向改變而改變。
    • the smallest width available for application layout in “dp” units; this is the smallest width dp that you will ever encounter in any rotation of the display.

Typical numbers for screen width dp are:
  • 320
    • a phone screen 
    • 240 x 320 ldpi, 320 x 480 mdpi, 480 x 800 hdpi, etc
  • 480
    • a tweener tablet like the Streak 480 x 800 mdpi
  • 600
    • a 7” tablet 
    • 600 x 1024
  • 720
    • a 10” tablet
    • 720 x 1280, 800 x 1280, etc


Resources Selector Examples

限定使用資源的最小寬度(smallest-width),如下:
res/layout/main_activity.xml           # For phones
res/layout-sw600dp/main_activity.xml   # For 7” tablets
res/layout-sw720dp/main_activity.xml   # For 10” tablets
Android 會選擇最接近但不大於的自身寬度的資源,如 700dp x 1200dp tablet 會使用 layout-sw600dp 裡的資源。


限定使用資源的寬度(width),假設你想直向時只顯示某區塊,而橫向時因為寬度較大,想顯示多點內容,可以使用這方式,如下:
res/layout/main_activity.xml          # Single-pane
res/layout-w600dp/main_activity.xml   # Multi-pane when enough width

smallest width < 600 時使用 layout; 大於 600 則會依據方向所在的寬使用 layout-sw600dp 或 layout-sw600dp-w720dp:
res/layout/main_activity.xml                 # For phones

res/layout-sw600dp/main_activity.xml         # Tablets

res/layout-sw600dp-w720dp/main_activity.xml  # Large width



// 或是寫成 layout-sw600dp-port,表示直向時使用此

res/layout/main_activity.xml                 # For phones

res/layout-sw600dp/main_activity.xml         # Tablets

res/layout-sw600dp-port/main_activity.xml    # Tablets when portrait


和舊的 qualifier 一同使用,如下:
// 使用 layout-swNNNdp 比 layout-port 好
res/layout/main_activity.xml                 # For phones
res/layout-land/main_activity.xml            # For phones when landscape
res/layout-sw600dp/main_activity.xml         # Tablets


相容性寫法

Type 1 - Using new qualifiers with old qualifiers
new qualifiers(ex: layout-sw600dp) 會被舊版本忽略,所以以下寫法能 work:
res/layout/main_activity.xml           # For phones
res/layout-xlarge/main_activity.xml    # For pre-3.2 tablets
res/layout-sw600dp/main_activity.xml   # For 3.2 and up tablets

Type 2 - Using new qualifiers with old qualifiers for different layouts
利用 values selector 使用相同名稱指向不同 layout:

res/layout/main_activity.xml           # For phones
res/layout/main_activity_tablet.xml    # For tablets


res/values-xlarge/layout.xml
res/values-sw600dp/layout.xml

res/values-sw600dp/layout.xml:

    
            @layout/main_activity_tablet
    


Type 3 - Select in code
在程式中判斷螢幕大小決定 layout:
public class MyActivity extends Activity {
    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate();

        Configuration config = getResources().getConfiguration();
        // config.smallestScreenWidthDp: >= API 3.2
        if (config.smallestScreenWidthDp >= 600) {
            setContentView(R.layout.main_activity_tablet);
        } else {
            setContentView(R.layout.main_activity);
        }
    }
}


* Reference
- Android Developers Blog: New Tools For Managing Screen Sizes
- Supporting Multiple Screens

2012年9月15日 星期六

[Screen] Sensor-on-lens

Sensor-on-lens
  • 傳統螢幕
    • 由三層組成,最底層是顯示層 (Display),中間是感應層 (Sensor),而最上是鏡片層 (Len)。
    • 這三層就組成了觸控屏幕,既可顯示影像,亦可感應手指觸控。
  • 而 Sensor-on-lens 就是將感應器整合在鏡片內,螢幕就由兩層所組成。
  • 優點
    • 可讓螢幕變得更薄。
    • 提升了畫面的清晰度。
    • 在光線下影像會較明亮。
    • user 使用起來會更覺 “貼手”。


* Reference
- Sony Mobile

[JavaScript] Regular Expression syntax

RegExp(pattern [, flags])
/pattern/flags

  • pattern
    • The text of the regular expression.
  • flags
    • If specified, flags can have any combination of the following values:
  • g
    • global match
    • 找全部。因為 REGEX 預設碰到第一個符合的內容就結束比對。
  • i
    • ignore case 勿略大小寫。
  • m
    • Treat beginning and end characters (^ and $) as working over multiple lines (i.e., match the beginning or end of each line (delimited by \n or \r), not only the very beginning or end of the whole input string)


* Reference
- RegExp | MDN
石頭閒語:Regular Expression (RegExp) in JavaScript - 樂多日誌

[Android] Memory Cache

Reference
  • reference 的可以分為多種強度,我們最熟悉和最常使用的是 strong reference。
  • Four different degrees of reference strength: strong, soft, weak, and phantom.
  • 強度的差異在於 reference 和 garbage collector 間的互相影響關係。

Strong Reference
// buffer 就是 strong reference
StringBuffer buffer = new StringBuffer();
  • 當 reference 指向一個以上的物件,便是 strong reference。
  • 可以防止此 reference 被 GC。
  • 缺點:
    • Memory: 因為使得物件不能被回收,所以有造成 memory leak 的危險。
    • Caching: 假設在 application 中應用到許多大圖片,為了一直 reload 而 cache 圖片,所以 always 會有 reference 指向圖片,使得它在 memory 且不會被回收,也就是說我們得決定它是否該被移除且使其可以回收。

WeakReference
weak reference 則是隨時有可能已被回收。
// API 使用方式如下,建立 Widget 的 WeakReference。
WeakReference weakWidget = new WeakReference<widget>(widget);
// 取出 Widget object。
// 注意: 因為物件可以被回收,所以可能會得到 null。
weakWidget.get()
WeakHashMap
  • 作用類似 HashMap,只是 key 是使用 weak reference,若 key 變成 garbage 則它的 entry 便自動會被移除。
  • 但並不是你啥也也沒做他就能自動釋放,而是你使用到 value 才會被釋放。
  • super(key, queue); 只有 key 才是 weak reference,value 仍是 strong reference,所以 System.gc() 後,key 會被清除,value 則是才被視為 weak reference 然後到被調用到了才會被清除。

Reference queues
  • 當 WeakReference 回傳 null 時表示指向的物件已被回收,WeakReference object 也無用了,所以如 WeakHashMap 會去移除這類的 WeakReference object,避免 WeakHashMap 一直成長,其中卻有很多無用的 WeakReference 。
  • ReferenceQueue 可以幫助你管理這些 dead reference。
    • 如果你將 ReferenceQueue 傳入 weak reference's constructor,當有 reference 指向的物件被回收時,該 reference 會自動被 insert 到 ReferenceQueue 中,所以你可以定期清裡 ReferenceQueue 也就會清理了 dead reference。

Soft references
  • 類似於 weak reference,差異是比 weak reference 不易被回收。
  • 因為 soft reference 會盡量被保留在 memory 所以適合做 image cache。

Phantom References
  • Its get() method always returns null.
  • 用處:
    • 可以讓你決定何時將物件從 memory 移除。ex: manipulating large images,你可以先確定現在這一張已被移除,再載入下一張以避免 OOM。
    • 避免 finalize() method 可以 "resurrect" 建立了 strong reference 的 object。
      • override finalize() 的物件至少要被視為 GC 對象兩次以上才能被回收到,而不能及時的被回收,也因此會有多個待回收的 garbage 存在著等著被回收。

Android itself employs some caching as part of the resources infrastructure, so you are already getting the benefit of memory caching.

使用 bitmap 時,記得使用 recycle(),可以幫助釋放空間,所以若是再呼叫 getPixels() or setPixels(),可能會得到 exception,所以建議當不會再使用到 bitmap 時再使用。

LruCache
  • API level 12 (3.1)
  • Support Library back to API level 4 (1.6).
  • 管理與 cache 物件,呼叫 get(key) 取出物件,若物件不存在則會呼叫 create() 產生物件,並將新產生的物件加入 head of cache 再將其回傳。
  • 加入新物件時,cache 會檢查是否超過指定的大小,若超過則會刪除最後一筆 (tail of cache list)。

// override 這個 method 可以讓我們決定 cache 中每個物件 size 怎麼計算,default returns 1。
@Override
protected int sizeOf( String key, Bitmap value )
{
    return value.getByteCount();
}

Note:
Bitmap#getByteCount()
  • Supported from API Level 12。
// 建構子中則傳入想預設此 cache 的大小,這裡設定最大為 5 M。
// 所以一旦超過 5 M,物件會從最後一直被移除直到總大小小於 5 M。
public LruMemoryCache(Context context)
{
    super( 5 * 1024 * 1024 );
    this.context = context;
}

為避免發生 OutOfMemoryError,在系統呼叫 onLowMemory() 時建議呼叫 LruCache#evictAll() 移除所有元素再重建。

Note:
  • onLowMemory() 會被呼叫是因為整個系統的空間不足而不是因為你的 App 所用的空間已不足!
    • 所以等到此 method 被呼叫時已來不及,更好的方式是在 App 執行一開始便設定適當的大小限制給它。
    • ActivityManager#getMemoryClass() (API Level 5) 可以取得該 application 在 該 device 中的分配空間:
      • 單位為 megabytes。
      • 預設為 16 M,空間大點裝置可到 24 或更高。

也可以利用 LruCache 來管理在 SD card 中的檔案大小:
  • 儲存 File object 在 LruCache(override create())。
  • 以 file.length() 計算檔案大小 (override sizeOf())。
  • 移除物件時刪除 SD card 中的檔案 (override entryRemoved())。


* Reference
- Understanding Weak References | Java.net
- Styling Android » Blog Archive » Memory Cache – Part 1
- Styling Android » Blog Archive » Memory Cache – Part 2
- Styling Android » Blog Archive » Memory Cache – Part 3
- Styling Android » Blog Archive » Memory Cache – Part 4
- WeakHashMap的神话 - - ITeye技术网站
- WeakHashMap是如何清除不用的key的

2012年8月27日 星期一

[Java] Serialize

  • 以字串型態傳遞物件。
  • 不能跨平台。
  • 像物件的 version control id。
  • 當物件屬性改變此 id 就會改變。
  • 當 B side 接收到 Serialize id,會根據此 id 去 new 相對應的物件將值設定進去。

[Spring] enum type attribute

// 如果物件中有 enum type 的屬性。
public class User {
    private MyEnumType name;

    ...... 
}

<%-- 
    JSP 中 form 欄位的 value 必須放入 MyEnumType 才能對回物件。
    使用 List options
--%>
.....

2012年8月26日 星期日

[Spring] Type not matched when String is "" and is tried to convert to date

ERROR MESSAGE
Type not matched when String is "" and is tried to convert to date


Solution

因為 form 中的 date 為 "" (空字串) 因為要轉成 Date 時會出錯。

@InitBinder
protected void initializeBinder (WebDataBinder binder)  {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd" );
    dateFormat.setLenient(false);
    CustomDateEditor dateEditor = new CustomDateEditor(dateFormat, true);

    binder.registerCustomEditor(Date. class, dateEditor);
    binder.registerCustomEditor(ModelEntity.class, customPropertyEditor);
}

2012年8月25日 星期六

[JPA] @ModelAttribute("xxx")

// entity: request 中的值對設定到物件中。
@RequestMapping(...)
public void methodName(@ModelAttribute("model") EntityType entity) {}



---- Update on 2013/08/25 ----

// @ModelAttribute("xxx") 會建立 EntityType 的物件,並且將此物件放入 request.
@ModelAttribute("model")
public Object prepare(...) {
    Object model = new EntityType();
    return model;
}


[Android] MSISDN, ICCID, IMEI, IMSI

下列值在以下情況會被改變或是取不到正確值:
  • ICCID
    • 換了 SIM card
  • IMEI
    • 山寨機
  • ANDROID_ID
    • 恢復原廠設定


Related
MSISDN, ICCID, IMEI, IMSI

[ORM] Date and Timestamp

DB 中時間的 type 有:
  • Date
  • Timestamp

對應到 java 中的 type 皆是宣告為 Date

DB 都是收到相同的值 然後再依欄位 type 決定存入的值

例如若是 date 會被 truncate 掉 millisecond 後再存入

[Animation] Property Animation (>= 11)

Supported from API Level 11.

Property Animation
  • A property animation changes a property's (a field in an object) value over a specified length of time.
  • 以某項 attribute 進行動畫。ex: x-axis 使物件橫向移動。
  • 分為兩部份:
    • 計算產生動畫的值。
    • 設定動畫值於物件的 property 中。

  • The view animation system
    • View animation 是藉由重繪 view 來顯示動畫,而此動作是由每個 view 自己的 container 來做(because the View itself had no properties to manipulate)。
    • 雖然結果可以看到 view 出現在不同位置,但實際上沒有改變到 view object 的任何 property,所以關於 view object 的設定卻還停留在原位 (ex: 點擊原始位置才會觸發 view 的事件)。
  • The property animation system
    • Property animation 則是改善了這個問題,因為它是改變 view object 的 property 來顯示動畫。
    • 而當 view object 的 property 改變,會自動呼叫 invalidate() 。

TypeEvaluator
  • 決定如何去計算進行動畫的 attribute 的值。
  • An interface that allows you to create your own evaluator.
  • If you are animating an object property that is not an int, float, or color, you must implement the TypeEvaluator interface to specify how to compute the object property's animated values.
  • You can also specify a custom TypeEvaluator for int, float, and color values as well, if you want to process those types differently than the default behavior.

ValueAnimator
  • Keeps track of your animation's timing.
  • How long the animation has been running.
  • The current value of the property that it is animating.
  • 管理 object 動畫中的 attribute 在動畫過程中的值,包含資訊:
    • 是否重複動畫。
    • 接收更新動作通知的 listeners。
    • 使用客制化的 evaluator。
  • 但 ValueAnimator 並不會將計算後的值設給 property,因此要使用 listeners 接收計算後的值再自行去更新,例如需實作 ValueAnimator.AnimatorUpdateListener

ObjectAnimator
  • A subclass of ValueAnimator.
  • 可以設定發生動畫的物件以及決定動畫內容的 property。
  • 此 class 會更新 property 的值,所以大部份使用此 class 比較方便,不需自行處理更新這部份動作。

AnimatorSet
  • 設定動畫效果於一群 view,他們能一起變化、有序的或是延遲的。
  • Provides a mechanism to group animations together so that they run in relation to one another. You can set animations to play together, sequentially, or after a specified delay.


* Reference
- Property Animation | Android Developers

2012年7月1日 星期日

[Spring] Mapping among jsp, controller and DB

// === @ModelAttribute ===
@ReuestMapping(value=...)
public String m(
    @ModelAttribute(ATTRIBUTE_MODEL) MyObject myObject) {
    
    // 若 MyObject 前有宣告 @ModelAttribute(ATTRIBUTE_MODEL)
    // 會受 prepare() 中對 MyObject o 操作的影響
    // 若沒有宣告 則仍單純是 form bean

}

@ModelAttribute(ATTRIBUTE_MODEL)
public Object prepare() {
    // 進入 m() 前會先經過這裡
    MyObject o = new MyObject();
    return o;
}


// === URL Mapping ===
@RequestMapping(value = URL_MAPPING, method = RequestMethod.POST)
public String m(
    @RequestParam(value = ATTRIBUTE_ID, required = true) BigDecimal id) {
    // 除了 RequestMapping 中的 value 要 mapping 到以外
    // 若 RequestParam 中 required = true,request 中也必須帶有此 attribute
}


// === Mapping enum object to DB ===
// DB 內儲存的是 NAME1
// @Enumerated 便會儲存 MyObject 所對應的 name
@Enumerated (EnumType.STRING)
public MyObject getMyObject() {}

enum MyObject {
    NAME1("value1");
}


// DB 內儲存的是 DB_VALUE
// 從 DB 取出後 可藉 valueOfCode 取得相對應 MyObject
enum MyObject {
    NAME1("DB_VALUE");

    private static volatile Map<String, MyObject> registry = new HashMap<String, MyObject>();

    // Use DB_VALUE be the key of Map
    // put value to Map and use key to get MyObject
    public static MyObject valueOfCode (String code) {
        if(0 == registry.size())  {
             synchronized ( registry) {
                 if(0 == registry.size())  {
                     for(MyObject o: MyObject.values())  {
                         registry.put(o. code, o);
                     }
                 }
              }
        }
            return registry.get(code);
        }
    }

[Apache] Directory setting

httpd.conf
Alias /virtualUrl /RealUrl


    AllowOverride None
    Options None
    Order allow,deny
    Allow from all


2012年6月30日 星期六

[Spring] Spring Expression Language (SpEL)

Assume get this value from DB #{#root["valueB"]}/path
// Using Expression parser, valueB should be found from DB, too.
Expression expression = parser.parseExpression(property.getValue(), 
    new TemplateParserContext());
property.setValue(expression.getValue(context, String.class));


* Reference
- Spring Expression Language (SpEL)

2012年6月22日 星期五

[Web] Brief notes


  • slf4j
    • 在 jar 檔時就 binding,比較好切換。
  • framework
    • 提供 pattern 的模組
  • Spring framework
    • 本身是個大 factory,將工作交給底下的 factory...
  • Struts2
    • #attribute 作用約是 ${attribute}
  • iBatis
    • $var$
      • paraClass 中的 attribute
    • #fieldName:fieldType#
      • Table field
  • HTML
    • 由上而下 compiler,結果會是 DOM tree 結構。
    • DTD
      • 描述 HTML syntax
    • <meta>
      • 提供和 browser or search engine 相關的訊息。
      • ex: 描述文檔的內容。

2012年6月15日 星期五

[Android] Context

public abstract class Context
  • 管理 global application 資訊的 interface,是由 Android System 實作。
    • Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system.
  • 可由此取得 application-specific 的 resources and classes。
    • It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.

getApplicationContext()
  • 在啟動 app 時,預設會啟動 Application,也就是 AndroidManifest.xml 中的 <application>,因此也能自己實作指定在此 tag 中,替代此預設。
  • 回傳所在 process 中的 global application context。
    • Return the context of the single, global Application object of the current process.
  • 應被使用在當 lifecycle 不和當前 component 綁在一起時。
    • This generally should only be used if you need a Context whose lifecycle is separate from the current context, that is tied to the lifetime of the process rather than the current component.
ex: 
  • registerReceiver(BroadcastReceiver, IntentFilter)
    • 如果使用的是 Activity context,這個 receiver 就是被註冊在此 Activity,所以你必須在此 Activity destroy 前 unregister 此 receiver,若沒有這樣做則會發生 exception。
      • If you use the Activity context to register a receiver that is static (global to the process, not associated with an Activity instance) then that registration will be removed on you at whatever point the activity you used is destroyed.
    • 如果是使用 Application context,這個 receiver 是和 application 相關連,因此不會被 unregistered,但有可能會造成 leak。
      • However using the ApplicationContext elsewhere can easily lead to serious leaks if you forget to unregister, unbind, etc.
  • 使用在 DB 操作時。


* Reference
- 求getApplicationContext用法-Android 问题&解答-eoeAndroid开发者社区 - Powered by Discuz!
谈谈Android里的Context的使用!!! - Android_Tutor的专栏 - 博客频道 - CSDN.NET

[JPA] @OneToMany

// ObjectA many-to-one with ObjectB

// In ObjectA
// mappedBy  的值是在 ObjectB 中的 attribute
@OneToMany(fetch = FetchType.LAZY, mappedBy = "objectA")
public List<ObjectB> getObjectB()  {  
    return objectBs;  
}

// In ObjectB
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JoinColumns({
    @JoinColumn(name = "FIELD_X", referencedColumnName = "FIELD_X", insertable = false, updatable = false )
})
public ObjectA getObjectA() {  return objectA; }

[Database] BigDecimal

當 table 對應為物件時

若其 value 長度可能會超過 java int

這時候就會使用 BigDecimal type

ex: 流水號


* Reference
- How big is BigDecimal?

[Graphic] Gif format

GIF 的版本有分
  • GIF 87a: 不會動的
  • GIF 89a: 此版本的格式才支援動態


不會動的一定是 87a 格式

或是可以使用 Ultra Edit 查看 header

可分辨是何種格式的


* Reference
- wiki GIF

[AndroidLayout] Inflate layout

Error Message
06-11 16:31:59.046: E/ListView(28360): at java.lang.reflect.Method.invoke(Method.java:507)
06-11 16:31:59.046: E/ListView(28360): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
06-11 16:31:59.046: E/ListView(28360): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)
06-11 16:31:59.046: E/ListView(28360): at dalvik.system.NativeStart.main(Native Method)


Solution

inflate layout 傳入參數為

inflate(R.layout.items_row, parent, false);

or

inflate(R.layout.items_row, null);



* Reference
- Android: Custom ListAdapter extending BaseAdapter crashes on application launch

2012年6月9日 星期六

[Android] Content Provider

  • Content providers are the standard interface that connects data in one process with code running in another process.
  • The provider and provider client automatically handle security and inter-process communication.

ContentResolver
  • In the client application's process.
  • Owns the provider automatically handle inter-process communication.
  • Acts as an abstraction layer between its repository of data and the external appearance of data as tables.

query(Uri, projection, selection, selectionArgs, sortOrder)
Should do queries asynchronously on a separate thread. (ex: CursorLoader class)
  • projection: the columns that will be returned for each row
  • The expression that specifies the rows to retrieve is split into a selection clause and selection arguments.
  • selection
    • The selection clause is a combination of logical and Boolean expressions, column names, and values (the variablemSelection).
    • selection 中的值應用 ? 取代,實際的值放在 selectionArgs(the selection arguments array ),作為對應.
    • The selection clause is set to null, and the query returns all the words in the provider

Query result:
  • If no rows match the selection criteria
    • Cursor.getCount() is 0 (an empty cursor).
  • If an internal error occurs
    • Return null, or it may throw an Exception.
  • Since a Cursor is a "list" of rows, a good way to display the contents of a Cursor is to link it to a ListView via a SimpleCursorAdapter.

Content providers can offer the following formats:
You can see the available data types by looking at the Cursor class "get" methods.
  • integer
  • long integer (long)
  • floating point
  • long floating point (double)
  • Binary Large OBject (BLOB) implemented as a 64KB byte array

Three alternative forms of provider access are important in application development:
  • Batch access
    • You can create a batch of access calls with methods in the ContentProviderOperation class, and then apply them with ContentResolver.applyBatch().
    • Useful for
      • Inserting a large number of rows.
      • Inserting rows in multiple tables in the same method call
      • Performing a set of operations across process boundaries as a transaction (an atomic operation).
  • Asynchronous queries
    • You should do queries in a separate thread
    • One way to do this is to use a CursorLoader object. The examples in the Loaders guide demonstrate how to do this.
  • Data access via intents: 
    • Although you can't send an intent directly to a provider, you can send an intent to the provider's application, which is usually the best-equipped to modify the provider's data.


* Reference
- Content Providers
- Content Provider Basics

[Android] Links in TextView

* Reference
- public class LinkMovementMethod
- public class Linkify
- Android: Clickable hyperlinks in AlertDialog
- How do I make links in a TextView clickable? ***
- TextView 加链接所有方法 **

2012年6月3日 星期日

[Database] DataSource

有下列管理 transaction 的方式:
  • JDBC
  • JTA
    • 管理的範圍較廣,可以包含多種不同來源。
  • DataSource

連至 DB 的方式:
  • Local -> server -> DB
    • 要透過 jndi 向 server 取得 look up service -> DATASOURCE。
    • Too dependent on server.
  • Local -> DB
    • Security issue(user, password).

If web service is on Server:
  • 可以直接對應 jndi 取得 Datasource。


If NOT:
  • 方式一: 利用 InitialContext預設會使用 jndi.properties 中的 jndi name。
public class DataSourceFactory {

    private static DataSource dataSource;

    public static synchronized DataSource getDataSource()
            throws ConnectionException, NamingException {
        if (dataSource != null) {
            return dataSource;
        }

        String datasourceJndiName = Configuration.getInstance().getJndiName();
        if (datasourceJndiName == null) {
            throw new ConnectionException("cann't find datasource jndi name!");
        }
        InitialContext ctx = new InitialContext();
        DataSource ds = (DataSource) ctx.lookup("java:comp/env/" + datasourceJndiName);
        dataSource = ds;
        return dataSource;
    }
}
  • 方式二: springframework configuration, 透過 org.springframework.jndi.JndiObjectFactoryBean。
    • 此設定是 spring 包裝 方式一 取得 datasource 的過程。
    • 在這裡可以自行指定 jndi 變數來源。
    • 若是沒有此設定,則如 方式一 預設使用 jndi.properties 中的設定,因此若沒有在此檔中提供此資訊會掛掉。

[Android] WebView WebViewClient

  • WebViewClient.onLoadResource
    • Anything loaded in webview will pass by.
  • WebViewClient.shouldOverrideUrlLoading
    • Actions occured in webview will pass by.
    • But! Standard links and server redirects trigger shouldOverrideUrlLoading(); window.location does not.

2012年6月2日 星期六

[AndroidProcess] Background works

Main thread 負責處理 UI event,所以也稱為 UI thread,Activity、Service、Receiver、Provider,都是由 main thread 負責執行。因此不能在此 thread 中執行耗時的動作,android 會發出 ANR,這時候就得在 background thread 中執行,讓 main thread 同時仍能回應或執行 UI event,以避免 ANR 狀況。

sendBroadcast() 與 startService() 都一樣會被丟到 main message queue 裡,等待 main thread 的執行,只有呼叫 local content provider 不會進到 main message queue 裡,而是由 main thread 直接執行。但如果是 remote content provider 則是由 thread pool 中取得 thread 來執行,外部 client 呼叫 service 也是如此。

每個 Thread 中都有 Looper 和 Message Queue,Message Queue 中儲存著要被處理的 events (UI event and System event),Looper 負責 Thread 和 Message Queue 間的連繫。

另外,因為是 main thread 負責更新 UI,所以若是試圖在 worker thread 中更新 UI,是會得到 exception 的,必須把更新 UI 的動作再丟給 main thread 處理。


可選擇以下方式:

* Simple Worker Thread and runOnUiThread()/View.post()
View.post()
Each View object has a message queue which is processed sequentially on the UI thread. post() allows us to add a new message to the message queue.
new Thread(new Runnable() {
    @Override
    public void run() {
        // TODO works here.
        
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // UI event
            }
        });

        // or
        final TextView textView =
            (TextView) findViewById( R.id.textview );
        textView.post(new Runnable() {
            @Override
            public void run() {
                // UI event
                textView.setText( "Hello World" );
            }
        });
    }
}).start();

* new Thread + Handler
Handler: 負責處理 thread 的訊息(message)。
private Handler handler = new Handler() {
    @Override
    public void handleMessage(android.os.Message msg) {
        // UI event
        progressDialog.dismiss();
    };
}

new Thread() {new Runnable() {
    @Override
    public void run() {
        // TODO works here.

        // 把 message 送給 handler 處理。
        handler.sendEmptyMessage(0);

        // or 將 Runnable post 到 handler。
        handler.post(new Runnable() {
            @Override
            public void run() {
                textView.setText( "Hello World" );
            }
        });
    }
}.start();

* AsyncTask
  • 如果只會 Override doInBackground 則可考慮使用 Thread 即可。
  • AsyncTask 會 hold Activity context 直到工作結束,所以可能會有 context leak 問題。
new AsyncTask() {
    // onPreExecute(), onProgressUpdate()

    @Override
    protected Void doInBackground(Void... params) {
        // TODO works here.
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        // UI event
    };
}.execute();


** AsyncTask and Handler
  • AsyncTask 內部實做機制為較新且較強的 java.util.concurrent,但較佔資源,而 Handler Thread 則為基本的 Java Thread。
  • 由於 Handler Thread 依靠 Message Queue 與 Main Thread 互動,相對於 AsyncTask,Handler Thread 比較可能發生塞車情況。
  • 但 Handler Thread 在即時互動上優於 AsyncTask,因為 Main Thread 可以隨時傳送 Message 給 Handler Thread,而 AsyncTask 不行,只能依照事先定義 Callback 進行。
  • 基於輕量環境資源的有限,當執行單一的工作時建議使用 AsyncTask,如下載一個大檔案,但是當執行大量重複性的工作時,建議使用 Handler Thread,如下載多個小圖。

* Loader
  • Introduced in Android 3.0 and also included in the Support Library.
  • Used to asynchronously load data in an activity or fragment.
  • Quite effectively to perform these tasks:
    • Loading content either from a SQLite database or file storage, or from a network resource as a background task.
  • There are essentially three components that we need:
  • How to use:
    • Obtain LoaderManager instance from Activity/Fragment/FragmentActivity.
    • Implement LoaderManager.LoaderCallbacks.
      • Will create a loader.
      • Get called when the loader either finishes, or is reset.
      • These will all be executed on the UI thread, and we will typically implement them within our Activity / FragmentActivity.
      • 也就是在 Loader 中處理 UI event。(?)

* Service
  • Services is a means of performing some task which is not attached to a specific Activity.
  • Run in the main thread of their hosting process. (並不會在另一個 thread 中執行,所以不適做耗費 CPU 的工作 會有 ANR 的可能,或者是必須 new a thread。)
  • There are two types of Service:
    • A background Service
      • The default type of Service and can be killed by the OS (or Task Killer apps, more of them later) to free up system resources.
    • A foreground service
      • Not be killed by the OS, but requires an ongoing Notification to be displayed in the Notification bar while it is running so that the user is aware that the foreground Service is active and will not be killed automatically by the OS.
      • ex: music player.

* IntentService extends Service
  • Service + Handler + HandlerThread。
  • Will receive a single Intent and then shut down automatically once we have processed it.
  • 和 Service 不同,此 api 會執行在自己的 worker thread,陸續執行交給它的 request,但只會有一個 worker thread 同時也只會執行一個 request,當執行完後會自行停止。
  • 實做其 onHandleIntent(Intent intent),在這裡處理 request。
  • 是設計用來可以在一個 Service 中服務多項工作,因此在 onHandleIntent(),不可以呼叫 stopSelf(),全部工作結束,它會自行停止。
  • start service -> send message to handler that has non-UI thread looper -> handlerMessage() -> onHandleIntent()
    • Looper 就是訊息迴圈 (message loop),這是 Android UI 在處理各式訊息時,最重要的元件之一。
  • One word of warning:
    • Performing long tasks in an IntentService does have the inherent risk that it will stop if the device goes to sleep. You can prevent this from happening by holding a WakeLock while onHandleIntent() is executing. Just make sure you release it before onHandleIntent() returns. Alternatively use Mark Murphy’s WakefulIntentServicepattern.

* Pending
  • StrictMode
    • API level 9。
    • 可用於發現潛在問題,ex: 你該使用 background thread 的動作。
  • Loader
    • API level 11。


* Reference
- Background Tasks – Part 1 (Introduction)
- Background Tasks – Part 2 (Worker thread, Handler)
- Background Tasks – Part 3 (AsyncTask)
- Background Tasks – Part 4 (Loader)
- Background Tasks – Part 5 (Service)
- Background Tasks – Part 6 (IntentService)
- Android之Service与IntentService的比较 - HiPhoneZhu的专栏 - 博客频道 - CSDN.NET **
- 深入研究 IntentService 原始碼 ***
- IntentService的功用
- Android Handler 筆記 **
- Java Artisan: Android AsyncTask 與 Handler Thread 的差異 **
- Java Artisan: 在 Android 裡使用 Local Service

2012年5月20日 星期日

[AndroidDev] Managing the Activity Lifecycle

  • 如果 AndroidManifest.xml 中沒有任何 activity 有宣告 MAIN action 與 LAUNCHER category,此 app 的 launch icon 則不會出現在 app list 中。
  • onPause <-> onResume
  • onStop -> onRestart -> onStart -> onResume

onCreate()
  • 適合處理在整個 activity life 中只應處理一次的邏輯,ex: 初始化 class-scope variables。

onRestart()
  • 當 activity 是從 onStop() 被啟動時,系統才會呼叫此 method。所以若是有在 onStop() 中釋放資源,記得在此初始或設定。

onStart()
  • activity 已為可見狀態,但會很快的便進入 onResume()。

onResume()
  • 會停留到 resume 完 activity 到暫停前的狀態。

onPause()
  • activity 仍為半可視狀態,ex: 被 dialog 覆蓋。
  • 可表示 user 離開此 activity 而進入 onStop(),所以可執行:
    • Stop animations or other ongoing actions that could consume CPU.
    • Commit unsaved changes, but only if users expect such changes to be permanently saved when they leave (such as a draft email).
    • Release system resources.
      • broadcast receivers, handles to sensors (like GPS).
      • Any resources that may affect battery life while your activity is paused and the user does not need them.
  • 不需要在此儲存 user 所輸入的資料,因為其實此 Activity instance 還是被儲存在 memory 中的,所以當在 onResume(),元件的狀態會再被重新載入,除非這是項明確功能:
    • ex: email 會自動儲存為草槁。
  • 不適合在此中處理會耗費 CPU 的工作,ex: 寫入 DB,因為會拖慢顯現下一個 activity 的速度,所以這類型的工作更適合在 onStop() 中處理。
    • 要到 activity B 前,activity A 需先進入 onPause()。

onStop()
  • 保證 UI 不是可視的,user 已在使用另一個 activity 或 app。
  • 適合做耗費 CPU 的工作:
    • ex: 寫入 DB。
  • 不需要在此儲存 user 所輸入的資料,因為其實此 Activity instance 還是被儲存在 memory 中的,所以當 onResume(),元件的狀態會再被重新載入。
    • ex: If the user entered text into an EditText widget, that content is retained so you don't need to save and restore it.
    • 即使 activity 被 destroy,其中的 View objects 仍會被儲存在 Bundle 中,並且在 user 回到此 activity(the same instance of the activity) 時被重新載入。
  • 以下情況使得 activity A 會被 stopped 與 restarted:
    • user 由 Recent Apps window 開啟另一個 app,activity A 會進入 onStop(),若 user 再由 Home launcher icon or Recent Apps window 開啟你的 app,那麼 activity A 會進入 onRestart()。
    • 在你的 app 中進入下一個 activity,activity A 會進入 onStop(),若 user 按下 Back 鍵,activity A 會進入 onRestart()。
    • user 在使用 app 時有來電。

onDestroy()
  • The system calls onDestroy() after it has already called onPause() and onStop() in all situations except one:
    • when you call finish() from within the onCreate() method.
    • onCreate() 會直接進入 onDestroy()。

以下情況可能會使得你的 activity 被 destroyed:
  • The user presses the Back button.
  • Calling finish().
  • Activity is in onStop() 且已長時間沒有被使用而被系統回收。
  • Foreground activity 需要更多資源,因此關閉 background processes to recover memory。

若 activity 是被系統回收,那麼系統會記下它的狀態(is called the "instance state", stored in a Bundle object.),以在 user 想開啟此 activity 時能 restore 該狀態。

onSaveInstanceState()
  • 當系統要 destroy this activity,會呼叫此 method,並且傳入 Bundle object 來儲存 activity 資訊,所以你若有需要保存的資訊也可儲存在此 Bundle 中。
  • 然後此 activity 會被系統 recreate 並且傳入與 destroy 時相同的 Bundle object,因此可以在 onCreate() 中從 Bundle 中取出之前所儲存的資訊。
    • 但因為 activity 可以是完全新建立或是重新被建立的,也就是說傳入的 Bundle 不一定都是有值的,若是要使用,務必判斷是不是 null。
    • 或者與其在 onCreate() 中 restore 資訊,也可以選擇在 onRestoreInstanceState() 做。
      • 此 method 會在 onStart() 後被呼叫。
      • 只有在 Bundle != null 時會被呼叫。
  • The default implementation of this method saves information about the state of the activity's view hierarchy:
    • ex: he text in an EditTextwidget or the scroll position of a ListView. 
    • 所以在此 method 和 onRestoreInstanceState() 中記得呼叫 super.xxxx; 以儲存與重載 the state of the view hierarchy。


* Reference
- Starting an Activity | Android Developers
- Pausing and Resuming an Activity | Android Developers
- Stopping and Restarting an Activity | Android Developers
- Recreating an Activity | Android Developers

[AndroidLayout] Input Method Editors

若沒有做任何設定與調整,在輸入時所跳出的鍵盤(IMEs, Input Method Editors)很有可能會擋住正在輸入文字的元件,可以用以下方式處理:
  • 畫面中使用 scrollView,讓使用者可以自己適當的調整畫面位置。
  • 在該 activity 設 android:windowSoftInputMode ="adjustPan|adjustResize",讓系統幫忙處理。


android:windowSoftInputMode ="adjustPan"
  • Can prevent your background from resizing.
  • 不會呼叫 View.onSizeChanged()。
  • 不會調整 layout 所以不能保證能看到整個 layout 但會保持必能看到輸入框(平移)。
  • 設為 fullscreen 有時會使此參數失效,所以若是用 webview fullscreen 得注意。

android:windowSoftInputMode ="adjustResize"
  • 把原本的 layout(include background!) 往上頂,移出空間給 IME,但僅發生在 application 有可調整的空間。
  • 沒加此的話,不會一開啟就 focus on editText(?);加的話,一開啟就會 focus on 且有 soft input(?。
  • 會呼叫 View.onSizeChanged()。
  • 設為 fullscreen 有時會使此參數失效,所以若是用 webview fullscreen 得注意。


* Reference
- android:windowSoftInputMode
- Android Development Tips: Resizing layout while on-screen keyboard is displayed
- Issue 5497: adjustResize windowSoftInputMode breaks when activity is fullscreen
- Android windowSoftInputMode – Resize the application for the soft-keyboard
- Android: Soft Keyboard resizes background image
- android软键盘弹出引起的各种不适终极解决方案
- Android软键盘的隐藏显示研究 ***
- 关于android的输入法弹出来 覆盖输入框的问题
- Issue 14596: adjustPan not working correctly in landscape mode

2012年5月13日 星期日

[Android] The way to parser xml - SAX

Parser XML 可以用以下 API 達成:
  • SAX
  • Digester


SAX 
  • Simple API for XML。
  • 實作方式:
    • extends DefaultHandler
    • new SAXParserFactory
      • SAXParserFactory sAXParserFactory  =  SAXParserFactory.newInstance();
    • new SAXParser:
      • SAXParser sAXParser = sAXParserFactory.newSAXParser();
    • 從 SAXParser 中得到一個 XMLReader 的實例:
      • XMLReader xMLReader = sAXParser.getXMLReader();
    • Set Handler 到 XMLReader
      • xMLReader.setContentHandler(rssParser);
    • 藉 InputStream 取得 XML,用 handler 進行 parser。
      • xMLReader.parse(is);


DefaultHandler 執行方式:
  • startDocument()
    • 適合建立儲存物的集合 (ex: list)。
  • startElement(String namespaceURI, String localName, String qName, Attributes atts)
    • 解析過程中,遇到 XML 中的 tag 時,此 method 會被呼叫,可以由 localName 得知解析到那個 element 了。
    • 可以適當的建立相對物件。
    • attributes.getValue(NAME)
  • characters(char ch[], int start, int length)
    • 在執行 startElement() 後,此 method 會被呼叫,参数 ch[] 就是 element 中所帶的内容。
  • endElement(String namespaceURI, String localName, String qName)
  • endDocument()


* Reference
- android解析xml文件的方式(其二) - 东子哥 - 博客园
- 使用SAXParser取得XML文件里的属性值 - XML - AJava
- Android RSS解析步骤 | 易网联信
- SAX之:SAXParserFactory与SAXParser - 小文字 - 博客园

2012年5月6日 星期日

[Spring] configurations


<!-- Activates various annotations to be detected in bean classes -->
<!-- 設定註釋注册到Spring容器 -->
<context:annotation-config />

<!-- Scans the classpath for annotated components that will be auto-registered as Spring beans.
 For example @Controller and @Service. Make sure to set the correct base-package-->
<!-- 在 base-package下尋找有 @Component 和 @Configuration 的 target Class予註冊為 bean -->
<context:component-scan base-package="org.krams.tutorial" />

<!-- Configures the annotation-driven Spring MVC Controller programming model.
Note that, with Spring 3.0, this tag works in Servlet MVC only!  -->
<mvc:annotation-driven />


* Reference
- krams::: Spring 3 MVC: Using @ModelAttribute in Your JSPs

2012年5月5日 星期六

[AndroidLayout] declare-styleable and TypedArray

自定 View,且定訂屬性可以使用在 layout xml 中並取得其值。
  • Define attributes in <declare-styleable>。
  • extends View,畫出自己的圖,也可取得 xml 中的設定值。
  • 可在 layout xml 中引用自訂的 View。


Define attributes in <declare-styleable>。
  
      
          
          
      
  

extends View,畫出自己的圖,也可取得 xml 中的設定值。
public class CustomView extends View {
    private Paint paint;

    public CustomView(Context context,AttributeSet attrs) {  
        super(context,attrs);  
        paint = new Paint();  
          
        // 取出自定的 attributes from MyView.
        TypedArray a = context.obtainStyledAttributes(attrs,  
                R.styleable.MyView);  

        // 個別取出 attribute,要給預設值,以在 xml 中沒有定義時使用。  
        int textColor = a.getColor(R.styleable.MyView_textColor,  
                Color.WHITE);  
        float textSize = a.getDimension(R.styleable.MyView_textSize, 36);  
          
        paint.setTextSize(textSize);  
        paint.setColor(textColor);  
        
        // Give back a previously retrieved StyledAttributes, for later re-use.
        a.recycle();  
    }  
}

可在 layout xml 中引用自訂的 View。
  
  

* Reference
- Android 中自定义控件和属性(attr.xml,declare-styleable,TypedArray)的方法和使用 - jincf2011的专栏 - 博客频道 - CSDN.NET
- Declaring a custom android UI element using XML
- public void recycle ()

2012年5月2日 星期三

[Publish] Filters on Google Play

  • Google Play 會 filter app 是否相容於 device 來決定是否顯示於 user,filter 主要條件是:
    • 以宣告在 AndroidManifest.xml 中的 設定來和 device's configuration 做比對。
    • User's country and carrier, the presence or absence of a SIM card, and other factors. 
    • Filter 是以版本為根本,假設 user 已安裝 v1,但 v2 不適用於他的 device 那麼 user 便不會收到此 app 的更新通知。

Based
  • <supports-screens>
    • Smaller layout can be used on Larger screens; but Larger screen cannot be used on Smaller screens.
    • ex: Only declares: normalScreen
      • Available to both normal- and large-screen devices.
      • Not available to small-screen devices.
  • <uses-configuration>
    • Device Configuration: keyboard, navigation, touch screen
  • <uses-feature>
    • This functionality was introduced in Android 2.0 (API Level 5).
    • Device Features from name, ex:
      • <uses-feature android:name="android.hardware.sensor.light" />
    • OpenGL-ES Version(openGlEsVersion), ex:
      • <uses-feature android:openGlEsVersion="int">
    • 即使有些 device features 開發者並沒有宣告在此,Google Play 也會藉由<uses-permission>推出些 app 中應該會用到的 features 來做為 filter 條件。
  • <uses-library>
    • Device 中應該要有的 shared library。
  • <uses-permission>
    • 事實上並沒有直接使用宣告於此的做為 filter 條件,但會從此推論出應該使用到的 device feaures。
  • <uses-sdk> 
    • Minimum Framework Version (minSdkVersion) 
      • <uses-sdk android:minSdkVersion="3">
    • Maximum Framework Version (maxSdkVersion)
      • <uses-sdk android:maxSdkVersion ="10"> 
      • Deprecated. Android 2.1 以上(含)已不會再檢查此 attribute
      • The SDK will not compile ifmaxSdkVersion is set in an app's manifest. For devices already compiled with maxSdkVersion, Google Play will respect it and use it for filtering.
      • 不建議宣告此 attribute。


Advanced manifest filters
以下 attributes 通常使用於 high-performance games and similar applications that require strict controls on application distribution. Most applications should never use these filters.
  • <compatible-screens>
    • Google Play filters the application if the device screen size and density does not match any of the screen configurations (declared by a <screen> element) in the <compatible-screens>element.
    • Normally, you should not use this manifest element. Using this element can dramatically reduce the potential user base for your application, by excluding all combinations of screen size and density that you have not listed. 
  • <supports-gl-texture>


Other Filters
  • Application and publishing characteristics that affect filtering on Google Play.
  • Publishing Status
    • Only published applications will appear in searches and browsing within Google Play.
  • Priced Status
    • Not all users can see paid apps. 
    • To show paid apps, a device must have a SIM card and be running Android 1.1 or later, and it must be in a country (as determined by SIM carrier) in which paid apps are available.
  • Country / Carrier Targeting
  • Native Platform
  • Copy-Protected Applications

How Google Play filters by features

Google Play compares:
  • Features required by the application
    • An application declares features in <uses-feature> elements in its manifest 
  • Features available on the device, in hardware or software
    • A device reports the features it supports as read-only system properties.
    • 當 user 開啟 Google Play 會呼叫 PackagManager.getSystemAvailableFeatures() 取得 device features. 


How Google Play handles app
每次 developer 上傳 app 時,會列出 AndroidManfest.xml 中會用來做為條件的內容。
這些所得的 list 會做為 apk 的 metadata 與 the application .apk and the application version 儲存一起.
  • Filtering based on explicitly declared features
    • <uses-feature> 中  anandroid:required=["true" | "false"] attribute (API level 5 or higher),預設為 true,表示一定要符合。
    • 所以若不想因為此 feature 而被 filter 掉,可宣告此 feature 並將此參數設為 false。 
  • Filtering based on implicit features
    • 有可能因為下列因素 app 中有使用到某些 features 但並未被宣告
    • Compiled Android Library
      • Android 1.5  前並未有 <uses-feature> element.
      • The developer 誤以為所有裝置都會有此 feature 因此沒有宣告。
      • The developer 忘了.
      • The developer declared the feature explicitly, but the declaration was not valid. 
        • For example, 拼錯 feature 名稱。
    • 所以..
      • Google Play 會利用 <uses-permission> 去推論會使用到的 features 並自行做為 filter 條件。
      • 但如果不想要這樣則必須明確宣告在 <uses-feature> element 並且設 android:required="false"。


Special handling for Bluetooth feature
  • Google Play enables filtering for the Bluetooth feature only if the application declares its lowest or targeted platform as Android 2.0 (API level 5) or higher
  • However, note that Google Play applies the normal rules for filtering when the application explicitly declares the Bluetooth feature in a <uses-feature> element.


執行下列 command 可預知 Google Play 所得的 filter 條件

Android Tools > Export Unsigned/signed Application Package

# aapt dump badging <path_to_exported_.apk>


* Reference
- Filters on Google Play
<uses-feature>