2011年9月28日 星期三

[AndroidSign] apk sign

* Restriction
  • Android 系統禁止更新安裝簽名不一致的 APK。
  • You cannot release your application to the public when signed with the debug certificate.


* Generate apk sign
  • 要簽名一個沒有簽名過的APK,可以使用一個叫作 Auto-sign 的工具。
    • Auto-sign工具實際執行的是一個叫做Sign.bat的批處理命令。
    • 用文本編輯器開啟這個批處理文件。
  • Obtain a suitable private key


* signapk.jar
  • 是 Android 源碼包中的一個簽名工具。路徑為/build/tools/signapk/SignApk.java
  • 對比一個沒有簽名的 APK 和一個簽名好的 APK,會發現,簽名好的 APK 包中多了一個叫做 META-INF 的文件夾。裡面有三個文件:
    • MANIFEST.MF
    • CERT.SF
    • CERT.RSA。
  • signapk.jar 就是生成了這幾個文件(其他文件沒有任何改變。因此我們可以很容易去掉原有簽名訊息)。


* signapk.jar process:

1、生成 MANIFEST.MF 文件
  • 程式遍歷 apk 包中的所有文件(entry),對非文件夾非簽名文件的文件,逐個生成SHA1 的數字簽名訊息,再用 Base64 進行編碼。
  • 之後將生成的簽名寫入 MANIFEST.MF 文件。
  • SHA1 數字簽名
    • 是一種安全 hash 算法,類似於 MD5 算法。它把任意長度的輸入,通過散列算法變成固定長度的輸出(這裡我們稱作「摘要訊息」)。
    • 你不能僅通過這 個摘要訊息復原原來的訊息。另外,它保證不同訊息的摘要訊息彼此不同。
    • 因此,如果你改變了 apk 包中的文件,那麼在 apk 安裝校驗時,改變後的文件摘要信息與 MANIFEST.MF 的檢驗訊息不同,於是程式就不能成功安裝。

2、生成 CERT.SF 文件
  • 對前一步生成的 Manifest,使用 SHA1-RSA 算法,用私鑰進行簽名
  • RSA 是一種非對稱加密算法。
    • 用私鑰通過RSA算法對摘要訊息進行加密。在安裝時只能使用公鑰才能解密它。
    • 解密之後,將它與未加密的摘要訊息進行對比,如果相符,則表明內容沒有被異常修改

3、生成 CERT.RSA 文件
  • CERT.RSA文件中保存了公鑰、所採用的加密算法等訊息。


* Overview
1、 Android 簽名機制其實是對 APK 包完整性和發佈機構唯一性的一種校驗機制。
2、 Android 簽名機制不能阻止 APK 包被修改,但修改後的再簽名無法與原先的簽名保持一致。(擁有私鑰的情況除外)。
3、 APK 包加密的公鑰就打包在 APK 包內,且不同的私鑰對應不同的公鑰。換句話言之,不同的私鑰簽名的APK公鑰也必不相同。所以我們可以根據公鑰的對比,來判斷私鑰是否一致。


* APK Parser
  • 源碼中有一個隱藏的類用於APK 包的解析。這個類叫 PackageParser
  • 路徑為 frameworks\base\core\java\android\content\pm\PackageParser.java
  • 當我們需要獲取APK包的相關訊息時,可以直接使用這個 class。

我們就可以通過 packageInfo.signatures 來訪問到APK的簽名訊息。

它們的關係如下面代碼所示:

也就是說 signature = new Signature(certificate.getEncoded());

certificate 證書中包含了公鑰和證書的其他基本訊息。

公鑰不同,證書肯定互不相同。

我們可以通過 certificate 的 getPublicKey 方法獲取公鑰訊息。

所以比對簽名證書本質上就是比對公鑰訊息



Related
[Android] Debug Key


* Reference
- Android APK簽名對比及說明 - Android 軟體設計 - Android 台灣中文網 - Android(安卓,安致)討論區 - APK.TW **
- Signing Your Applications

[AndroidIntent] Intent Filter note

對一個android的應用程式而言,最重要的檔案是AndroidManifest.xml。它負責向下一層的framwork註冊該應用程式,包括此應用程式的名字,分組 (哪個category),用哪個icon,有什麼功能 (avtivity,service,broadcast receiver,content provider)等等。使得framework (package manager)接到通知 (intent)時,能夠根據目前系統註冊的情況,濾出符合條件的功能。


* Definition
  • Android 系統如何判斷哪個元件可以接收哪個 intent, 宣告在 AndroidManifest.xml 中。
  • 宣告元件時可加入的 Intent Filter 設定,屬性有 action, category, data,三個在一組內皆能有多個,只要符合三個各自條件,即通過此 intent-filter
  • 每個元件內可以設定 0 ~ 多組 的 intent filter每一組的 Intent Filter 都是一份比對規則,只要通過一組即可


* Process
當 intent 發出來時,系統會去檢查Manifest 內各元件內的intent filter, 而啟動適合的元件,若元件沒有設定filter,那就只能接收到有清楚指定 component 的 intent。


* action: 執行 intent 的方式。
  • 能有 0 ~ 多個
  • 合格條件: intent 中的 action 為 intent-filter 宣告的之一。
    • 如果沒有宣告任何一個,因為 intent 沒得比對,所以沒有任何 intent 會符合;
    • 如果是 intent 沒有帶有 action,filter 中至少有宣告一個,即能通過此 filter。

* category: intent 的類別。
  • 能有 0 ~ 多個
  • 合格條件: intent-filter 中必須完全符合 intent 中的 category
    • intent-filter 宣告比 intent 中還多的 category 是不影響的。
    • i.e. intent 中沒有 category,即合格。
  • Default Category
    • 當執行 startActivity() 而使用沒有明確設定目標的 intent (implicit intent),Category 會預設為 Intent.CATEGORY_DEFAULT
    • 因此,若 componen 需要接收 implicit intent,就必須在 intent filter 裡加上"android.intent.category.DEFAULT"。
    • 例外中的例外: 如果 filter 設定 "android.intent.action.MAIN" 和 "android.intent.category.LAUNCHER",則不需指定 DEFAULT 也可接收 implicit intent。

* data: intent 的資料類型。
  • 能有 0 ~ 多個
  • 合格條件: intent 中的 data 為 intent-filter 宣告的之一


. Updated on 2014/02/18


* Reference
- Android Intent Filter-判斷intent傳遞對象 - kei chueng - 博客园
- Intent Filter
- android -- 應用程式自我介紹之intent resolution @ 心的距離 :: 痞客邦 PIXNET ::
- <action>
- <category>
- <data>

2011年9月27日 星期二

[AndroidDev] Android Developers Blog: Preparing for Handsets



* Above code support  your app’s screen-size only for tablet in two different ways:
  1. It declares that the app does not support the screen size buckets “small”, “normal”, and “large”, which are traditionally not tablets
  2. It declares that the app requires a screen size with a minimum usable area that is at least 600dp wide

requiresSmallestWidthDp attribute is the new API supported from Android 3.2.

* The safest thing to do is develop your app against the platform that matches the API level you’ve set for minSdkVersion.

* For more information about why the “smallest width” screen size is important for supporting different screen sizes, read New Tools for Managing Screen Sizes (really; it’s got lots of things you need to know).

* Here are two guidelines to help make your Honeycomb tablet app work well on handsets:
  1. Build your design around Fragments that you can reuse in different combinations, in single-pane layouts on handsets and multi-pane layouts on tablets
  2. Be conservative with your Action Bar design so the system can adjust its layout based on the screen size

* Creating single-pane and multi-pane layouts
  • Single activity: Swapping the fragments within the activity when necessary.
    • Dynamically add each fragment to the activity at runtime---rather than declare the fragments in your activity’s layout file — because you cannot remove a fragment from an activity if it’s been declared in the XML layout.
  • Use separate activities to host each fragment on a handset.
    • When you need to switch fragments (such as when the user selects an item), start another activity that hosts the other fragment.


* Specifically, you should follow two general guidelines:
  • Do not manipulate one fragment directly from another.
    • To avoid directly calling one fragment from another, declare a callback interface in each fragment class that it can use to deliver events to its host activity, which implements the callback interface. When the activity receives a callback due to an event (such as the user selecting a list item), it acts appropriately based on the current fragment configuration.
  • Keep all code that concerns content in a fragment inside that fragment, rather than putting it in the host activity’s code.


