Android Webkit学习之一:WebView创建及重画_大果冻与小布丁_新浪博客

1.Frame的创建

1)mWebViewCore = new WebViewCore(ctx, this, callbackProxy,

jsInterfaces)

\framworks\base\core\java\android\webkit\WebView.java@WebView()

2)mBrowserFrame = new BrowserFrame(mContext, this, mCallbackProxy,

mSettings, mJavascriptInterfaces);

 

\framworks\base\core\java\android\webkit\WebViewCore.java@initialize()

BrowserFrame()@BrowserFrame.java

->

\webkit\WebKit\android\jni\WebCoreFrameBridge.cpp@nativeCreateFrame()

nativeCreateFrame创建了几个很重要的对象:

3)创建ChromeClientAndroid对象

\webkit\WebKit\android\WebCoreSupport\ChromeClientAndroid.cpp@ChromeClientAndroid()

4) 创建EditorClientAndroid对象

\webkit\WebKit\android\WebCoreSupport\EditorClientAndroid.cpp@EditorClientAndroid()

5) 创建Page对象 \webkit\webcore\page\page.cpp@page()

6) 创建WebFrame对象

\webkit\WebKit\android\jni\WebCoreFrameBridge.cpp@WebFrame()

用于访问Java BrowserFrame类

  

让ChromeClientAndroid类保持WebFrame引用。

7)创建FrameLoaderClientAndroid对象

\webkit\WebKit\android\WebCoreSupport\FrameLoaderClientAndroid.cpp@FrameLoaderClientAndroid(webFrame)

8)创建Frame对象(管理page, document, dom window, event handler, FrameView)

\webkit\webcore\page\frame.cpp@Frame::create(page, null,

loaderClient)

  

FrameLoaderClientAndroid保持Frame的引用。

9)创建WebViewCore对象,用于访问Java WebViewCore

\webkit\WebKit\android\jni\WebViewCore.cpp@WebViewCore(env,

javaview, frame)

10)创建FrameView对象,传入Frame对象指针

\webkit\webcore\page\FrameView.cpp@FrameView::create(frame)

11) 创建WebFrameView对象

\webkit\WebKit\android\jni\WebFrameView.cpp@WebFrameView(frameView,

webViewCore)

12) 把frameView设置给新创建的Frame对象

\webkit\WebKit\android\jni\WebCoreFrameBridge.cpp@frame->setView(frameView)

13) 初始化frame并打开keyboard focus

\webkit\WebKit\android\jni\WebCoreFrameBridge.cpp@frame->init();

frame->selection()->setFocused(true);

14) 设置BrowserFrame的mNativeFrame为frame

\webkit\WebKit\android\jni\WebCoreFrameBridge.cpp@SET_NATIVE_FRAME(env,

obj, (int)frame)

15) 初始化skining有关的类

\webkit\WebKit\android\jni\WebCoreFrameBridge.cpp@WebCore::RenderSkinAndroid::Init(am,

directory)

16)初始化全局本地化按钮名字

\webkit\WebKit\android\jni\WebCoreFrameBridge.cpp@initGlobalLocalizedName()

2.基本关系

WebView 保持 nativeWebView 和 WebViewCore

WebView用sendMessage与WebViewCore通信

通过mNativeClass判断native WebView是否存在,调用native函数

WebViewCore中有System.loadLibrary(“webcore”),zygote初始化期间加载。

WebViewCore保持BrowserFrame, WebView, CallbackProxy, WebSettings,

JavascriptInterfaces, nativeClass

其中nativeClass是在native WebViewCore对象创建时赋值的。

\webkit\WebKit\android\jni\WebViewCore.cpp@env->SetIntField(javaWebViewCore,

gWebViewCoreFields.m_nativeClass, (jint)this);

WebViewCore通过JNI与native WebViewCore交互。

C代码中:

FrameView保持Frame, Frame也保持FrameView

WebFrameView保持FrameView 和 WebViewCore

同时把自己设置给FrameView

\webkit\WebKit\android\jni\WebFrameView.cpp@mFrameView->setPlatformWidget(this);

WebViewCore保持Frame

3.重画:

WebView.java@onDraw()

WebView.java@drawContent()

WebView.java@drawCoreAndCursorRing()

WebViewCore.java@drawContentPicture()

WebViewCore.java中的drawContentPicture最终会调到webkit中WebViewCore.cpp的drawContent方法:

bool WebViewCore::drawContent(SkCanvas* canvas, SkColor

color)

{

#ifdef ANDROID_INSTRUMENT

   

TimeCounterAuto

counter(TimeCounter::WebViewUIDrawTimeCounter);

#endif

   

DBG_SET_LOG(“start”);

   

m_contentMutex.lock();

    PictureSet

copyContent = PictureSet(m_content);

   

m_contentMutex.unlock();

    int sc =

canvas->save(SkCanvas::kClip_SaveFlag);

    SkRect

clip;

    clip.set(0,

0, copyContent.width(), copyContent.height());

   

canvas->clipRect(clip,

SkRegion::kDifference_Op);

   

canvas->drawColor(color);

   

canvas->restoreToCount(sc);

    bool

tookTooLong = copyContent.draw(canvas);

   

m_contentMutex.lock();

   

m_content.setDrawTimes(copyContent);

   

m_contentMutex.unlock();

   

DBG_SET_LOG(“end”);

    return

tookTooLong;

}

来源URL:http://blog.sina.com.cn/s/blog_49f62c350101475f.html