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的目录):
  1. 在Eclipse创建一个Android工程,把android.webkit目录下的Java代码拷贝过来;
  2. 将/home/roger/a41/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/webkit下面的EventLogTags.java也拷贝到自己的工程;
  3. 因为android.webkit下的类会使用SDK中非公开的API,我们需要解决编译错误:
    1. 创建一个User Library,并且勾选System Library的选项;
    2. 加入以下Jar包:
      1. /home/roger/a41/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
      2. /home/roger/a41/out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar
      3. /home/roger/a41/out/target/common/obj/JAVA_LIBRARIES/bouncycastle_intermediates/classes.jar
    3. 在Java Build Path/Order and Export把创建的库放在最前面;
  4. 因为在我们应用中的android.webkit包跟SDK中的重名,所以我们需要更改包名,可以改成android.webkit2;
  5. 我们需要重新编译libchromium_net.so和libwebcore.so,并且使用另外的名字,并且把其代码中使用的android/webkit/ JNI路径改成android/webkit2/保证JNI的正确性:
    1. 在/home/roger/a41/external/chromium下面,把所有源文件的android/webkit/路径改成android/webkit2/;
    2. 打开/home/roger/a41/external/chromium/Android.mk,修改库名为libchromium_net2,并且加多一行“LOCAL_MODULE_TAGS := optional“,具体内容见后;
    3. 重新编译chromium_net,得到libchromium_net2.so;
    4. 在/home/roger/a41/external/webkit/Source/WebKit/android下面,把所有源文件的android/webkit/路径改成android/webkit2/;
    5. 打开/home/roger/a41/external/webkit/Android.mk,将库名改成libwebcore2.so,并且加多一行“LOCAL_MODULE_TAGS := optional“(需要修改两个地方,静态库编译和动态库编译),另外还需要把导入库libchromium_net改成libchromium_net2,具体内容见后;
    6. 重新编译webcore,得到libwebcore2.so;
  6. 接下来我们可以把修改后的libwebcore2.so和libchromium_net2.so push到手机的rom里面,假设路径是/data/local(如果没有写权限,用Root Explorer修改);
  7. 然后我们需要修改Java的代码,让它去加载我们自己的库,修改的地方位于JniUtil.java和WebViewCore.java,具体内容见后(加载顺序需要改变,先加载libchromium_net2.so再加载libwebcore2.so);
  8. 最后加上我们自己的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

  1. effect in master.
  2. TODO: remove this when master-gpl is updated.

LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libwebcore2
LOCAL_MODULE_TAGS := optional
LOCAL_LDLIBS := $(WEBKIT_LDLIBS)


  1. Build the list of shared libraries
  2. 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”);
}
Advertisements