zoukankan      html  css  js  c++  java
  • 安卓系统源码编译系列(六)——单独编译内置浏览器WebView教程

     

                      

    本文主要对从安卓系统源码中抽取出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"/>

    现在我们就可以在模拟器上运行工程了,运行效果如下: 

      

    注意:

    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环境    》 

    如果大家觉得对自己有帮助的话,还希望能帮顶一下,谢谢:)

  • 相关阅读:
    iOS中的隐式动画
    CALayer 为什么选择 cg 开头 而 不选择 UI 开头
    webStorm中的混乱代码格式化
    html5中的常用的库
    地下城勇士外挂
    开发板的时间设置有效,但重启恢复
    8148
    监控行人检测 .
    Linux设备驱动程序学习之分配内存
    快熟傅里叶算法图之音频wav文件
  • 原文地址:https://www.cnblogs.com/bigben0123/p/4521512.html
Copyright © 2011-2022 走看看