* Here are some important tips:
  • When setting a menu item to be an action item, avoid using the “always” value. Use “ifRoom” for action items you’d like to add to the action bar. 
    • Now, you might need “always” when an action view does not have an alternative action for the overflow menu or when a menu item added by a fragment is low in the menu order and it must jump into the action bar at all times. But you should not use “always” more than once or twice.
  • When possible, provide icons for all action items and declare showAsAction="ifRoom|withText"
    • This way, if there’s not enough room for the text, but there is enough for the icon, then just the icon may be used.
  • Avoid using custom navigation modes in the action bar. Use the built-in tab and drop-down navigation modes.
    • They’re designed to be flexible and adapt to different screen sizes. 
    • For example, when the width is too narrow for both tabs and other action items, the tabs appear below the action bar. If your app requires a custom navigation mode in the action bar, thoroughly test it on smaller screens when Ice Cream Sandwich becomes available and make any adjustments necessary for a narrow action bar.


* Some other tips
  • When working with a ListView, consider how you might provide more or less information in each list item based on the available space. That is, you can create alternative layouts to be used by the items in your list adapter such that a large screen might display more detail for each item.
  • Create alternative resource files for values such as integers, dimensions, and even booleans. Using size qualifiers for these resources, you can easily apply different layout sizes, font sizes, or enable/disable features based on the current screen size.



* Reference
- Android Developers Blog: Preparing for Handsets

[Android] Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag

Error Message

Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

(發生在 content provider 中開啟 activity 時?)


Solution

Android has 4 components: Activity, Service, ContentProvider and Broadcast.

When Android needs to activate one of this components from your application, it looks if there is already existing running process with your application.

If not, then Android starts new process, initializes it, then it initializes your custom Application instance. And then it activates one of needed components.



Now, let's consider next scenario:

your application declared content provider in AndroidManifest.xml, and Android just about to start your application so you can provide some data to another foreground application.
and Android just about to start your application so you can provide some data to another foreground application.
Content Provider request is sent

  1. Your application wasn't running, and Android starts new process for it.
  2. Your custom Application instance is created
  3. Application.onCreate() is called.
  4. You start an activity
  5. Your Content Provider receives request

Somebody just wanted to connect to your content provider, but your application started an Activity instead. Same true for starting background Service and sometimes broadcast receivers.

Activity entends Context, and Override startActivity(). 如果使用 activity 中的 startActivity(),不會有任何限制,而如果使用 Context 的 startActivity(),就必須是在另一個新的 task. (?)

That's because you need to start new task when Activity is started outside of Activity context. But I strongly recommend to not start Activity from your Application'sonCreate().

Because Android guarantees that Application will be created only once and before any other component


* Reference
- startActivity的requires new task异常解析 - Android - mobile - ITeye论坛
- Android Application vs Activity - Stack Overflow **

[AndroidStorage] Content Provider 圖解







* Reference
- Byron's blog - Android 数据操作(个解)

2011年9月24日 星期六

[WEB] Project resources deployment path

ant > webroot /resources

maven > src/main/resources

[Android] app name setting and showing location

* When new an android project, you will see these information needed to fill:
  • Project name
    • 顯示在 eclipse 中的專案名稱。
    • export 時的預設名稱。
  • Application name
    • strings.xml 中預設產生的 app_name 的名稱。
    • activity 和 應用程式的預設名稱。
  • Package name
    • 預設產生的專案hierarchy。
    • AndroidManifest 中預設的 package name identifier.
    • BUT!
      • package hierarchy does not have directly relationship with package identifier. (?)
      • package identifier is relative to R.

* 在安裝 app 時,在 android installer 中的顯示名稱
  • 預設是使用<application>中的 label
  • 若沒有指定時,則是用 package name



* debug key apk cannot used to publish your app.

[Struts] <s:url>


<s:url>

會自動在 url 前加入 context root

2011年9月23日 星期五

[Android] Content Provider between Threads?

Error Message

java.lang.UnsupportedOperationException: Only CrossProcessCursor cursors are supported across process for now...



Solution

發生在 content provider 呼叫另一 content provider 的情況下

原因待解

20110923
- matrixCursor
- crossprocesscursor
- call content provider in another thread

[Apache] Set context root by MatchExPression

* Setting Apache context root (/conf/httpd.conf):

加入以下設定並填入該環境的 domain 和 port

MatchExpression /mobile WebLogicCluster={#domain}:{#port}|Debug=ON

[IE] focus

Error Message

在 IE6 和 IE7 上

若想要同時 focus 在頁面上和 alert 訊息

會因為先 alert 出訊息 而當使用者關掉 alert 再回到頁面上時

focus 效果已經消失 使用者也因此不會看到



Solution

利用 setTimeout( ) 來延遲 focus 事件 好讓使用者來得及看見

[WEBLOGIC] SAX Parser Factory


if [ "${SERVER_NAME}" = "managed01d-6" ] || [ "${SERVER_NAME}" = "managed01d-4" ]; then
    JAVA_OPTIONS="${JAVA_OPTIONS} -Djavax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"
    export JAVA_OPTIONS
fi

#
# http://forums.oracle.com/forums/thread.jspa?threadID=911954&tstart=150
# A bug with default SAX Parser Factory, version 10.3 for Windows
#
# JAVA_OPTIONS="${JAVA_OPTIONS}"
JAVA_OPTIONS="${JAVA_OPTIONS} -Djavax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"
export JAVA_OPTIONS








[JPA] javax.persistence.spi.PersistenceUnitInfo.getValidationMode()Ljavax/persistence/ValidationMode

Error Message
nested exception is java.lang.NoSuchMethodError: javax.persistence.spi.PersistenceUnitInfo.getValidationMode()Ljavax/persistence/ValidationMode;
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)


Solution

weblogic  /bea/setDomainEnv.sh 未指定 JPA jar path


if [ "${SERVER_NAME}" = "managed01d-1" ] ; then
    PRE_CLASSPATH="${DOMAIN_HOME}/lib-ext/hibernate-jpa-2.0-api-1.0.0.Final.jar"
    export PRE_CLASSPATH
fi

2011年9月19日 星期一

[Linux] crontab

* Definition
  • Linux/Unix 系統中用來讓系統各使用者自行設定在需要的時間 ,做需要的事的程式。
  • crontab 這個指令所設定的工作將會循環的一直進行下去! 除了可以使用指令執行外,亦可編輯 /etc/crontab 來支援。
  • 讓 crontab 可以生效的服務則是 crond 這個服務。
  • 若只需處理僅執行一次就結束排程的指令,可用 at

* 一般 Linux 在開機時會自動載入,如果發現無 crond 在跑,可以到 /etc/rc.d/ 目錄下看看是否有將執行crond 程式的指令加入開機自動執行檔裡面。


* User Name -> crontab file name
  • 當使用者使用 crontab 這個指令來建立工作排程之後,該項工作就會被紀錄到 /var/spool/cron/ 裡面去了,而且是以帳號來作為判別的。
  • 所有使用者的 crontab 檔都會存檔 /usr/spool/cron/crontab/ 下,每個人都只有一個檔案存在,檔名就是該帳號的名字。ex:
    • dmtsai 使用 crontab 後, 他的工作會被紀錄到 /var/spool/cron/dmtsai

[Note] 不要使用 vi 直接編輯該檔案, 因為可能由於輸入語法錯誤,會導致無法執行 cron 。

* cron 執行的每一項工作都會被紀錄到 /var/log/cron 這個登錄檔中。

* Re-start /etc/init.d/crond restar
在 Linux 底下的 crontab 會自動的幫我們每分鐘重新讀取一次 /etc/crontab 的例行工作事項,但是某些原因或者是其他的 Unix 系統中,由於 crontab 是讀到記憶體當中的,所以在你修改完 /etc/crontab 之後,可能並不會馬上執行, 這個時候請重新啟動 crond 這個服務吧!『/etc/init.d/crond restart』。


* syntax:
#crontab [-u username] [-l|-e|-r]

/*
選項與參數:
-u : 只有 root 才能進行這個任務,亦即幫其他使用者建立/移除 crontab 工作排程;
-e : 編輯 crontab 的工作內容
-l  : 查閱 crontab 的工作內容
-r : 移除所有的 crontab 的工作內容,若僅要移除一項,請用 -e 去編輯。
*/


[Note]
  • 如果只是要刪除某個 crontab 的工作項目,那麼請使用 crontab -e 來重新編輯即可!』如果使用 -r 的參數,是會將所有的 crontab 資料內容都刪掉的。
  • 使用者可以用 crontab -e 指令來編寫需要做的工作或者將要執行的工作,或寫在一個 file 裡,再執行 crontab filename 就可以了。
  • 注意必須使用 絕對路徑。

ex:
// 此時會進入 vi 的編輯畫面讓您編輯工作,然後以一個工作一行來編輯,
// 編輯完畢之後輸入『 :wq 』儲存後離開 vi 就可以了。
#crontab -e


* 每項工作 (每行) 的格式都是具有六個欄位,如下:
(minute) (hour) (day of month) (month) (day of week) (job)

