展会信息港展会大全

android4.0 webkit 请求网络数据的调用流程
来源:互联网   发布日期:2015-10-02 21:35:40   浏览:1919次  

导读:1. PassRefPtrResourceLoaderAndroid ResourceLoaderAndroid::start( ResourceHandle* handle, const ResourceRequest request, FrameLoaderClient* client, bool isMainResource, bool isSync) { // Called on main thread FrameLoaderClientAndroid* clien...

1.

PassRefPtr<ResourceLoaderAndroid> ResourceLoaderAndroid::start(

ResourceHandle* handle, const ResourceRequest& request, FrameLoaderClient* client, bool isMainResource, bool isSync)

{

// Called on main thread

FrameLoaderClientAndroid* clientAndroid = static_cast<FrameLoaderClientAndroid*>(client);

#if USE(CHROME_NETWORK_STACK)

WebViewCore* webViewCore = WebViewCore::getWebViewCore(clientAndroid->getFrame()->view());

bool isMainFrame = !(clientAndroid->getFrame()->tree() && clientAndroid->getFrame()->tree()->parent());

return WebUrlLoader::start(client, handle, request, isMainResource, isMainFrame, isSync, webViewCore->webRequestContext());

#else

return clientAndroid->webFrame()->startLoadingResource(handle, request, isMainResource, isSync);

#endif

}

2.

PassRefPtr<WebCore::ResourceLoaderAndroid>

WebFrame::startLoadingResource(WebCore::ResourceHandle* loader,

const WebCore::ResourceRequest& request,

bool mainResource,

bool synchronous)

{

#ifdef ANDROID_INSTRUMENT

TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);

#endif

LOGV("::WebCore:: startLoadingResource(%p, %s)",

loader, request.url().string().latin1().data());

JNIEnv* env = getJNIEnv();

AutoJObject javaFrame = mJavaFrame->frame(env);

if (!javaFrame.get())

return 0;

WTF::String method = request.httpMethod();

WebCore::HTTPHeaderMap headers = request.httpHeaderFields();

WTF::String urlStr = request.url().string();

int colon = urlStr.find(':');

bool allLower = true;

for (int index = 0; index < colon; index++) {

UChar ch = urlStr[index];

if (!WTF::isASCIIAlpha(ch))

break;

allLower &= WTF::isASCIILower(ch);

if (index == colon - 1 && !allLower) {

urlStr = urlStr.substring(0, colon).lower()

+ urlStr.substring(colon);

}

}

LOGV("%s lower=%s", __FUNCTION__, urlStr.latin1().data());

jstring jUrlStr = wtfStringToJstring(env, urlStr);

jstring jMethodStr = NULL;

if (!method.isEmpty())

jMethodStr = wtfStringToJstring(env, method);

WebCore::FormData* formdata = request.httpBody();

jbyteArray jPostDataStr = getPostData(request);

jobject jHeaderMap = createJavaMapFromHTTPHeaders(env, headers);

// Convert the WebCore Cache Policy to a WebView Cache Policy.

int cacheMode = 0;// WebSettings.LOAD_NORMAL

switch (request.cachePolicy()) {

case WebCore::ReloadIgnoringCacheData:

cacheMode = 2; // WebSettings.LOAD_NO_CACHE

break;

case WebCore::ReturnCacheDataDontLoad:

cacheMode = 3; // WebSettings.LOAD_CACHE_ONLY

break;

case WebCore::ReturnCacheDataElseLoad:

cacheMode = 1;// WebSettings.LOAD_CACHE_ELSE_NETWORK

break;

case WebCore::UseProtocolCachePolicy:

default:

break;

}

LOGV("::WebCore:: startLoadingResource %s with cacheMode %d", urlStr.ascii().data(), cacheMode);

ResourceHandleInternal* loaderInternal = loader->getInternal();

jstring jUsernameString = loaderInternal->m_user.isEmpty() ?

NULL : wtfStringToJstring(env, loaderInternal->m_user);

jstring jPasswordString = loaderInternal->m_pass.isEmpty() ?

NULL : wtfStringToJstring(env, loaderInternal->m_pass);

bool isUserGesture = UserGestureIndicator::processingUserGesture();

jobject jLoadListener =

env->CallObjectMethod(javaFrame.get(), mJavaFrame->mStartLoadingResource,

(int)loader, jUrlStr, jMethodStr, jHeaderMap,

jPostDataStr, formdata ? formdata->identifier(): 0,

cacheMode, mainResource, isUserGesture,

synchronous, jUsernameString, jPasswordString);

env->DeleteLocalRef(jUrlStr);

env->DeleteLocalRef(jMethodStr);

env->DeleteLocalRef(jPostDataStr);

env->DeleteLocalRef(jHeaderMap);

env->DeleteLocalRef(jUsernameString);

env->DeleteLocalRef(jPasswordString);

if (checkException(env))

return 0;

PassRefPtr<WebCore::ResourceLoaderAndroid> h;

if (jLoadListener)

h = WebCoreResourceLoader::create(env, jLoadListener);

env->DeleteLocalRef(jLoadListener);

return h;

}

