浏览器探究——回退和前进

来源:互联网 发布:js节点 元素 编辑:程序博客网 时间:2024/05/15 11:01

前进:

在菜单中点击前进功能主线程会执行BrowserActivity.onOptionsItemSelected,它会调用Controller.onOptionsItemSelected,在处理该菜单项时执行如下语句getCurrentTab().goForward();入口点很明确,就是调用了当前tab的goForward函数。

Tab.goForward调用了主WebView的goForward

WebView.goForward

/**     * Go forward in thehistory of this WebView.     */该函数内先执行了一句checkThread(),这里额外说一句该函数,该函数怎么检查的线程?其实就是判断下当前线程的looper是不是main looper,如果不是就报异常。而且该函数是个静态函数。该函数在WebView的很多地方都有调用,基本上每个WebView的函数都调了,也就是要求WebView这个控件必须在主线程中运行啦。

之后调用WebView.goBackOrForwardImpl。这个函数是回退很前进的统一实现函数。另外有个类似的函数叫WebView.goBackOrForward,其实实现是一样的。

  *Go to the history item that is the number of steps away from     * the current item. Steps is negative ifbackward and positive     * ifforward.     * @param steps The number ofsteps to take back or forward in the back    *              forward list.     */可见回退还是前进,就是通过参数step来决定的。这样看来回退也会调用到该函数。

的确,回退是调用Tab.goBack,进而调用WebView.goBack进而调用WebView.goBackOrForwardImpl,只是参数不同而已。

继续看WebView.goBackOrForward,这里首先调用了WebView.clearHelpers

/**     * Called to clearstate when moving from one page to another, or changing     * in some other way that makes elementsassociated with the current page     *(such as WebTextView or ActionModes) no longer relevant.     */这个函数还是很有用的,他做了很多所谓的清除的工作,包括界面上的和一些状态上的。此处不细看。

接下来是我们熟悉的向WebViewCoreThread线程发消息的流程了。发送GO_BACK_FORWARD消息,WebViewCoreThread线程收到消息后,执行BrowserFrame.goBackOrForward,BrowserFrame.goBackOrForward会调用jni函数nativeGoBackOrForward,该函数对应c层webkit/Source/WebKit/android/jni里的函数。

从c层的JNI函数出来,会回调WebBackForwardList.setcurrentIndex

/**     * Set the new historyindex.     * @param newIndex The newhistory index.     */

这个jni回调对应webkit/Source/WebKit/android/jni/WebHistory.cpp

WebBackForwardList.seturrentIndex是BrowserFame.nativeGoBackOrForward执行是回调上来的函数,所以当前还处于WebViewCoreThread线程中,该函数会通过CallbackProxy发消息给主线程,发HISTORY_INDEX_CHANGE消息。主线程接收到该消息后,执行Tab的WebBackForwardListClient的onIndexChanged。

WebBackForwardListClient

/** * Interface to receive notificationswhen items are added to the * {@link WebBackForwardList}. * {@hide} */

在Tab构造函数中被创建。这个onIndexChanged的处理略过。总之是通过回调把更新BackForwordList索引的事件传了出来,并发送到了主线程中进行了处理。

接着,BrowserFrame.nativeGoBackOrForward从c层的JNI函数出来,会回调BrowserFrame.handleUrl函数。此时回调的参数url已经是待加载的url了,即新的Url了。

/**     * This method iscalled by WebCore to check whether application     * wants to hijack url loading     */

这个函数就是个hijack函数,做一些拦截处理。如果没什么可拦截的,那么这个函数什么也不做的返回。

接着,BrowserFrame.nativeGoBackOrForward从c层的JNI函数出来会回调BrowserFrame.loadStarted。此时回调的参数url已经是待加载的url了,即新的Url了。

 

/**     * native callback     * Indicates the beginning of a newload.     * This method will be calledonce for the main frame.     */

还是老流程了,通过CallbackProxy发送PAGE_STARTED消息给主线程,其中参数包含一个url和一个Bitmap的图标,应该就是网站的logo了。主线程接收后执行Tab的WebViewClient.onPageStarted。该函数对执行WebViewController.onPageStarted,这个WebViewController就是Controller,由于Controller是继承WebViewController接口的。

WebViewController.onPageStarted这个函数在loadurl那节讲了,这里补充一点,里面调用了maybeUpdateFavicon,这个函数会更新bookmark数据库的favicon。传入的Bitmap参数在这里被用到。之后WebViewClient.onPageStarted会执行WebViewClient.updateBookmarkedStatus。即WebViewClient.onPageStarted操作会更新bookmark数据库的。

继续回到BrowserFrame.nativeGoBackOrForward,从c层的JNI函数出来会回调BrowserFarme.setProgress。

/**     * Set the progress forthe browser activity.  Called by native code.     * Uses a delay so it does not happen toooften.     * @param newProgress An intbetween zero and one hundred representing    *                    the currentprogress percentage of loading the page.    */

这个函数的实现略去,主要是会更新UI等状态。

接下来的操作就跟lordUrl的一样了。

0 0
原创粉丝点击