* 每欄位可填入的值如下:

  • minute: 0-59
  • hour: 0-23
  • day of month: 1-31
  • month: 1-12 (or names, see below)
  • day of week: 0-7 (0 or 7 is Sun, or use names),週的數字為 0 或 7 時,都代表『星期天』的意思。


ex:
# 每小時的 5,15,25,35,45,55 分
5,15,25,35,45,55 * * * * (job)

# 每個小時 10 分
1 * * * *  (job)

 # 每天早上三點整
0 3 * * * (job)

# 每個月一號早上 3:50
50 3 1 * * (job)

# 每週日早上 4:30
30 4 * * 0 (job)

# 每週六早上 5:30
30 5 * * 6 (job)



* 特殊符號
  • 星號(*)
    • 代表任何時刻都接受。
    • ex: 0 12 * * * (job)
      • 日、月、週都是 * , 就代表著『不論何月、何日的禮拜幾的 12:00 都執行後續指令』的意思。
  • 逗號(,)
    • 代表分隔時段的意思。
    • ex: 0 3,6 * * * command
      • 要下達的工作是 3:00 與 6:00,第二欄是 3,6 ,代表 3 與 6 都適用 。
  • 減號(-)
    • 代表一段時間範圍內。
    • ex: 20 8-12 * * * command
      • 8 點到 12 點之間的每小時的 20 分都進行一項工作,第二欄變成 8-12 ,代表 8,9,10,11,12 都適用的意思。
  • 斜線(/n)
    • n 代表數字,亦即是『每隔 n 單位間隔』。
    • ex: */5 * * * * command
      • 每五分鐘進行一次,也可以寫成 0-59/5 ,相同意思。


[Note]
週與日月不可同時並存,
30 12 11 9 5 root echo "just test" <==這是錯誤的寫法


* 進行登錄檔的輪替 (log rotate):
  • Linux 會主動的將系統所發生的各種資訊都記錄下來,這就是登錄檔。 
  • 由於系統會一直記錄登錄資訊,所以登錄檔將會越來越大。
  • 我們知道大型檔案不但佔容量還會造成讀寫效能的困擾, 因此適時的將登錄檔資料挪一挪,讓舊的資料與新的資料分別存放,則比較可以有效的記錄登錄資訊。這就是 log rotate 的任務!這也是系統必要的例行任務。



* Reference
- 鳥哥的 Linux 私房菜 -- 例行性工作排程的建立 ***
- Crontab 的寫法(@reboot, @yearly...) | Tsung's Blog
- crontab 使用格式說明 **

2011年9月18日 星期日

[WEB] Tile, JSTL, JS syntax in HTML





${status.count}


 colspan="2">



* Tile 的 attribute 在 HTML 中可透過 getAttribute 取得,ex:

<tiles:insertAttribute name="title" />





* 視 js 為 .txt







[SQL] Join

Join 可分兩種:
  • 有關係的 tables,則可使用一般見到的 join ... on ...
  • 沒有關係的 tables,則是

select ...
from TABLENAME1, TABLENAME2
where (condition between TABLENAME1 and TABLENAME2)

[JPA] unidirectional and bi-directional @OneToMany

unidirectional @OneToMany + @JoinColumn


bi-directional @OneToMany(..., mappedBy = "attributeName", orphanRemoval = true)

[Oracle] ORA-00932: 不一致的資料類型

LOB 的資料不應被用來做為 group by 條件或是直接 select 出來

因為此 type 的資料類型太大,會影響效率

在 group by 中也被限制使用 LOB

所以若是 LOB 的屬性,可另成一個物件,

和原本物件便可視為一對一的關係

等到需要時再去取出。

LOB: one-to-one LAZY FECTCH

LAZY FETCH DO not write to toString


[JPA] Fetch type

CriteriaQuery 有設 select 則依 select 的欄位為主,也就是不管屬性是設定什麼,會依所設定的欄位去撈出資料。

否則會去撈回整個物件,但會根據你的 annotation(eager or lazy....),去處理欄位 。

eager: one-to-many 所有關係都撈好才回將物件還給你,並關掉session。

lazy: 等你要去 get 時才去撈。

[Design] Object relationship

假設 A B C 間的關係如下:

A <-> (many-to-one) <-> B <-> (one-to-many) <-> C

但如果按照此關係,設 List在 B 並不符合實務

因為這樣當我們去找 A 相對的 B,B 便會找出其他我們不須要的 A

所以反過來置放。

還有,實際上可看見 A 和 C 沒有直接的對應關係。

[iBatis] query and parameter note


  • parameterClass: 指定輸入參數 type。
  • resultClass: 指定接收執行結果的 type。
  • resultMap: 用 map 對應執行結果到自訂的物件。
  • parameterMap: 輸入參數放在 map 中以對應。


  • QueryForList("SQLMapFileName.SQLId", parameterValue);
  • QueryForObject("SQLMapFileName.SQLId", parameterValue);
    • Using queryForList... directly and write SQL by self
    • Using DAO to do  queryForList...


  • Get simple parameter in SQL: #value#


  • <Statement>: 可以包含任意類型的語句。


* Reference
- 读《IBatis in action 》 总结 - JennieFlying - 博客园

2011年9月17日 星期六

[SQL] OVER, GROUP BY, PARTITION BY

* GROUP BY
是單純的對 query result 做分組。
經常和 aggregate function 一起使用 (AVG(), COUNT()...)

* PARTITION BY
analysis function,是會根據此分組去 query。

* 可見 sum()over() - 闲来之笔 - 博客频道 - CSDN.NET 範例

* OVER
FUNCTION_NAME(<argument>, <argument>...)
OVER
(<Partition-Clause><Order-by-Clause><Windowing Clause>)


* Reference
- oracle 分析函数over
- oracle partition by与group by 的区别 - 郑云飞博客 - ITeye技术网站
- oracle rank,over partition 函数 - Laughing - 博客频道 - CSDN.NET
- sum()over() - 闲来之笔 - 博客频道 - CSDN.NET
- PLSQL中over(partition by .. order by ..)的使用 - Alinaxz的专栏 - 博客频道 - CSDN.NET

[Mobile] 上網符號意義

* 這邊的 G,是由電信相關產業的聯盟所訂立下來的通訊標準。
  • 1G 代表第一世代,代表作是黑金剛手機。
  • 2G 是第二世代,代表作包括 Nokia 6150、3210、Moto小海豚之類的,而手機可以上網,是從 2G 延伸的2.5G (GPRS) 開始,另外還有 2.75G (EDGE)
  • 3G 就是我們目前普遍用來上網的技術,其中又可以分為3G、3.5G、3.75G 以及 3.9G。至於 4G,則包括 WiMAX 以及 LTE 兩項新興技術。


* 2.5G (G)
  • 傳輸速度是最慢的,最快也不過 48k 左右,大概是回到過去用電話撥號上網的時代。


* 2.75G (E)
  • EDGE (E) 傳輸速度最高可到 384kbps,但以目前使用網路的習慣,2G 以及 2.5G 大概只適合用來傳傳純文字的電子郵件。


* 3G: 3G 或是 U
  • 可以上一些簡單的入口網站找資料、看圖片,3G 的出現是真正把通訊網路帶到實用境界的關鍵。又分為:
    • GSM 系統的 WCDMA (UMTS)
    • CDMA 系統的 CDMA2000
  • 台灣多數的電信都是屬於 WCDMA 系統,僅有亞太電信採用 CDMA2000 系統。


* 3.5G、3.75G: H (HSPA 以及 HSUPA)
  • 看看Youtube、聽聽音樂不會容易LAG,有8Mbps 以上的傳輸速度。


* 3.9G 以及 4G: 目前尚不普及的技術

  • 上網速度媲美家裡的寬頻網路。
  • 3.9G 的 WiMAX 與 LTE 也可說是準 4 G,這兩項技術的傳輸速度宣稱未來(也就是現在還達不到標準) 都能達到100Mbps,而 100Mbps 也是電信產業對於 4G 門檻的共識。
  • 到了 4G 以後,最重要的里程碑是讓手機上網與家用上網的速度相差無幾。
  • 雖然國外已經有搭載 WiMAX 與 LTE 技術的手機,不過台灣目前使用的4G 技術是 WiMAX,而系統廠商目前是把 WiMAX 定調用於行動上網,至於 LTE 台灣也還沒真正開通服務,所以短時間內還看不到具備 4G 技術的手機。



* Reference
- 3G, GSM, CDMA, WCDMA, WAP, GPRS...
- 簡單認識一下智慧手機上的標誌代表什麼吧~ | Android中文資源站
- 手机上网信号符号“G”“E”“H”“T”完美解释 - MOTO DEFY(ME525)/DEFY+ 论坛 - 机锋论坛Android安卓手机平板游戏系统应用,主题壁纸铃声下载分享第一社区
- 手机屏幕上方出现H和3G符号是什么意思? - Moto Droid 2/Milestone 2 (A953) - 安卓论坛 安卓论坛-中国最大Android手机交流社区 - Powered by Discuz!

