安卓系统源码编译系列(六)——单独编译内置浏览器WebView教程
?
??????????????????
原文?????????????????? http://blog.csdn.net/zhaoxy_thu/article/details/18883015????????????本文主要對從安卓系統源碼中抽取出WebView相關源碼進行單獨編譯的流程進行說明。
編譯流程說明????
由于WebView包含兩個部分,一部分是上層的Java代碼,包括若干Java類,用于對外提供接口;另一部分是下層的C++代碼,包括兩個so庫(libwebcore.so和libchromium_net.so),用于網頁的解析和渲染。兩個部分之間通過JNI進行交互。
因此,編譯WebView也需要分成兩部分,一部分是編譯Java代碼,另一部分是將C++代碼編譯成so庫。另外,由于WebView的Java代碼中會使用到很多系統的隱藏API,所以我們還需要編譯安卓系統,并從中獲取幾個jar包。
編譯Java代碼??
首先,我們需要下載并編譯任意一個版本的安卓系統源碼,具體步驟可以參見《安卓系統源碼下載及編譯教程》。
??? 完成編譯后,我們可以使用Eclipse(不能使用Intellij IDEA,因為之后添加library的時候無法設置為system library)新建一個Android工程,在src目錄下創建一個??? android.webkit2???? 的包。然后將源碼目錄下的??? frameworks/base/core/java/android/webkit???? 目錄下的所有文件拷貝到新創建的包中。?
由于其中有一個類是編譯之后生成的,所以我們還需要從編譯完的源碼目錄???? out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/webkit??? 中將EventLogTags.java類也拷貝到新建的包中。??
接下來,我們需要在工程中加入包含系統隱藏API的jar包,將以下三個jar包重命名(名稱隨意)后拷貝到工程的libs目錄下:
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/bouncycastle_intermediates/classes.jar在Eclipse中打開工程的Properties->Java Build Path->Libraries->Add Library->User Library,點擊下一步,選擇User Libraries...,選擇New,隨便輸入一個名字,將System library選上(重要),選擇OK。選中剛剛新建的User Library,選擇Add JARs,在工程目錄中選擇新加入的三個jar包,選擇OK。
添加完Library之后,切換到Order and Export選項卡,將剛剛新建的User library調整到最前面,確保隱藏API不會被系統API覆蓋(由于包名相同),選擇OK。另外,還要把Android Private Libraries庫前的勾取消掉,否則之后運行會報錯。
最后,由于我們的java文件都放到了android.webkit2包下,避免與系統的包重名,我們需要將所有java文件中的android.webkit都替換成android.webkit2。使用菜單中的Search命令批量替換即可。完成替換后,刷新一下工程,會發現所有的錯誤都沒了。(有可能還會提示minSdkVersion版本太低,直接按要求修改AndroidManifest.xml文件即可)
編譯so庫??
此時我們的Eclipse工程已經可以編譯運行了,但是啟動的時候會閃退,因為我們還沒有加入so庫。下面我們就來編譯so庫。再回到虛擬機中,進入到安卓源碼的external/chromium目錄下,在終端執行以下命令:
$ sudo sed -i "s#android/webkit#android/webkit2#g" `grep android/webkit -rl *`可以將源碼中的android/webkit都替換成android/webkit2,確保與我們的java代碼包名相同。
再打開external/chromium目錄下的Android.mk文件,將其中的libchromium_net都替換成libchromium_net2,同時增加一行LOCAL_MODULE_TAGS := optional,修改部分如下:
LOCAL_MODULE := libchromium_net2 LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_MODULE_TAGS := optional INTERMEDIATES := $(call local-intermediates-dir)再回到安卓源碼根目錄,運行以下命令:
$ source build/envsetup.sh $ mmm external/chromium編譯成功后可以在??? out/target/product/generic/obj/lib???? 目錄下找到libchromium_net2.so文件。?
接下來進入到安卓源碼的external/webkit/Source/WebKit/android目錄下,在終端執行以下命令:
$ sudo sed -i "s#android/webkit#android/webkit2#g" `grep android/webkit -rl *`同樣可以將源碼中的android/webkit都替換成android/webkit2,確保與我們的java代碼包名相同。
再打開external/webkit目錄下的Android.mk文件,將其中的libwebcore都替換成libwebcore2(三個地方),并且增加一行LOCAL_MODULE_TAGS := optional,另外還要將LOCAL_SHARED_LIBRARIES里面的libchromium_net改成libchromium_net2。修改部分如下:
# 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) ... LOCAL_SHARED_LIBRARIES := \ libEGL \ libGLESv2 \ libandroid \ libandroidfw \ libandroid_runtime \ libchromium_net2 \ libcrypto \ ... LOCAL_PRELINK_MODULE := false LOCAL_MODULE := libwebcore2 LOCAL_MODULE_TAGS := optional LOCAL_LDLIBS := $(WEBKIT_LDLIBS) LOCAL_SHARED_LIBRARIES := $(WEBKIT_SHARED_LIBRARIES) LOCAL_STATIC_LIBRARIES := libwebcore2 $(WEBKIT_STATIC_LIBRARIES) LOCAL_LDFLAGS := -fvisibility=hidden 同樣再回到安卓源碼根目錄,運行以下命令:? $ source build/envsetup.sh $ mmm external/webkit編譯成功后可以在???? out/target/product/generic/obj/lib??? 目錄下找到libwebcore2.so文件。??
完成編譯并運行測試代碼
??? 下面我們將以上編譯生成的兩個so文件(libchromium_net2.so和libwebcore2.so)放到我們工程的??? libs/armeabi???? 目錄下。再修改工程android.webkit2包下的JniUtil.java和WebViewCore.java文件,將其中的?
static {System.loadLibrary("webcore");System.loadLibrary("chromium_net"); }改為(注意,順序也顛倒了)
static {System.loadLibrary("chromium_net2");System.loadLibrary("webcore2"); }到此為止,與WebView相關的操作都完成了,我們可以開始加入測試代碼。在測試的Activity.java的onCreate方法中加入:
WebView webView = (WebView)findViewById(R.id.webview); webView.getSettings().setJavaScriptEnabled(true); webView.loadUrl("http://www.baidu.com"); 對應的xml layout中加入:? <android.webkit2.WebView android:id="@+id/webview" android:layout_width="fill_parent" android:layout_height="fill_parent" />最后在AndroidManifest.xml中加入:
<uses-permission android:name="android.permission.INTERNET"/>現在我們就可以在模擬器上運行工程了,運行效果如下:?
??注意:
真機運行??
在模擬器上運行成功之后可以在真機上運行,效果如下:?
??但是一旦用手指滑動WebView,應用就會閃退,原因是缺少一些資源,下面我們來將它們加上:
首先我們需要將安卓源碼目錄下的???? frameworks/base/core/res/res/values/styles.xml??? 中的??
<style name="ZoomControls"><item name="android:gravity">bottom</item> <item name="android:paddingLeft">15dip</item> <item name="android:paddingRight">15dip</item> </style>粘貼到我們工程目錄下的???? res/values/styles.xml??? 中。??
然后再將???? frameworks/base/core/res/res/layout/zoom_magnify.xml??? 文件復制到我們工程目錄下的???? res/layout??? 中。??
接著將???? frameworks/base/core/res/res/drawable/btn_zoom_page.xml??? 文件復制到我們工程目錄下的???? res/drawable??? 中。??
最后將???? frameworks/base/core/res/res??? 下的???? drawable-ldpi??? 、???? drawable-mdpi??? 、???? drawable-hdpi??? 、???? drawable-xhdpi??? 目錄下的???? btn_zoom_page_normal.png??? 和???? btn_zoom_page_press.png??? 文件復制到我們工程目錄???? res??? 下的相應文件夾中。??
再次運行,即可任意滑動WebView了。
參考資料
??? 《??? Android 4.1 - 將系統瀏覽器編譯成獨立應用??? 》???
??? 《??? 搭建自定義android?Browser環境??? 》?
如果大家覺得對自己有幫助的話,還希望能幫頂一下,謝謝:)
總結
以上是生活随笔為你收集整理的安卓系统源码编译系列(六)——单独编译内置浏览器WebView教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hadoop学习笔记(七)
- 下一篇: java信息管理系统总结_java实现科