3.

/**

* Start loading a resource.

* @param loaderHandle The native ResourceLoader that is the target of the

*data.

* @param url The url to load.

* @param method The http method.

* @param headers The http headers.

* @param postData If the method is "POST" postData is sent as the request

*body. Is null when empty.

* @param postDataIdentifier If the post data contained form this is the form identifier, otherwise it is 0.

* @param cacheMode The cache mode to use when loading this resource. See WebSettings.setCacheMode

* @param mainResource True if the this resource is the main request, not a supporting resource

* @param userGesture

* @param synchronous True if the load is synchronous.

* @return A newly created LoadListener object.

*/

private LoadListener startLoadingResource(int loaderHandle,

String url,

String method,

HashMap headers,

byte[] postData,

long postDataIdentifier,

int cacheMode,

boolean mainResource,

boolean userGesture,

boolean synchronous,

String username,

String password) {

PerfChecker checker = new PerfChecker();

if (mSettings.getCacheMode() != WebSettings.LOAD_DEFAULT) {

cacheMode = mSettings.getCacheMode();

}

if (method.equals("POST")) {

// Don't use the cache on POSTs when issuing a normal POST

// request.

if (cacheMode == WebSettings.LOAD_NORMAL) {

cacheMode = WebSettings.LOAD_NO_CACHE;

}

String[] ret = getUsernamePassword();

if (ret != null) {

String domUsername = ret[0];

String domPassword = ret[1];

maybeSavePassword(postData, domUsername, domPassword);

}

}

// is this resource the main-frame top-level page?

boolean isMainFramePage = mIsMainFrame;

if (DebugFlags.BROWSER_FRAME) {

Log.v(LOGTAG, "startLoadingResource: url=" + url + ", method="

+ method + ", postData=" + postData + ", isMainFramePage="

+ isMainFramePage + ", mainResource=" + mainResource

+ ", userGesture=" + userGesture);

}

// Create a LoadListener

LoadListener loadListener = LoadListener.getLoadListener(mContext,

this, url, loaderHandle, synchronous, isMainFramePage,

mainResource, userGesture, postDataIdentifier, username, password);

if (LoadListener.getNativeLoaderCount() > MAX_OUTSTANDING_REQUESTS) {

// send an error message, so that loadListener can be deleted

// after this is returned. This is important as LoadListener's

// nativeError will remove the request from its DocLoader's request

// list. But the set up is not done until this method is returned.

loadListener.error(

android.net.http.EventHandler.ERROR, mContext.getString(

com.android.internal.R.string.httpErrorTooManyRequests));

return loadListener;

}

// Note that we are intentionally skipping

// inputStreamForAndroidResource.This is so that FrameLoader will use

// the various StreamLoader classes to handle assets.

FrameLoader loader = new FrameLoader(loadListener, mSettings, method,

mCallbackProxy.shouldInterceptRequest(url));

loader.setHeaders(headers);

loader.setPostData(postData);

// Set the load mode to the mode used for the current page.

// If WebKit wants validation, go to network directly.

loader.setCacheMode(headers.containsKey("If-Modified-Since")

|| headers.containsKey("If-None-Match") ?

WebSettings.LOAD_NO_CACHE : cacheMode);

// Set referrer to current URL?

if (!loader.executeLoad()) {

checker.responseAlert("startLoadingResource fail");

}

checker.responseAlert("startLoadingResource succeed");

return !synchronous ? loadListener : null;

}

4.

/**

* Issues the load request.

*

* Return value does not indicate if the load was successful or not. It

* simply indicates that the load request is reasonable.

*

* @return true if the load is reasonable.

*/