[Velocity] Brief Definition

* Velocity Template Language (VTL)
  • VTL uses references to embed dynamic content in a web site, and a variable is one type of reference.
  • Variables are one type of reference that can refer to something defined in the Java code, or it can get its value from a VTL statement in the web page itself.

Syntax:

##comment


#* comment *#


#directive
    
#end





$variable


#if ( expression)
#end


#foreach($item in $list)
    $item 
#end 


* When an online visitor requests your web page, the Velocity Templating Engine will search through your web page to find all # characters, then determine which mark the beginning of VTL statements, and which of the #characters that have nothing to do with VTL.

* #if
(i) $foo is a boolean (true/false) which has a true value, or
(ii) the value is not null. Remember that the Velocity context only contains Objects, so when we say 'boolean', it will be represented as a Boolean (the class).


* Reference
- Apache User Guide - Contents
- apache velocity介绍及资料: 可下載文件。
- Apache Velocity实现模板化的最简实例 - 玉米疯收 - 博客园: 圖解

[Android] RAM and ROM

[RAM]

* General Definition
  • Random Access Memory,隨機存取記憶體,也就是暫存記憶體,類似DDR。
  • 是與 CPU 直接交換資料的記憶體,也叫主記憶體。
  • 可隨時讀寫,速度快,通常做為 OS 或其他應用程式執行時的暫存位置。


* Android Platform
  • 部份的 RAM 會挪為系統或硬體所使用,不同的硬體所佔用的空間會不同
  • ex: Qualcomm 會佔用的比 TI OAMP(ex: milestone2) 的多。
  • 除非自行刷 ROM,否則這部份幾乎是不可能會被釋放。


[ROM]

* General Definition
  • Read Only Memory,唯讀記憶體,是一種半導體記憶體,類似電腦硬碟。
  • 一旦儲存資料就無法再將資料改變或刪除,且資料也不會因為關閉電源而消失。
  • 在電子或電腦系統中,通常用於儲存不需經常變更的程式或資料。


* Android Platform
  • 在 android 中可分為三部份:
    1. /data: 放一般 end user 所安裝的 apps。
    2. /system: 放 google 或系統廠商所 pre-install 的 apps。
    3. /cache: 系統程式所使用的快取空間。
  • /system 可藉由 root 把 pre-install 的 apk 移除到別的地方,來釋放空間。
  • 而 /data and /cache 受硬體限制,除非自行刷 ROM,再用指令重新分配空間。


[Overview]
大略的說,RAM 用來執行程式,ROM 用來儲存。


* 可觀看 android 系統資訊的 app



* Reference
- Mobile01 如何觀看Android手機的可用RAM與ROM大小 **
- 可以不要再把RAM跟ROM 傻傻分不清楚了! - Mobile01

[AndroidDev] Process and Thread

[Process]
* 如果 application 在沒有任何 component 被執行中的情況下開啟,則會開啟新的 process 執行單一執行緒;若是已有被執行中的 component,則會在相同的 process and thread 執行你所要執行的功能。
  • When an application component starts and the application does not have any other components running, the Android system starts a new Linux process for the application with a single thread of execution.
  • By default, all components of the same application run in the same process and thread (called the "main" thread).
  • If an application component starts and there already exists a process for that application (because another component from the application exists), then the component is started within that process and uses the same thread of execution.
* However, you can arrange for different components in your application to run in separate processes, and you can create additional threads for any process.
  • <activity>, <service>, <receiver>, and 中可利用 android:process 屬性來指定其 component 要跑在那個 process 上。
  • <application> 也能利用 android:process 去設定所有 components 的預設值。
  • By default, all components of the same application run in the same process and most applications should not change this.
* Process Types
To determine which processes to keep and which to kill, the system places each process into an "importance hierarchy" based on the components running in the process and the state of those components.
  1. Foreground process: user 正在執行中的 process。ex:
    • User 正在使用的 activity (activity is onResume())。
    • User 正在使用的 activity 所使用的 service
    • The Service has called startForeground().
    • A Service that's executing one of its lifecycle callbacks (onCreate(), onStart(), or onDestroy()).
    • A BroadcastReceiver that's executing its onReceive() method.
  2. Visible process: A process that doesn't have any foreground components, but still can affect what the user sees on screen. ex:
    • An Activity that is not in the foreground, but is still visible to the user (its onPause() method has been called). This might occur, for example, if the foreground activity started a dialog, which allows the previous activity to be seen behind it.
    • A Service that's bound to a visible (or foreground) activity.
  3. Service process: A process that is running a service that has been started with the startService() method and does not fall into either of the two higher categories.
  4. Background process: A process holding an activity that's not currently visible to the user (the activity's onStop() method has been called). These processes have no direct impact on the user experience.
    • Usually there are many background processes running, so they are kept in an LRU (least recently used) list to ensure that the process with the activity that was most recently seen by the user is the last to be killed. 
    • If an activity implements its lifecycle methods correctly, and saves its current state, killing its process will not have a visible effect on the user experience, because when the user navigates back to the activity, the activity restores all of its visible state.
  5. Empty process: A process that doesn't hold any active application components. The only reason to keep this kind of process alive is for caching purposes, to improve startup time the next time a component needs to run in it.
    • A process running a service is ranked higher than a process with background activities.


[Thread]


* Main/UI Thread
  • When an application is launched, the system creates a thread of execution for the application, called "main."
  • It is in charge of dispatching events to the appropriate user interface widgets, including drawing events.
  • The thread in which your application interacts with components from the Android UI toolkit (components from the android.widget and android.view packages).
  • By default, the system does not create a separate thread for each instance of a component. All components that run in the same process are instantiated in the UI thread, and system calls to each component are dispatched from that thread.
  • If the UI thread is blocked for more than a few seconds (about 5 seconds currently) the user is presented with the infamous "application not responding" (ANR) dialog.
  • Is not thread-safe.


* Worker/Background Thread
  • If you have operations to perform that are not instantaneous, you should make sure to do them in separate threads ("background" or "worker" threads).
  • Do not access the Android UI toolkit from outside the UI thread.
  • Android offers several ways to access the UI thread from other threads. ex:
// about Thread
new Thread(new Runnable() {
    Activity.runOnUiThread(Runnable)
}
View.post(Runnable)
View.postDelayed(Runnable, long)

// http://developer.android.com/reference/android/os/AsyncTask.html
public abstract class AsyncTask

// http://developer.android.com/reference/android/os/Handler.html
public class Handler

Using example:
new Thread(new Runnable() {
        public void run() {
            final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
            mImageView.post(new Runnable() {
                public void run() {
                    mImageView.setImageBitmap(bitmap);
                }
            });
        }
    }).start();


* AsyncTask
You can then run the task by calling execute() from the UI thread.
public void onClick(View v) {
    new DownloadImageTask().execute("http://example.com/image.png");
}

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    /** The system calls this to perform work in a worker thread and
      * delivers it the parameters given to AsyncTask.execute() */
    protected Bitmap doInBackground(String... urls) {
        return loadImageFromNetwork(urls[0]);
    }
    
    /** The system calls this to perform work in the UI thread and delivers
      * the result from doInBackground() */
    protected void onPostExecute(Bitmap result) {
        mImageView.setImageBitmap(result);
    }
}


  • The method doInBackground() executes automatically on a worker thread.
  • onPreExecute(), onPostExecute(), and onProgressUpdate() are all invoked on the UI thread
  • You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the UI thread.


* Another problem you might encounter when using a worker thread is unexpected restarts in your activity due to a runtime configuration change (such as when the user changes the screen orientation), which may destroy your worker thread.


[Thread-safe methods]

* Service
  • When a call on a method implemented in an IBinder originates in the same process in which the IBinder is running, the method is executed in the caller's thread.
  • Because a service can have more than one client, more than one pool thread can engage the same IBinder method at the same time. IBinder methods must, therefore, be implemented to be thread-safe.


* Content Provider
  • A content provider can receive data requests that originate in other processes.
  • Although the ContentResolver and ContentProvider classes hide the details of how the interprocess communication is managed, ContentProvider methods that respond to those requests—the methods query(), insert(), delete(), update(), and getType()—are called from a pool of threads in the content provider's process, not the UI thread for the process. Because these methods might be called from any number of threads at the same time, they too must be implemented to be thread-safe.

* These are the another issue need be explored.


* Reference
- Processes and Threads | Android Developers

2011年9月15日 星期四

[JPA] Using @IdClass to represent multiple @Id

當物件必須要有多個欄位才能表示其 primary key 時

則需要使用 @IdClass 指明其 primary key class

public class ObjectPrimaryKey implements Serializable  {
    // 宣告 @Id 的欄位為屬性
    private String attributeId1 = null;

