Android 4.1 – 將系統瀏覽器編譯成獨立應用

為瞭方便在手機上(Galaxy Note with CM10),調試Android4.1 系統瀏覽器的代碼,進行代碼研究,我把系統瀏覽器編譯成瞭一個獨立的應用,不會跟ROM原來的系統瀏覽器產生沖突,可以很方便地在Eclipse自己建立的工程裡面對Java部分的代碼進行跟蹤調試,理論上C++的部分也可以通過GDB進行調試。


自己編譯的庫,顯示Layer邊界和信息

首先系統瀏覽器可以認為分為3部分:
1,Browser.Apk 一個全功能瀏覽器應用
2,android.webkit 平臺適配層的Java部分代碼,對外提供瞭封裝好的WebView
3,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");
    }

You May Also Like