public boolean executeLoad() {

String url = mListener.url();

// Process intercepted requests first as they could be any url.

if (mInterceptResponse != null) {

if (mListener.isSynchronous()) {

mInterceptResponse.loader(mListener).load();

} else {

WebViewWorker.getHandler().obtainMessage(

WebViewWorker.MSG_ADD_STREAMLOADER,

mInterceptResponse.loader(mListener)).sendToTarget();

}

return true;

} else if (URLUtil.isNetworkUrl(url)){

if (mSettings.getBlockNetworkLoads()) {

mListener.error(EventHandler.ERROR_BAD_URL,

mListener.getContext().getString(

com.android.internal.R.string.httpErrorBadUrl));

return false;

}

// Make sure the host part of the url is correctly

// encoded before sending the request

if (!URLUtil.verifyURLEncoding(mListener.host())) {

mListener.error(EventHandler.ERROR_BAD_URL,

mListener.getContext().getString(

com.android.internal.R.string.httpErrorBadUrl));

return false;

}

mNetwork = Network.getInstance(mListener.getContext());

if (mListener.isSynchronous()) {

return handleHTTPLoad();

}

WebViewWorker.getHandler().obtainMessage(

WebViewWorker.MSG_ADD_HTTPLOADER, this).sendToTarget();

return true;

} else if (handleLocalFile(url, mListener, mSettings)) {

return true;

}

if (DebugFlags.FRAME_LOADER) {

Log.v(LOGTAG, "FrameLoader.executeLoad: url protocol not supported:"

+ mListener.url());

}

mListener.error(EventHandler.ERROR_UNSUPPORTED_SCHEME,

mListener.getContext().getText(

com.android.internal.R.string.httpErrorUnsupportedScheme).toString());

return false;

}

5.

boolean handleHTTPLoad() {

if (mHeaders == null) {

mHeaders = new HashMap<String, String>();

}

populateStaticHeaders();

populateHeaders();

// response was handled by Cache, don't issue HTTP request

if (handleCache()) {

// push the request data down to the LoadListener

// as response from the cache could be a redirect

// and we may need to initiate a network request if the cache

// can't satisfy redirect URL

mListener.setRequestData(mMethod, mHeaders, mPostData);

return true;

}

if (DebugFlags.FRAME_LOADER) {

Log.v(LOGTAG, "FrameLoader: http " + mMethod + " load for: "

+ mListener.url());

}

boolean ret = false;

int error = EventHandler.ERROR_UNSUPPORTED_SCHEME;

try {

ret = mNetwork.requestURL(mMethod, mHeaders,

mPostData, mListener);

} catch (android.net.ParseException ex) {

error = EventHandler.ERROR_BAD_URL;

} catch (java.lang.RuntimeException ex) {

/* probably an empty header set by javascript.We want

the same result as bad URL*/

error = EventHandler.ERROR_BAD_URL;

}

if (!ret) {

mListener.error(error, ErrorStrings.getString(error, mListener.getContext()));

return false;

}

return true;

}

6.

/**

* Request a url from either the network or the file system.

* @param url The url to load.

* @param method The http method.

* @param headers The http headers.

* @param postData The body of the request.

* @param loader A LoadListener for receiving the results of the request.

* @return True if the request was successfully queued.

*/

public boolean requestURL(String method,

Map<String, String> headers,

byte [] postData,

LoadListener loader) {

String url = loader.url();

// Not a valid url, return false because we won't service the request!

if (!URLUtil.isValidUrl(url)) {

return false;

}

// asset, res, file system or data stream are handled in the other code

// path. This only handles network request.

if (URLUtil.isAssetUrl(url) || URLUtil.isResourceUrl(url)

|| URLUtil.isFileUrl(url) || URLUtil.isDataUrl(url)) {

return false;

}

// If this is a prefetch, abort it if we're roaming.

if (mRoaming && headers.containsKey("X-Moz") && "prefetch".equals(headers.get("X-Moz"))) {

return false;

}

/* FIXME: this is lame.Pass an InputStream in, rather than

making this lame one here */

InputStream bodyProvider = null;

int bodyLength = 0;

if (postData != null) {

bodyLength = postData.length;

bodyProvider = new ByteArrayInputStream(postData);

}

RequestQueue q = mRequestQueue;

RequestHandle handle = null;

if (loader.isSynchronous()) {

handle = q.queueSynchronousRequest(url, loader.getWebAddress(),

method, headers, loader, bodyProvider, bodyLength);

loader.attachRequestHandle(handle);

handle.processRequest();

loader.loadSynchronousMessages();

} else {

handle = q.queueRequest(url, loader.getWebAddress(), method,

headers, loader, bodyProvider, bodyLength);

// FIXME: Although this is probably a rare condition, normal network

// requests are processed in a separate thread. This means that it

// is possible to process part of the request before setting the

// request handle on the loader. We should probably refactor this to

// ensure the handle is attached before processing begins.

loader.attachRequestHandle(handle);

}

return true;

}

作者:lihui130135

赞助本站

人工智能实验室

相关热词: android开发 教程

相关内容
AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港