    // CONSTRUCTORS
    public ObjectPrimaryKey () {  super();  }

    // SETTER AND GETTER of attributes

   // Override equals(), toString() and hashCode()
}


然後在 Object 上指明其 primary key class
@IdClass(AppDownloadTimesPrimaryKey.class)
public class Object {
    // 在所有做為 primary key 之一的 attributes 要記得加上 @Id annotation
}

2011年9月14日 星期三

[JPA] @NamedQueries and NamedQuery

可以在 EntityA 中利用 @NamedQuery 定義簡單的 query 語句
@NamedQueries({
     @NamedQuery(name = "EntityA.test", query = "from TABLE o where o.FIELD = :variable")
     // ....可多個 @NamedQuery
})
public class EntityA extends DomainEntity {
    // query 語句中需要代入的變數,用冒號做前置符號
    public static final String ATTRIBUTE_VARIABLE = "variable";
    // NamedQuery 的名稱
    public static final String NAMED_QUERY_TEST = "Entity.test";

}

然後便可在 service 中使用此 NamedQuery
// find: 取回的結果有多筆時使用
public List findEntityA (String variable)  {
    return find(EntityA.NAMED_QUERY_TEST, EntityA.ATTRIBUTE_VARIABLE, "vaiableValue");
}

// getSingleResult: 只會取回一筆結果時
public EntityA findEntityA (String variable)  {
    return getSingleResult(EntityA.NAMED_QUERY_TEST, EntityA.ATTRIBUTE_VARIABLE, "vaiableValue");
}

若 SQL 中有多個變數時,可用 Map,ex:
Map parameters = new HashMap();
parameters.put(ATTRIBUTE1, VALUE1);
parameters.put(ATTRIBUTE2, VALUE2);
find(EntityA.NAMED_QUERY_TEST, parameters);


* Reference
- find

[Android] Android Framework

Android Framework



* Reference
- Multiple phone web-based application framework
- Android 開發教學筆記 - 使用 PhoneGap、jQuery Mobile 與台北市政府開放資料(Open Data)

[JPA] fail-safe cleanup (collections)

Error Message

main WARN org.hibernate.engine.loading.LoadContexts.cleanup(LoadContexts.java:132) - fail-safe cleanup (collections) : org.hibernate.engine.loading.CollectionLoadContext@c74fe
[2011-09-13 21:47:13,492] main WARN org.hibernate.engine.loading.CollectionLoadContext.cleanup(CollectionLoadContext.java:348) - On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [1] entries



Solution

目前查到所解的大部份是說這是 hibernate 的 bug,可以忽略或是改使用 3.x.x 以上的版本即可

但目前所使用的便是 3.x.x 的版本,而且查看結果,不如預期!

[JPA] Repeated column in mapping for entity

Error Message

Invocation of init method failed;
nested exception is org.hibernate.MappingException:
Repeated column in mapping for entity: com.justinmobile.lticket.domain.EcUserConsInfo column


Solution

在欄位的對應上 指定了重複的欄位而產生此 exception

在表單顯示資料時 便已撈出物件

當頁面上的資訊被修改 其實DB裡的資料也已被修改

只是還未submit 所以當對應了重複的欄位時

會讓系統不知道該更新那裡的資訊

可以加上 insertable = false, updatable = false 來修正此問題

ex:

@JoinColumn(name = "FIELD_NAME", referencedColumnName = "FIELD_NAME", insertable = false, updatable = false)

[JPA] no appropriate constructor in class

Error Message


