Android集成三方浏览器之Crosswalk

上一篇讲解了腾讯 X5 内核的集成,这一篇是讲解 Crosswalk 的集成 Crosswalk 也是采用了Chromenium 内核,是一款开源的 web 引擎,开发者可以直接把 Crosswalk 嵌入到应用之中,当然也支持共享模式(系统中没有对应的 Crosswalk 库是会提示下载)。只不过 Crosswalk 已经停止维护了。

Crosswalk官网

集成

想要使用 CrossWalk 有三种方式:

  1. maven 远程依赖
//配置gradle
   repositories {
        maven {
            url 'https://download.01.org/crosswalk/releases/crosswalk/android/maven2'
        }
    }
复制代码
compile 'org.xwalk:xwalk_core_library:23.53.589.4'
复制代码

2.下载 zip 包后解压,然后以用开发工具Import Module导入,作为一个library依赖。

推荐使用 stable(稳定版)!其他的分别是 beta(测试版), canary(金丝雀版)。下载最新版本的 zip包: 23.53.589.4

3.下载aar 下载aar包后导入项目的 lib目 录下,然后在gradle中添加

repositories {
    flatDir {
        dirs 'libs'
    }
}
复制代码
compile(name: 'crosswalk-23.53.589.4', ext: 'aar')
复制代码

使用

1.manifest中添加

android:hardwareAccelerated="true" //application节点下开启硬件加速
复制代码
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
复制代码

2.布局中添加

    <org.xwalk.core.XWalkView
        android:id="@+id/xwalkview"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    org.xwalk.core.XWalkView>
复制代码

3.新建 Activity 继承 XWalkActivityonXWalkReady() 方法里面进行初始化操作

class MainActivity : XWalkActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    override fun onXWalkReady() {
        XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, true);   //开启默认动画
        var setting = xwalkview.settings
        setting.loadWithOverviewMode = false
        setting.javaScriptEnabled = true                        //支持js
        setting.javaScriptCanOpenWindowsAutomatically = true    //支持通过JS打开新窗口
        setting.useWideViewPort = true                          //将图片调整到合适webview的大小
        setting.loadWithOverviewMode = true                     //缩放至屏幕的大小
        setting.loadsImagesAutomatically = true                 //支持自动加载图片
        setting.supportMultipleWindows()                        //支持多窗口
        setting.setSupportZoom(true)
        setting.allowFileAccess = true
        setting.setDomStorageEnabled(true)
        setting.allowContentAccess = true
        setting.allowContentAccess = true
        setting.domStorageEnabled = true
        xwalkview.requestFocus()
        setting.cacheMode = WebSettings.LOAD_NO_CACHE
        xwalkview.setResourceClient(object : XWalkResourceClient(xwalkview) {
            override fun onLoadStarted(view: XWalkView?, url: String?) {
                super.onLoadStarted(view, url)
            }

            override fun onLoadFinished(view: XWalkView?, url: String?) {
                super.onLoadFinished(view, url)
            }

            override fun shouldOverrideUrlLoading(view: XWalkView?, url: String?): Boolean {
                view?.loadUrl(url)
                return true
            }

            override fun onReceivedSslError(view: XWalkView?, callback: 
                                            ValueCallback?, error: SslError?) {
                callback?.onReceiveValue(true)
                super.onReceivedSslError(view, callback, error)
            }


            override fun onReceivedLoadError(view: XWalkView?, errorCode: Int,
                                             description: String?, failingUrl: String?) {
                super.onReceivedLoadError(view, errorCode, description, failingUrl)
            }

            override fun onProgressChanged(view: XWalkView?, process: Int) {
                super.onProgressChanged(view, process)
                if (...) {
                    ...
                    progressBar.setProgress(process)
                    ...
                } else {
                    ...
                }
            }
        })
        xwalkview.setUIClient(object :XWalkUIClient(xwalkview){

            override fun onJsAlert(view: XWalkView?, url: String?, 
                                   	message: String?, result: XWalkJavascriptResult?): Boolean {
                return super.onJsAlert(view, url, message, result)
            }

            override fun onReceivedTitle(view: XWalkView?, title: String?) {
                super.onReceivedTitle(view, title)
            }

            override fun openFileChooser(view: XWalkView?, uploadFile: ValueCallback?, acceptType: String?, capture: String?) {
                super.openFileChooser(view, uploadFile, acceptType, capture)
            }
        })

        xwalkview.loadUrl("your url")
    }
  
     override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (xwalkview!=null){
            xwalkview.onActivityResult(requestCode, resultCode, data)
        }
    }

    override fun onNewIntent(intent: Intent?) {
        if (xwalkview != null) {
            xwalkview.onNewIntent(intent)
        }
    }
 
      override fun onDestroy() {
        super.onDestroy()
        XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, false);
    }
}
复制代码

XWalkUIClient 对应系统 webview 中的 WebChromeClient

XWalkResourceClient 对应系统 webviewWebViewClient

  • 监听页面生命
override fun onResume() {
    super.onResume()
    xwalkview?.let {
        xwalkview.pauseTimers()
        xwalkview.onHide()
    }
}
override fun onPause() {
    super.onPause()
    xwalkview?.let {
        xwalkview.pauseTimers()
        xwalkview.onHide()
    }
}
复制代码
  • 判断页面返回
if (xwalkview.navigationHistory.canGoBack()) {
    xwalkview.getNavigationHistory().navigate(
            XWalkNavigationHistory.Direction.BACKWARD, 1)
} else {
    finish()
}
复制代码

提示

在使用 Crosswalk 的过程遇到了几个问题,在这里提一下,希望能有一点帮助。

  1. lang.RuntimeException: Crosswalk's APIs are not ready yet异常:请在onready里面进行相关设置和加载页面
  2. 使用第一种 maven 集成方式 可能会报资源异常 在你的 build.gradle 中添加:
configurations.all {
    resolutionStrategy {
        force 'com.android.support:support-v4:27.1.0'//自己的版本号
    }
}
复制代码

3.Crosswalk 加载 SSL 证书有问题的网站时会报 Rquest was denied for security

override fun onReceivedSslError(view: XWalkView?, callback: ValueCallback?, error: SslError?) {
    callback?.onReceiveValue(true) //系统webview中的是handler.process()
}
复制代码

添加上述代码后会回调 onReceivedLoadError并报net:: ERR_SECURITY_RESPONSE。这个问题折腾了很久,在 xwalkview的论坛 中发现 Crosswalk 会阻止连接到不信任的 SSL

最后发现源码中的 SsLUtil.java 会阻止加载。

public static boolean shouldDenyRequest(int error)
{
    assert error >= -215 && error <= -200;
    switch (error)
    {
        case -213:
        case -212:
        case -211:
        case -208:
        case -207:
        case -206:
        case -203:          
 //	case -202:   
        case -201:           
 //	case -200:  
    	case -150:
        case -129:
     return true;
    }
    return false;
}
复制代码

修改后的资源已忽略证书安全问题「不建议忽略证书安全问题,我是测试环境所需」

参考文档:

Crosswalk官网

Crosswalk Api 文档

Crosswalk 项目

官方论坛

最后

关于腾讯 X5 内核集成请跳转:

Android集成三方浏览器之X5内核

你可能感兴趣的:(移动开发,java,开发工具)