webkit是如何接受到数据的

从网络上回来的数据是如何被webkit接收的?

在framework/…/net/http/EventHandler.java 中定义了一些接口, 比如:
public void data(byte[] data, int len);
public void headers(Headers headers);
public void error(int id, String description);

 

这个接口被framework/…/webkit/LoadListener.java 实现, 重写EventHandler接口中的方法.

被重写的这3个方法大致的思路是: 通过sendMessageInternal api, 把数据包装成message, 发给LoadLisenter所在的线程, 在Handler.handleMessage(Message msg)处理.

class LoadListener extends Handler implements EventHandler {    //所以LoadListener在架构中就当成一个Handler使用.

* IMPORTANT: as this is called from network thread, can't call native
* directly

public void data(byte[] data, int length) {
    boolean sendMessage = false;
    synchronized (mDataBuilder) {
        sendMessage = mDataBuilder.isEmpty();
       
mDataBuilder.append(data, 0, length);
    }
    if (sendMessage) {
        sendMessageInternal(obtainMessage(MSG_CONTENT_DATA));
    }
}

public void headers(Headers headers) {
    sendMessageInternal(obtainMessage(MSG_CONTENT_HEADERS, headers));
}

public void error(int id, String description) {
    sendMessageInternal(obtainMessage(MSG_CONTENT_ERROR, id, 0, description));
}

}

 

/*
* This message handler is to facilitate communication between the network
* thread and the browser thread.
*/
public void handleMessage(Message msg) {
    switch (msg.what) {
        case MSG_CONTENT_HEADERS:
            handleHeaders((Headers) msg.obj);
            break;

        case MSG_CONTENT_DATA:
            commitLoad();
            break;

        case MSG_CONTENT_ERROR:
            handleError(msg.arg1, (String) msg.obj);
            break;

    }
}

 

打断点跟, 哪个thread call headers(), 哪个thread call handleHeaders().

 

可以看到是http thread执行的LoadListener.java ---> headers().

image_thumb1

是WebViewCoreThread 执行的LoadListener.java ---> handleHeaders().

image_thumb3

 

打断点跟, 数据是怎么从http thread 到 browser thread的.

http thread 执行LoadListener.java ---> data(byte[] data, int length).

image_thumb5

WebViewCoreThread 执行commitLoad().

image_thumb8

private void commitLoad() {
       
// Give the data to WebKit now.
        ByteArrayBuilder.Chunk c;
        while (true) {
            c = mDataBuilder.getFirstChunk();
            if (c == null) break;
            if (c.mLength != 0) {
               
nativeAddData(c.mArray, c.mLength);
            } else {
                c.release();
            }
        }
}

调用jni接口nativeAddData(byte[] data, int length); 把mDataBuilder中的数据传给webkit做底层的处理.

 

2011年最后一天, 做个技术上的收尾.

 

 

posted @ 2013-03-04 11:09  webkit_android  阅读(323)  评论(0编辑  收藏  举报