main ERROR org.hibernate.hql.ast.ErrorCounter.reportError(ErrorCounter.java:56) - Unable to locate appropriate constructor on class
[cause=org.hibernate.PropertyNotFoundException: no appropriate constructor in class:



Solution

使用 criteriaQuery.select 時,它使用的是預設 constructor

使用 criteriaQuery.multiselect 時,則得依據你所要 select 的欄位新增 constructor

ex:

criteriaQuery.multiselect(root.get(Object_x), root.get(Object_y))

// 則在 Object 中應該要有以下的 constructor

public Object(Type x, Type y) {
    this.x = x;
    this.y = y;
}



[JPA] org.hibernate.AnnotationException: Illegal attempt to map a non collection

Error Message

Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements:



Solution

若是屬性的 annotation 有一方中是 many 的關係,則在 metamodel 中需寫成:

ListAttribute<Object1, Object2> attributes;

[Weblogic] Domain and Managed

weblogic 分為兩部份

  1. Domain
  2. Managed

然後 Domain 會管理 Managed

每個 Managed 有一個 JVM

若一個 Domain 中有的三個 Managed

則表示管理四個 (再加 Admin)

[Oracle] ORA-00979: 不是一個 GROUP BY 表示式

Error Message

ORA-00979: 不是一個 GROUP BY 表示式



Solution

select 出來的欄位要和 group by 的欄位一樣



* Reference
- ORA-00979: 不是 GROUP BY 表达式 的原因 - zsgzs的个人主页 - ITeye技术网站
- select *from emp group by deptno;这个语句是不是group by 语句 - 黑马程序员第3届交流区 - 中关村黑马程序员训练营论坛 - Android培训,Java培训,3G培训,就业后,才还款!
- hibernate 查询部分字段时异常:[cause=org.hibernate.PropertyNotFoundException: no appropriate co_功夫熊猫_新浪博客

2011年9月13日 星期二

[AndroidDialog] The ways to show dialog

可用以下幾方式呈現出 dialog:

  • Toast
  • AlertDialog
  • Dialog
  • Activity (設置背景圖片為透明,只保留中間顏色,模擬成 dialog 樣式)


* Reference
- andriod 自定义对话框(不含边框和标题)_sunboy_2050的空间_百度空间

[Oracle] SYS_CONNECT_BY_PATH


  • SYS_CONNECT_BY_PATH is valid only in hierarchical queries.
  • Provided from oracle9i.
  • It returns the path of a column value from root to node, with column values separated by char for each row returned by CONNECT BY condition.
  • Both column and char can be any of the datatypes CHAR, VARCHAR2, NCHAR, or NVARCHAR2.
  • The string returned is of VARCHAR2 datatype and is in the same character set as column.


* 在 Oracle 中,rownum 會比 group by、order by更先執行,因此要用子查詢。

select xxx from (select xxx from xxx order by xxx) where rownum<=xx


* Reference
- SYS_CONNECT_BY_PATH
- Rownum搭配Order by - 馬小玲傳說- 點部落
- SYS_CONNECT_BY_PATH函数用法 ORACLE - XZC.Log - BlogJava

[Database] SQL note

一般而言,資料庫的語法 ( SQL ) 分為三大類別:

1. DDL ( Data Definition Language ):定義資料庫物件使用的語法,常看到的關鍵字有:

  • Create:建立資料庫的物件。
  • Alter:變更資料庫的物件。
  • Drop:刪除資料庫的物件。

2. DCL ( Data Control Language ):控制資料庫物件使用狀況的語法,常看到的關鍵字有:

  • Grant:賦予使用者使用物件的權限。
  • Revoke:取消使用者使用物件的權限。
  • Commit:Transaction 正常作業完成。
  • Rollback:Transaction 作業異常,異動的資料回復到 Transaction 開始的狀態。

3. DML ( Data Manipulation Language ):維護資料庫資料內容的語法,常看到的關鍵字有:

  • Insert:新增資料到 Table 中。
  • Update:更改 Table 中的資料。
  • Delete:刪除 Table 中的資料。
  • Select:選取資料庫中的資料。


* 沒有指定WHERE,則所有紀錄都會被更動,請注意小心使用!!


* Reference
- SQL語法

[Oracle] Hierarchical Queries

CONNECT BY [NOCYCLE] [condition] START WITH [condition]

(or)

START WITH [condition1] CONNECT BY [condition2]

SELECT *
FROM PERSON p
CONNECT BY  p.name = PRIOR p.ID
START WITH p.ID = 0


* CONNECT BY
  • Specifies the relationship between parent rows and child rows of the hierarchy.
  • 指定 Hierarchical Queries 中 parent rows and child rows 之間的關係,當前資料會與對應的 parent rows 做比較。
  • One expression in condition must be qualified with the PRIOR operator to refer to the parent row
  • condition 中必須有一個 PRIOR,且不能包含子查詢。
  • CONNECT_BY_ISLEAF


* START WITH
  • Specifies the root row(s) of the hierarchy.
  • 指定 Hierarchical Queries 的 root (一筆或多筆),所有滿足 condition 的會被當作是 root rows。
  • 可以省略,但若沒有指定給 root,則所有資料都會被當成 root,分別掃瞄。
  • condition 可以是一個子查詢。


* PRIOR
  • 指定 parent rows。
  • Is most commonly used when comparing column values with the equality operator.
  • ex: p.name = PRIOR p.ID,表示 id of prior row = name of current name。
  • prior 放在子節點端,表示是以 START WITH 指定的節點做為跟節點,由上往下掃瞄,可能對一個或多個分支。
  • prior 放在父節點端,表示是以 START WITH 指定的節點做為最低層子節點,從下往上掃瞄,直到根節點為只,這種情況只能得到一個分支。


* LEVEL
  • Level of root row is 1,所以其 child rows 的 LEVEL = 2。


* SQL 執行順序
  1. JOIN,無論是 JOIN ON 還是在 WHERE 中做的關連
  2. CONNECT BY
  3. 其它的WHERE條件



* Reference
- Oracle Connect By
- The Oracle PL/SQL PRIOR Operator
- Hierarchical Queries
- 【原】Oracle开发专题之:级联查询(Hierarchical Queries) - pengpenglin - BlogJava
- Oracle Handbook系列之一:结构化查询(Hierarchical Queries) - SnowToday - 博客园
- oracle树中prior的用法 - space6212的个人空间 - ITPUB个人空间 - powered by X-Space

2011年9月12日 星期一

[Glossary] CDMA, RUIM

* CDMA
  • Code Division Multiple Access,意思是「分碼多重進接」通信技術。
  • 在美國最為普及,但在亞洲如日本、韓國、中國、香港、台灣等地亦被廣泛採用。
  • 在台灣,採用 CDMA 技術的電信公司就是亞太電信
  • 優點:
    • 採用了先進的擴頻技術,使通信背景噪音大大降低,讓其通話品質可以和固定式電話相媲美。
    • 意味著注重環保與節能。
      • 因為 CDMA 系統的發射功率最高只有 200mW ,所以採用 CDMA 系統的手機輻射量只有 GSM 系統的千分之一,對環境影響較小。
    • 通話不易被竊聽、上網速度快等特性。


* RUIM
  • Removable User Identity Module
  • 簡單的說就是「CDMA 的 SIM 卡」。
  • 其實 SIM 卡(Subscriber Identity Module)只能用在 GSM 系統的情況下,因為並非所有的這種手機電話號碼身分卡都叫做 SIM 卡。


* 從韓國引進 CDMA 技術的亞太電信,在早年時也如同美、日、韓一樣採用機卡合一的方式。後來由於中國電信廠商皆採用機卡分離方式以支援雙模手機,所以後來亞太也開始改用機卡分離的手機。所以有一陣子亞太曾經同時機卡合一與機卡分離兩種方式並行,後來才隨著時間過去,讓早年的機卡合一機種漸漸自然淘汰。



* Reference
- FrostyPlace.com > CDMA 小常識

[Java] toString()

  • 主要是讓平凡人可以讀到某些有意義的資訊,而這些資訊是有關你的類別的物件時,此時就會複寫掉toString( )。
  • 其他程式碼可呼叫你的物件的toString()來取得某些關於你的物件的有用細節。
  • 當我們使用Sysout.our.println( 物件 ),其實就是印出物件的toString()的回傳值而已。
  • 預設其實是印出16進制的HashCode碼。


* Reference
- toString()

[maven] build command

  • mvn [clean] package
  • mvn -o [clean] package
    • Offline Build.
  • mvn -Dbuild.stage=staging clean package
  • mvn -Dmaven.test.skip=false package
    • enable the unit testing.
  • mvn -Dmaven.test.skip=false test
    • testing only.
  • mvn -Dmaven.test.skip=true -Dbuild.stage=staging clean package

[Android] export android project 為 jar 檔

* steps:
  1. Remove mainfest.xml and res/*.
  2. eclipse -> export -> JAVA -> JAR file
  3. "Select the resources to export:" 下的項目皆不選 (ex: .classpath, .project, AndroidManifest.xml, default.properties, res, assets)
  4. "Next"
  5. "Finish"
---
Update on 20111106

* Cannot include AndroidManifest.xml or you will get this exception.

Error generating final archive: Found duplicate file for APK: AndroidManifest.xml
Origin 1: (#project path)\bin\resources.ap_
Origin 2: (#store JAR path)\Test.jar


* Or include the duplicate res will get this exception.

include res may duplicate with user


Error generating final archive: Found duplicate file for APK: res/layout/main.xml
Origin 1: (#project path)\bin\resources.ap_
Origin 2: (#store JAR path)\Test.jar


* Test including strings.xml

  • If include strings.xml in Jar
    • It won't be compiler and keep in Main Project apk.
    • Main Project cannot find the string resource id that belong to Jar or get the string in Main Project that resource id is equal to.
    • If try to access it will get exception:
      • Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x7f040002
  • If using open project to be library
    • strings.xml will compiler with Main Project and export.
    • So could get the string in library by JAR's namespace.



* Reference
- Android如何将程序打成jar包 | 第三极 | 移动开发者
- web_surf - ChinaUnix博客 - IT人与你分享快乐生活
- android中生成和使用jar 分享 - 黑暗任务 - ITeye技术网站 **

[J2EE] getParameter and getAttribute

* getParameter()
  • 資料會從 web client 傳到 web server,表示 HTTP 請求數據,get/post 的參數(For HTTP servlets, parameters are contained in the query string or posted form data. )。
  • app server 在分析你送上來的 request 頁面內容時,取得你設在表單或 URL 重定向時的值。
  • 只能接受 String。
  • ex: A.jsp 連到 B.jsp 時,B.jsp 可以透過 getParameter() 獲得請求參數。


* getAttribute()
  • 資料只會存在 web container,在具有轉發關係的 web 組件間共享,用來接受來自 servlet 的變數或 action,主要資料來至於server conainer 的記憶體,透過兩個方式設定:
  • container 自動加上去的一些 自訂request 資訊(javax.servlet.request.X509Certificate 等)。
  • setAttribute是 app server 把 object 放在該頁面所對應的空間,當頁面被 forward 到另一個頁面時, app server 會把這個空間的資訊複製到另一頁面所對應的空間中,所以getAttribute就能取得之前所設下的值。
  • 接受 type 是 Object。
  • 屬於 class HttpServletRequest。
  • ex: A.jsp forwaed到 B.jsp 時,可在 A.jsp 中先 setAttribute(),在 B.jsp 便可由 getAttribute 取得。


* Overview
  • 所以當使用get/post資料時,應該是用getParameter 而非 getAttribute ,若要在request (像是session)分享資訊(含Object),可以用getAttribute ,若要在兩個page 之間,理當要forward 才可以用getAttribute 共享,不然scope已經超過了..
  • ActionForm若僅只是要給forward使用的變數 , 可以用set/get Attribute 而少用session(效能)



* Reference
- request.getAttribute()和request.getParameter()的区别 - Java / Java EE
- JWorld@TW Java論壇 - Re:request的getParameter和getAttribute
- request.getAttribute()与request.getParameter() 方法区别_Struts_Java中文网
- request.getParameter和request.getAttribute之间的区别 - LL_java - 博客园

[Android] AlarmManager

* AlarmManager

  • 主要維護 app 所註冊的鬧鐘(在系统中,linux實現的設備名為”/dev/alarm”)。會一直監視著鬧鐘設備,一旦有鬧鐘處發或是鬧鐘事件發生,AlarmManagerServie就會從鬧鐘列表中找尋對應的鬧鐘並發出廣播。
  • 系統啟動時,system_service啟動並初始化 /dev/alarm。
  • 在 JAVA 層的AlarmManagerService與Linux Alarm驅動程序接口之間還是有一層封裝,那就是JNI
  • AlarmManager 與 AlarmManagerServie之間是通過Binder來通信的,他們之間是多對一(?)的關系。


* 鬧鐘類型

  • public static final int ELAPSED_REALTIME
    • 當系統進入睡眠狀態時不會喚醒系統,直到系统下次被唤醒才會傳遞此訊息
    • 所用的時間是相對時間,是從系统啟動後開始計算的,包括睡眠時間,可以通過 SystemClock.elapsedRealtime() 取得。
  • public static final int ELAPSED_REALTIME_WAKEUP
    • 當系統進入睡眠狀態時能唤醒系统,ex: 透過聲音、振動。
  • public static final int RTC
    • 當系统進入睡眠狀態時,不會喚醒系統,直到系统下次被唤醒才會傳遞此訊息。
    • 所用的時間是絕對時間,UTC 時間,可以通過 System.currentTimeMillis() 取得。
  • public static final int RTC_WAKEUP
    • 會唤醒此系統,傳遞此訊息。
  • Public static final int POWER_OFF_WAKEUP
    • 會喚醒系統,在裝置關機的狀態下也可以喚醒系統,同RTC類型。

Related
[API] Alarm

* Reference
- 深入学习android之AlarmManager - Java-Jinguo - ITeye技术网站
- 8.3.5 全局定时器AlarmManager(1) - 51CTO.COM

[Android] dismiss and cancel dialog

* dismiss()
- thread-safe.

* cancel()
- triggered by "back"。
- 注意! 此動作不只會觸發onCancelListener也會觸發onDismissListener。


* Reference
- dialog.dismiss()和dialog.cancel()有什么区别分别用在什么场合
- Android 问题&解答 - eoe·Android开发者门户 - Powered by Discuz!

- Android学习笔记--创建Dialog_云开雾散_百度空间

2011年9月11日 星期日

[iBatis] SQL Map

* 使用SQL Map優點:
  • 能夠大大減少訪問關係數據庫的代碼。
  • 使用簡單的XML配置文件將Java Bean映射成SQL語句,對比其他的數據庫持續層和ORM框架(如JDO的實現,Hibernate等),SQL Map最大的優點在於它簡單易學
  • 要使用SQL Map,只要熟悉Java Bean,XML和SQL,就能使您充分發揮SQL語句的能力。


* SQL Map的概念:
  • SQL Map API讓開發人員可以輕易地將Java Bean映射成PreparedStatement的輸入參數和ResultSet結果集。
  • 開發SQL Map的想法很簡單:提供一個簡潔的架構,能夠用20%的代碼實現80%JDBC的功能。


* SQL Map如何工作?
  • SQL Map提供了一個簡潔的框架,使用簡單的XML描述文件將Java Bean,Map實現和基本數據類型的包裝類(String,Integer等)映射成JDBC的PreparedStatement。


* 以下流程描述了SQL Maps的高層生命週期:


將一個對象作為參數(對象可以是Java Bean,Map實現和基本類型的包裝類),參數對象將為SQL修改語句和查詢語句設定參數值。

  1. 執行mapped statement。這是SQL Maps最重要的步驟。 SQL Map框架將創建一個PreparedStatement實例,用參數對象為PreparedStatement實例設定參數,執行PreparedStatement並從ResultSet中創建結果對象。
  2. 執行SQL的更新數據語句時,返回受影響的數據行數。執行查詢語句時,將返回一個結果對像或對象的集合。和參數對像一樣,結果對象可以是Java Bean,Map實現和基本數據類型的包裝類。



* Reference
- iBATIS SQL Map (1)_StackDoc

[Database] Index

索引是提高資料查詢的最有效方法。

索引的管理成本:
  1. 存儲索引的磁碟空間
  2. 執行資料修改操作(insert、update、delete)產生的索引維護
  3. 在資料處理時會需額外的回退空間。


建索引之後,資料修改時間會延長。


* Reference
- 索引是提高資料查詢的最有效方法(轉) @ oracle園地 :: 痞客邦 PIXNET ::

[Oracle] TableSpace

* Definition
是Oracle空間管理上的邏輯單位,實體上存放資料的是Tablespace裡面的檔案(Data File);而我們所熟悉的Table就放在這 一個一個的檔案裡面。
所以TableSpace可以看成是Data File的群組,是一對多的關係。


* 通常在管理上會把使用者的資料與Oracle系統的物件以不同的Tablespace做切分 。如果一個Oracle上有多個不同的AP系統,以不同的TableSpace做切割,則可以達到管理與備份的目的。但是TableSpace的功用也不僅僅只是簡單的群組分類而已,Oracle 提供了許多功能上的參數來設定TableSpace來達到空間管理與效能增進的目的。

* 有必要提的是,TableSpace沒辦法跨資料庫,TableSpace中的Data File沒辦法跨TableSpace,Data File中的Table (Segement)可以跨 Data File,但不能跨TableSpace。
簡單的來說,一個Table裡面的資料是有可能因為Oracle的空間分配而分布在同一個TableSpace的 不同的Data File中的;因此一個Data File創出來後,是不能隨便刪除的,這將會造成嚴重的資料損毀的問題。


* SYSTEM與Non-SYSTEM TableSpace
當資料庫剛建立起來,系統會建立一個叫做SYSTEM的系統TableSpace,存放SYS、SYSTEM等User重要的系統資料(ex:資料字典與預儲程序等) 如果我們建立Oracle User時,不指定預設的TableSpace,則此User則會以SYSTEM TableSpace作為預設的TableSpace。 這將造成管理上的混亂與嚴重的效能問題,這是必須特別注意的。


* 傳統的Oracle管理概念中,傾向一個tablespace中創建多個data file,特別是在多個儲存位置時,以分散 I/O,但10g後推出了BigFile Tablespace。



* Reference
- TableSpace介紹
- Oracle Bigfile Tablespace大文件表空间 - 求道的路上 - ITPUB个人空间 - powered by X-Space

[Android] Intent and PendingIntent

[Intent]
  • 是即時的,隨著其所在的 activity 消失而消失。
  • 提供 component 互相調用時的所需資訊,算是 caller 和 callee 間的橋樑 (?)。


[PendingIntent]
  • 用於處理即將發生的事,例如在 notificationManager 跳轉頁面,但不是馬上跳轉。
  • 包含了 Intent 的描述又是 Intent 行為的執行,如果將 Intent 比作成一個訂單的話,PendingIntent 像是一個下訂單的人,因为它既要負責將訂單發出去,也要負責訂單發送的處理,比如發送成功後要準備驗收訂定貨物,發送失敗後要重發送或是取消訂單等操作。
  • 主要包含的內容是要執行的 intent 和當時 component 的 context,可以看做是對 intent 再做包裝的結果。
  • 當前的 activity 並不能馬上使用 pendingIntent 所包含的 intent,而是在外部執行 pendingIntent 時,才去使用其中的intent,可以脫離 app 而存在。
  • 有就是 pendingIntent 中會保存前個 context of component (ex: A),讓後來調用的此 pendingIntent 的 component (ex: B),可以如在 A 中執行的使用此 pendingIntent 中的 intent,所以即使 A 已不存在,還是能透過保存在 pendingIntent 中的 context 執行 intent。
  • 可透過getActivity(), getBroadcast(), getService() 得到。
  • ex: 常使用在 alertManager and notificationManager。



* Reference
- Intent和PendingIntent的区别详细分析 | 无锋网
- 深入学习android之AlarmManager - Java-Jinguo - ITeye技术网站
- Android Intent学习 | 好你 - 你好,Google Android 2.2学习笔记

[Java] Static variable

電腦的記憶體在執行程式時, 會被分成三區: permanent, stack 和 heap。
  • permanent: 變數會一直活到程式執行完。
  • stack:
    • 變數則是在{}執行完就被移除。
    • ex: 用來存放function return address和function的local variables(包括參數)及保存暫存器值的記憶體空間。
    • ex: local variable既然在{}外的程式都看不到他, 很自然的選則就是在離開{}後就把他清掉, 好節省記憶體。
  • heap: 程式中動態配置記憶體所用的記憶體空間。


BSS(block storage segment): 用來存放程式中未初始化的全域變數的空間。
Data Segment: 用來存放已初始化的全域變數。
Text Segment: 用來存放程式碼(固定不變的部分)。

Data Segment and Text Segment 兩塊記憶體大小在程式執行前就固定了。

Static Variable
  • 在執行程式其間,此變數是共享的,所以可以節省系統空間與共享資源。
  • 生命周期較長,而且不易被系统回收,因此如果不能合理地使用Static Variable,就會是反效果,造成大量的空間浪費。
  • 因此,建議在符合以下所有條件時,才考慮使用Static Variable:
    • 會占用較多的空間。
    • 生命週期較長。
    • 所包含的數據穩定。
    • 有共享需求。



* Reference
- 程式記憶體位址的配置 - 程式專欄 - Yahoo!奇摩部落格
- java static静态变量 - - ITeye技术网站

2011年9月10日 星期六

[Javascript] note

* javascript no overloading


* js action in href

<a href="javascript:function()">....


[JPA] note

* java -> JPA -> hibernate

[Metamodel]
* 用處: select 時讓 JPA 知道attribute type 否則會將 attribute 視為string,ex:
  • 有 metamodel
    • root.get(EntityMetamodel_.attribute)
  • 沒有 metamodel
    • 若沒有寫在metamodel,則可在 root.get 地方寫成 root.<String>get("attribute")
    • 如果 type 是 string 可不轉,不過建議還是轉,以知道其type。

* Must
- 若 join table 時使用到 JoinPath 則一定要有 metamodel。


[Annotation]
* Transient : 不在table field的 attribute


[Java] Java doc

{@link Object#attribute}: Object.attribute

2011年9月5日 星期一

[Lifecycle] Activity Lifecycle


應用程式中所使用的 activity 會被堆疊在 stack 中 (task?)。

畫面上的呈現與 activity 狀態對應如下:
  • running <-> visible and get focus
    • 正在運行的 activity 便是 stack 最上面的那個 activity,會顯示在畫面上的。
  • onPause <-> visible but lost focus
    • 在畫面上仍是可見的,但已失去焦點。
    • ex: 最上的 activity 畫面獲得焦點且是可看見背景的,那麼原本的 activity ,即使是 onPause 也仍存活著,保持自己的狀態與訊息,仍然與 window manager 保持連接,但有可能會被系統殺掉。
  • onStop <-> non-visible and lost focus
    • 在畫面上已被其他 activity 完全擋住兒而不可見的,仍保有自己的狀態與資訊,但 window manager 已不再管理其訊息,系統資源不夠時會被殺掉。


當 activity is onPause or onStop,系統則可以清楚它,可能提示 user 是否結束或只是殺掉其 process。




* 當Progress Dialog啟動時Activity模糊化(blur)進入OnPause()狀態, 並以執行緒(Thread)模擬事件進度.



* Reference
- Android activity 堆栈(1) - 嘴嘴的小的日志 - 网易博客
- tsots的Android範例Source: ProgressDialog~ProgressBar~搭配Handler顯示執行進度

2011年9月4日 星期日

[Android] INSTALL_FAILED_INSUFFICIENT_STORAGE error

* Error
- message:
Installation error: INSTALL_FAILED_INSUFFICIENT_STORAGE
Please check logcat output for more details. 
Launch canceled!
- It happens regardless of app size, or how much storage is available.


* Solution
  1. 先移除再重新安裝,可解決,但可能還是會再發生相同問題。
  2. If your test device is running Android 2.2 or later then add the android:installLocation attribute to your application's manifest file, with the value "preferExternal". This will force the app to be installed on the device's external storage, such as a phone's SD card.
  3. assets內過大的資源放在(載到)SD card,再重SD card 讀取。
  4. process internal memory default is 16M,可改變 RUNTIME_HEAP_MAX 的大小:
// 尚未試過以下這方法
#ifdef CUSTOM_RUNTIME_HEAP_MAX
#define __make_max_heap_opt(val) #val
#define _make_max_heap_opt(val) "-Xmx" __make_max_heap_opt(val)
opt.optionString = _make_max_heap_opt(CUSTOM_RUNTIME_HEAP_MAX);
#undef __make_max_heap_opt
#undef _make_max_heap_opt
#else
/* limit memory use to 16MB */
opt.optionString = "-Xmx16m";
#endif
mOptions.add(opt);


* Reference
- Solution: Android INSTALL_FAILED_INSUFFICIENT_STORAGE error - Stack Overflow *
- Installation error: INSTALL_FAILED_INSUFFICIENT_STORAGE - Android 问题&解答 - eoe·Android开发者门户 - Powered by Discuz!

API Release Version

[Java]
  • for each
    • from 1.5
  • @Override
    • from 1.5
    • 但在 1.5 不支援 interface 使用,因此必須使用 1.6。
    • 20120615
      • 1.7 也無支援

[JSP]
  • EL
    • from 2.0


* Reference
- 关于解决Java @Override的问题


2011年9月3日 星期六

[Web] CDATA

* 原本要在 xml 中使用特殊字元時,則必須寫成 &lt;、&gt;、、等,否則 xml 分析會出錯。


CDATA 區段提供了一種通知剖析器的方法,說明 CDATA 區段所包含的字元沒有標記。 寫法如下:


<![CDATA[  >   ]]>


* 也就是說在 CDATA 中的字元不會被解析。




* Reference
- CDATA 區段 - XML 標準

[Android] ANDROID_ID

* Definition
- A 64-bit number (as a hex string) that is randomly generated on the device's first boot and should remain constant for the lifetime of the device. (The value may change if a factory reset is performed on the device.)
- 第一次啟動 Android 設備時隨機生成的64位數(以十六進制字符串表示), "應在"保持設備一生不變的. (當設備執行重置出廠值時, 該值可能改變.)

* from level 3

* How to get?
- Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
- but you will get "null" on emulator.

* Is it unique for each Device?


Update on 20111106
  • 透過設定中的選項恢復原廠設定後,ANDROID_ID 仍是相同。
  • 若是更新系統,是否仍會相同?
  • 重新刷ROM的話,是否仍會相同?


* Reference
- Settings.Secure | Android Developers
- 獲取 Android 設備的 ID,Settings.Secure.ANDROID_ID

[Design] Design Software

軟體開發不是光靠程式設計 | 專欄 | iThome online

* Coding只是開發過程中的一部份工作
把程式設計等同於軟體開發,當然是很大的誤解。除了程式設計之外,軟體開發中涉及更多的層面。而其中,是否擁有正確的軟體開發觀念,絕對影響到是否能更順利地開發出有品質的軟體。

* 你會需要有這麼一個版本讓所有的人(包括客戶、使用者、產品經理、出錢的大老闆)清楚看到一個可以運作的系統,他們會對系統應該要是什麼樣的面貌更有概念,才更知道軟體功能該如何調整。

* 許多有經驗的開發者會知道,可以設定一個遠大的目標,但是,要先做出一個功能不那麼強、但是足夠穩定、能夠正常運作的第一個版本,接著再以這個版本為基礎,持續地演化及改進。

* 在開發的時候,要讓需求、規格盡量保持不變,甚至在時間有限時、而期限又不允許更動時,還要適度將那些較不優先的功能自開發範圍中削除

[Database] CLOB and BLOB

[CLOB]
- Character Large OBject。
- 用於儲存大量的文字資料。


[BLOB]
- Binary Large Object。
- 用於儲存大量的二進位資料。


* Reference
- Java Gossip: 將檔案存入資料庫

[JAVA] BigDecimal compare


  • The BigDecimal.equals method does not think that 2.0 is equals to 2.00, but compareTo does.
  • equals
    • new Integer(0).equals(new BigDecimal(0)): false
    • new Integer(0).toString().equals(new BigDecimal(0).toString()): true



* Reference
- Java BigDecimal equals vs. comareTo | Xinotes

[Database] Oracle ROWNUM and ROWID

[ROWNUM]

* Definition
- 執行結果資料的列數
- Is a pseudo-column that returns a row's position in a result set.
- Is evaluated AFTER records are selected from the database and BEFORE the execution of ORDER BY clause.
- Only exists for a row once it is retrieved from a query. It represents the sequential order in which Oracle has retrieved the row. Therefore it will always exist, be at least 1, and be unique (among the rows returned by the query).


* 運作方式:
  1. Oracle executes your query.
  2. Oracle fetches the first row and calls it row number 1.
  3. Have we gotten past row number meets the criteria? If no, then Oracle discards the row, If yes, then Oracle return the row.
  4. Oracle fetches the next row and advances the row number (to 2, and then to 3, and then to 4, and so forth).
  5. Go to step 3.
- 使用 ROWNUM > (condition) 是不合理的,因為在第三步時會不符合條件而不在結果內,第四步查出來的 ROWNUM 仍然是1,所以永遠也不會達成條件。
- 同樣道理,ROWNUM 如果單獨用 = ,也只有在 ROWNUM=1 時才有用。

* 因此,如果需要查詢 ROWNUM 在某區間的資料時,就必須使用子查詢的方式,但數據量大時會影響速度。
- ex: select * from(select rownum no ,id,name from student) where no>2;。
- 注意子查詢中的 rownum 必須要有别名,否則還是會查不到。因為 ROWNUM 不是真正屬於某個表的列,若沒有別名會無法判斷是子查詢還是主查詢的 ROWNUM。

* 還有,若是和 ORDER BY 同時使用的話,也必須使用子查詢,因為 ROWNUM 會比 ORDER BY 先被執行而指定,指定完列數後才會被 ORDER BY,這樣一來,最後的 ROWNUM 也亂掉了。


[ROWID]

* ROWID actually represents the physical location of the record/row in the database. That being the case, it is (according to Oracle documentation) the fastest way to retrieve a particular row. Faster than an index, even.

* Also both referred to as pseudo-columns. That is, they are not "real" columns that will show up when you DESC a table. They don't actually exist anywhere in the database. But they're available for you to use.



* Reference
- ROWNUM - Oracle FAQ
- OracleBlog: ROWNUM and ROWID
- Oracle的rownum原理和使用 - DCTM + SAP - ITeye技术网站 **

[Database] SELECT and ORDER BY

[SELECT order]

SELECT a.FIELD1, (SELECT b.FIELD1 FROM TABLEB b WHERE b.FIELD1 = a.FIELD1) AS c

FROM TABLE a

WHERE a.FIELD1 > 0;

* c 每次 SELECT 都會執行一次,以參考 a.FIELD1 產生欄位內容。


[ORDER BY]

* 如果order by 條件不是unique 不能確定select結果的順序會一樣

因為不知道oracle是怎麼運作來決定的 所以不知道順序的依據

不過select出來的資料不會有誤