在了解这部分功能之前,需要先了解一下浏览器的布局特点。在大部分应用里面,Activity的Layout文件是通过Activity::setContentView来指定的。不过浏览器的BrowserActivity有点特殊。他首先通过BrowserActivity所使用的DecorView取得其窗口内容的根View (由com.android.internal.R.id.content指定,请注意这里是窗口内容的根,并不是所有View的根),然后把R.layout.custom_screen作为其第一个孩子加入。
R.layout.custom_screen是FrameLayout类型,在全屏幕的情形(主要是视频),显示fullscreen_custom_content部分。否则显示LinearLayout节点的内容。
BrowserActivity主要成员介绍:
BrowserActivity::mCustomViewContainer,全屏使用的布局;
BrowserActivity::mContentView,非全屏布局
BrowserActivity::mErrorConsoleContainer,不了解;
视频播放流程(这个动作是由用户发起,DOM作为事件的传递者):
(C++)
MediaDocument::defaultEventHandler
HTMLMediaElement::play
HTMLMediaElement::playInternal
HTMLMediaElement::updatePlayState
MediaPlayer::play
MediaPlayerVideoPrivate::play,调用Java层得HTML5VideoViewProxy::play
(Java)
HTML5VideoViewProxy::play,发出PLAY
HTML5VideoViewProxy::handleMessage,PLAY
HTML5VideoViewProxy:VideoPlayer::play
WebChromeClient::onShowCustomView,请求往浏览器的mCustomViewContainer增加一个VideoView
Tab:mWebChromeClient::onShowCustomView
BrowserActivity.onShowCustomView,显示mCustomViewContainer
要注意的是,VideoView是SurfaceView的子类型。所以可以做到显示在BrowserActivity。但是其内容的渲染是在另外的线程里面。
关闭视频的流程(譬如按HOME或者Back按键):
(Java)
BrowserActivity.onPause
Tab.mWebChromeClient::onHideCustomView
Activity.onHideCustomView
隐藏mCustomViewContainer,显示mContentView
mCustomViewCallback.onCustomViewHidden
HTML5VideoViewProxy::onCustomViewHidden
释放定时器等资源,删除mVideoView
VideoView::stopPlayback
MediaPlayer.stop