原生和前端的无缝融合?支持同层渲染的Android WebView!

1,905 阅读2分钟

一、快速了解

先给它起个名字吧,G3WebCore,然后我们通过一组问答来了解它。

  1. G3WebCore是在系统WebView的基础上再次封装优化吗?
    答:G3WebCore不是对系统WebView的再次封装,它是基于chromium-81开发的一个新WebView,所以它自身携带了一个完整的浏览器内核。

  2. G3WebCore在使用上和系统WebView区别大吗?
    答:为了使用方便,它的API除了极个别以外和系统WebView几乎完全一样。

  3. G3WebCore开源吗?
    答:java代码全部开源,c++部分暂不开源。仓库地址点这里

  4. G3WebCore除了有独立于系统的浏览器内核外,还有什么特别的吗?
    答:当然是有的,它支持同层渲染。同层渲染,从技术上的理解,就是前端元素用原生组件的能力,并且需要让原生组件和前端元素一样受WebView控制。

二、简单介绍下原理

g3_web_core.jpg
更多的细节参考:

三、一个简单例子,live-player组件,原生侧用ijkplayer实现

  1. 前端侧
<embed id="plugin-live-player" type="native-plugin/live-player" width="500" height="300" src="xxx"/>
  1. 原生侧

使用之前在Aplication的Oncreate里初始化

public class TestApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        G3WebCoreInitializer.init(this);
    }
}

注册同层组件

webView.getNativePluginManager().registerNativePlugin("native-plugin/live-player", new NativePluginFactory() {
    @Override
    public NativePlugin createNativePlugin(long ptr) {
        return new LivePlayerPlugin(TestActivity.this, ptr);
    }
});

提供同层组件的对应实现

public class LivePlayerPlugin extends NativePlugin {

    private IjkMediaPlayer mediaPlayer;

    public LivePlayerPlugin(Context mContext, long mPtr) {
        super(mContext, mPtr);
    }

    @Override
    public boolean onCreate(SurfaceTexture surfaceTexture, int width, int height, Map<String, String> args) {
        try {
            mediaPlayer = new IjkMediaPlayer();
            mediaPlayer.setDataSource(args.get("src"));
            mediaPlayer.setSurface(new Surface(surfaceTexture));
            mediaPlayer.prepareAsync();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    @Override
    public void handleInputEvent(MotionEvent motionEvent) {

    }

    @Override
    public void onDestroy() {
        if (mediaPlayer != null) {
            mediaPlayer.release();
        }
    }

}
  1. 如果原生组件希望处理手势事件, js还需要设置触摸事件的监听
    pluginLivePlayer.addEventListener('touchstart', touch);
    pluginLivePlayer.addEventListener('touchmove', touch);
    pluginLivePlayer.addEventListener('touchend', touch);
    pluginLivePlayer.addEventListener("touchcancel", touch);
    pluginLivePlayer.addEventListener("touchleave", touch);

四、G3WebCore实现了哪些API了?

  • WebChromeClient
onProgressChanged
onReceivedTitle
onReceivedIcon
onReceivedTouchIconUrl
enterFullscreen,替代原来的onShowCustomView
exitFullscreen,替代原来的onHideCustomView
onCreateWindow
onCloseWindow
onJsAlert
onJsConfirm
onJsPrompt
onJsBeforeUnload
onGeolocationPermissionsShowPrompt
onGeolocationPermissionsHidePrompt
onPermissionRequest
onPermissionRequestCanceled
onConsoleMessage
getDefaultVideoPoster
getVisitedHistory
onShowFileChooser
  • WebViewClient
shouldOverrideUrlLoading
onPageStarted
onPageFinished
onLoadResource
onPageCommitVisible
shouldInterceptRequest
onReceivedError
onReceivedHttpError
doUpdateVisitedHistory
onReceivedSslError
  • WebView
loadUrl
addJavascriptInterface
removeJavascriptInterface
evaluateJavaScript
stopLoading
reload
canGoBack
goBack
canGoForward
goForward
canGoBackOrForward
goBackOrForward
getOriginalUrl
pauseTimers
resumeTimers
onPause
onResume
isPaused
clearCache
clearHistory
clearSslPreferences
getUrl
destroy
getFavicon
setWebViewClient
setWebChromeClient
copyBackForwardList
getNativePluginManager(同层渲染相关)