顯示具有 internal 標籤的文章。 顯示所有文章
顯示具有 internal 標籤的文章。 顯示所有文章

2008年10月27日 星期一

探究 Android 系統應用程式的祕密

Digging out the secret of Android preloaded applications

相信我,閱讀別人的原始程式碼,是你學寫程式最好的方式之一,尤其是原廠的原始程式碼。

其實 Google 為 Android 寫了不少範例程式,像是在 Android SDK 中,就有好幾個範例程式。還有 Google Open Source 中的 apps-for-android,也是我推薦你必讀的範例程式之一。沒事時,翻閱一下,都會有新收穫。

不過,似乎還有些 Google 的不傳秘技,不在這些範例程式中。你得從他的一些系統原始程式中,才能學到。

我剛開始學 Android 時,就常被 res 中的 xml 搞得迷迷糊糊的,只敢用最簡單的功能。後來看多了系統的原始程式碼,發覺裡面有許多 SDK 文件中,沒有提到,或是語焉不詳的用法。像是在 xml 中,還可以用 selector, alpha, set, scale, translate, level-list 等 tags 。這些用法,在某些時候,還蠻好用的。而這用法的範例,在 Google 釋放 Android 原始程式前,你還是要用一些非常手段,才能拿到。

Google 預計在年底前,會釋放出 Android 原始程式。不過這釋放的範圍到那,在謎底未公布前,誰也說不準。說不定,那些 Google 寫的應用程式,如 Maps ,他有可能還是不會公開他的原始碼。在未公開原始程式碼前,我在這裡先公開,如何抓出這些系統應用程式的原始碼。你要注意的是, decompile 這些程式有可能會違反 Android SDK 授權條款,請勿任意散播你所 decompile 出來的檔案。(註:Android source code 已經在 2008/10/21 釋放出來,當初我猜的沒錯,像是 Maps 應用程式,com.google.android.maps package 的原始碼還是沒公開。)

在這,我以 Maps 這個應用程式為例。我曾在 Android 內部的祕密 - 系統目錄 中提到過,/system/app 目錄中,放的都是系統預先安裝的應用程式執行檔。首先,你先依照我在這篇提到的方法,到 /system/app 目錄中,將 Maps.apk 轉存到 Windows 的檔案目錄中。由於 .apk 檔是符合 zip 壓縮格式的。因此,接著將 Maps.apk 改名成 Maps.zip ,並用 WinZip 將檔案解壓縮,存到你自己的目錄中。

解開後,你應該會看到下面這些檔案及目錄:

classes.dex
resources.arsc
AndroidManifest.xml
[res]
  [drawable]
  [layout]
  [layout-land]
  [layout-port]
  [menu]
  [xml]
[META-INF]

classes.dex 就是 Java 編譯後的 classes 檔。目前還沒有工具可以直接將 .dex 檔轉成 .class 或 .java 格式,不過倒是有個 dexdump,可以幫你列印出 Java VM 的 machine code。有興趣的人,可參考 How to decompile .dex file on Android,裡面有詳細的說明。

想要知道 Maps 這個程式,到底指定了那些 uses-permission,提供了那些 provider 的你,一定急著要打開 AndroidManifest.xml。有點失望吧!這是個二進位檔。別擔心,你可以用 axml2xml.pl,將他轉成一般的 xml 檔案格式。這個工具,用在 m5 之前的版本,都還正常。不過用在 1.0r1 上,我發覺 lauout/ 中 的 xml 檔,似乎轉出的結果有些問題。在網路上,有人說這二進位的 xml 檔,是 WBXML 格式。不過,我試了幾個 wbxml2xml 轉換工具,都不行。還是得等 axml2xml.pl 支援 1.0r1。

註:關於反解譯二進位 xml 檔的問題,已經有另一個解法。去 android4me 上下載 AXMLPrinter2.jar,接著在命令視窗上執行 java -jar AXMLPrinter2.jar binary_xml_file ,binary_xml_file 就是在 lauout/ 中的二進位 xml 檔。

註:'09/06:另一個可反組譯這二進位 xml 的方法,可到 http://www.it.usyd.edu.au/~massad/project-android.html 找。

