安卓系統源碼編譯系列(六)——單獨編譯內建瀏覽器WebView教程

來源:互聯網
上載者:User

標籤:

                    原文                   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.jarout/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jarout/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_net2LOCAL_MODULE_CLASS := SHARED_LIBRARIESLOCAL_MODULE_TAGS := optionalINTERMEDIATES := $(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 directoryLOCAL_MODULE := libwebcore2LOCAL_MODULE_CLASS := STATIC_LIBRARIESLOCAL_MODULE_TAGS := optionalbase_intermediates := $(call local-intermediates-dir)...LOCAL_SHARED_LIBRARIES := libEGL libGLESv2 libandroid libandroidfw libandroid_runtime libchromium_net2 libcrypto ...LOCAL_PRELINK_MODULE := falseLOCAL_MODULE := libwebcore2LOCAL_MODULE_TAGS := optionalLOCAL_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"/>

現在我們就可以在模擬器上運行工程了,運行效果如下: 

  

注意:

  1. 如果出現黑屏,可以嘗試將最後加入的INTERNET許可權去掉後重試。
  2. 只能在編譯時間對應版本的模擬器上運行,如果提示函數找不到,可以切換相應模擬器的版本後重試。
真機運行  

在模擬器上運行成功之後可以在真機上運行,效果如下: 

  

但是一旦用手指滑動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教程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.