為了方便在手機上(Galaxy Note with CM10),調試Android4.1 系統瀏覽器的代碼,進行代碼研究,我把系統瀏覽器編譯成了一個獨立的應用,不會跟ROM原來的系統瀏覽器產生衝突,可以很方便地在Eclipse自己建立的工程裡面對Java部分的代碼進行跟蹤調試,理論上C++的部分也可以通過GDB進行調試。
自己編譯的庫,顯示Layer邊界和資訊
首先系統瀏覽器可以認為分為3部分:
1,Browser.Apk 一個全功能瀏覽器應用2,android.webkit 平台適配層的Java部分代碼,對外提供了封裝好的WebView3,libwebcore.so 包括WebKit的代碼和平台適配層C++部分的代碼,libchromium_net.so Chrome的網路堆棧我們實際只需要後面兩部分(2和3),然後加上自己的一個簡單的測試用外殼就可以了。首先參考官方的文檔,建立ROM編譯環境,編譯ROM(http://source.android.com/source/index.html)。開始建立獨立的應用(home/roger/a41是我的ROM的目錄,需要替換成自己ROM的目錄):
- 在Eclipse建立一個Android工程,把android.webkit目錄下的Java代碼拷貝過來;
- 將/home/roger/a41/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/webkit下面的EventLogTags.java也拷貝到自己的工程;
- 因為android.webkit下的類會使用SDK中非公開的API,我們需要解決編譯錯誤:
- 建立一個User Library,並且勾選System Library的選項;
- 加入以下Jar包:
- /home/roger/a41/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
- /home/roger/a41/out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar
- /home/roger/a41/out/target/common/obj/JAVA_LIBRARIES/bouncycastle_intermediates/classes.jar
- 在Java Build Path/Order and Export把建立的庫放在最前面;
- 因為在我們應用中的android.webkit包跟SDK中的重名,所以我們需要更改包名,可以改成android.webkit2;
- 我們需要重新編譯libchromium_net.so和libwebcore.so,並且使用另外的名字,並且把其代碼中使用的android/webkit/ JNI路徑改成android/webkit2/保證JNI的正確性:
- 在/home/roger/a41/external/chromium下面,把所有源檔案的android/webkit/路徑改成android/webkit2/;
- 開啟/home/roger/a41/external/chromium/Android.mk,修改庫名為libchromium_net2,並且加多一行“LOCAL_MODULE_TAGS := optional“,具體內容見後;
- 重新編譯chromium_net,得到libchromium_net2.so;
- 在/home/roger/a41/external/webkit/Source/WebKit/android下面,把所有源檔案的android/webkit/路徑改成android/webkit2/;
- 開啟/home/roger/a41/external/webkit/Android.mk,將庫名改成libwebcore2.so,並且加多一行“LOCAL_MODULE_TAGS := optional“(需要修改兩個地方,靜態庫編譯和動態庫編譯),另外還需要把匯入庫libchromium_net改成libchromium_net2,具體內容見後;
- 重新編譯webcore,得到libwebcore2.so;
- 接下來我們可以把修改後的libwebcore2.so和libchromium_net2.so push到手機的rom裡面,假設路徑是/data/local(如果沒有寫入權限,用Root Explorer修改);
- 然後我們需要修改Java的代碼,讓它去載入我們自己的庫,修改的地方位於JniUtil.java和WebViewCore.java,具體內容見後(載入順序需要改變,先載入libchromium_net2.so再載入libwebcore2.so);
- 最後加上我們自己的Test Shell的代碼,運行就OK了,如果只修改了C++的代碼,重編譯後再Push到手機,然後重新運行Test Shell就可以馬上生效,Java的代碼可以在Eclipse裡面很方便的調試,C++的代碼理論上也可以通過GDB進行調試;
LOCAL_MODULE := libchromium_net2
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_TAGS := optional
INTERMEDIATES := $(call local-intermediates-dir)# Define our module and find the intermediates directory
LOCAL_MODULE := libwebcore2
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE_TAGS := optional
base_intermediates := $(call local-intermediates-dir)
# Do not attempt prelink this library. Needed to keep master-gpl happy, no
# effect in master.
# TODO: remove this when master-gpl is updated.
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libwebcore2
LOCAL_MODULE_TAGS := optional
LOCAL_LDLIBS := $(WEBKIT_LDLIBS)
# Build the list of shared libraries
# We have to use the android version of libdl
LOCAL_SHARED_LIBRARIES := \
libEGL \
libGLESv2 \
libandroid \
libandroidfw \
libandroid_runtime \
libchromium_net2 \
libcrypto \
libcutils \
libdl \
libgui \
libicuuc \
libicui18n \
libmedia \
libmedia_native \
libnativehelper \
libskia \
libsqlite \
libssl \
libstlport \
libutils \
libui \
libz static {
System.load("/data/local/libchromium_net2.so"); System.load("/data/local/libwebcore2.so");
}