註:'10/06:還有一個可反組譯整個 apk 的工具,可到 android-apktool 上下載。

底下就是執行 axml2xml.pl 後的部份內容。

雖然,不能看到原來的 Java 程式碼。不過,另一個值得參考的是 res 這個目錄。相信我,那裡面有很多的寶藏可挖,看到好東西,別忘了分享出來。Enjoy!


繼續閱讀全文...

2008年10月20日 星期一

Android 內部的祕密 - 系統目錄

Android Internal - system directories

您應該已經知道,Android 的核心作業系統是 Linux (現在用的版本是 2.6.25)。因此內部的檔案系統,與系統目錄等,也和 Linux 脫不了關係。要如何觀察這些系統目錄,到底藏了什麼秘密呢?

在 Eclipse 環境中,你可以用 DDMS 來觀察。不過這個 DDMS 在我的電腦上的執行速度,實在太慢了。我個人的偏好是,直接用 adb shell 來觀察。啟動 adb shell 的用法如下:

1. 在 Windows 中,開啟一個命令列視窗 (或執行 cmd.exe 這個程式)
2. cd <android-sdk-install_path>/tools
3. adb shell

當你看到這個 # 提示字元時,就表示你已經進入模擬器的系統。接下來,你就可以用 Linux 上的指令來瀏覽這些目錄。像是 cd, ls, pwd, cat, rm 等等。

這裡面,有幾個目錄是和 Android 相關的,我特地將他整理下來,供你參考。

/system/app

預載入應用程式執行檔 (*.apk),都是放在這。像是 Alarm Clock, Browser, Contacts, Maps,... 等等。

用 DDMS 觀察的話,目錄內的內容,就像下面這樣:

/system/framework

這會放 Android 系統的核心程式庫。像是 core.jar, framework-res.apk, com.google.android.gtalkservice.jar,...等等。疑,1.0r1 不是已經將 gtalk 等相關 APIs 移除了嗎?怎麼他的程式庫還在?雖然許多程式庫都是以 jar 結尾的,不過裡面 Java classes 還是以 dex 格式存在著。

/system/media/audio/(notification, alarms, ringtones, ui)

這裡放系統的聲音檔,像是鬧鈴聲,來電鈴聲等等。這些聲音檔,多是 ogg 格式。

/data/anr/traces.txt

當你的應用程式發生 ANR (Application is Not Responding) 錯誤時,Android 會自動將問題點的 code stack list 寫在這個檔案內,你直接用 cat 命令就可以看他的內容。

/data/app

/system/app 放的是系統預載的應用程式執行檔。而這裡放的是使用者自己安裝的應用程式執行檔 (*.apk)。

/data/data/<app-package-name>

當你在程式中用 Context.openFileOutput() 所建立的檔案,都放在這個目錄下的 files 子目錄內。而用 Context.getSharedPreferences() 所建立的 preferences 檔 (*.xml) ,則是放在 shared_pref 這個子目錄中。

/data/location/gps

這裡看起來,應該是給 GPS location provider 用的。其中的 properties 檔案的內容如下:

requiresNetwork false
requiresSatellite false
requiresCell false
hasMonetaryCost false
supportsAltitude true
supportsBearing true
supportsSpeed true
repeat true
accuracy 100
powerRequirement 1

沒猜錯的話,這應該是用來描述 GPS location provider 有那些功能的。

/data/system/location/location.gps

這個檔案也是個一般文字檔。主要是記錄最後的經緯度座標。LocationManager.getLastKnownLocation() 就在來這抓值的。

/data/property/persist.sys.timezone

這個檔案也是個一般文字檔。主要是記錄目前系統所使用的時區。在我的模擬器上,他記錄著 Asia/Taipei 這個字串。

最後,下面這兩個指令,也很好用。他可以幫你將外部檔案,複製到模擬器的系統檔案目錄內,也可以將模擬器內的檔案,複製到外部系統上。

adb push <local> <remote> - copy file/dir to device
adb pull <remote> <local> - copy file/dir from device


繼續閱讀全文...