Android瀏覽器開發 WebView setBlockNetworkImage來龍去脈
阿新 • • 發佈:2019-02-12
本身含義阻止圖片網路資料
webSettings.setBlockNetworkImage(true);
解除資料阻止
webSettings.setBlockNetworkImage(false);
實際上簡單的一句話為什麼會造成這麼強大的功力
我們來看下具體的實現
WebSettingsClassic.java
/**
* @see android.webkit.WebSettings#setBlockNetworkImage(boolean)
*/
@Override
public synchronized void setBlockNetworkImage(boolean flag) {
if (mBlockNetworkImage != flag) {
mBlockNetworkImage = flag;
postSync();
}
}
關鍵程式碼看上去只有
mBlockNetworkImage = flag;
但是不要忽略了
postSync();
這個就是通知c++層去讀取mBlockNetworkImage數值
我們看下具體的postSync函式實現
/* Post a SYNC message to handle syncing the native settings. */
private synchronized void postSync() {
// Only post if a sync is not pending
if (!mSyncPending) {
mSyncPending = mEventHandler.sendMessage(
Message.obtain(null, EventHandler.SYNC));
}
}
通知給
// create a new handler
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SYNC:
synchronized (WebSettingsClassic.this) {
if (mBrowserFrame.mNativeFrame != 0) {
nativeSync(mBrowserFrame.mNativeFrame);
}
mSyncPending = false;
}
break;
// Synchronize the native and java settings.
private native void nativeSync(int nativeFrame);
最後呼叫的函式
c++底層函式實現
WebKit/android/jni/WebSettings.cpp
//-------------------------------------------------------------
// JNI registration
//-------------------------------------------------------------
static JNINativeMethod gWebSettingsMethods[] = {
{ "nativeSync", "(I)V",
(void*) WebSettings::Sync }
};
static void Sync(JNIEnv* env, jobject obj, jint frame)
{
WebCore::Frame* pFrame = (WebCore::Frame*)frame;
ALOG_ASSERT(pFrame, "%s must take a valid frame pointer!", __FUNCTION__);
WebCore::Settings* s = pFrame->settings();
if (!s)
return;
WebCore::CachedResourceLoader* cachedResourceLoader = pFrame->document()->cachedResourceLoader();
flag = env->GetBooleanField(obj, gFieldIds->mBlockNetworkImage);
s->setBlockNetworkImage(flag);
if(!flag)
cachedResourceLoader->setBlockNetworkImage(false);
}
具體實現
CachedResourceLoader.cpp裡面
void CachedResourceLoader::setBlockNetworkImage(bool block)
{
if (block == m_blockNetworkImage)
return;
m_blockNetworkImage = block;
if (!m_autoLoadImages || m_blockNetworkImage)
return;
DocumentResourceMap::iterator end = m_documentResources.end();
for (DocumentResourceMap::iterator it = m_documentResources.begin(); it != end; ++it) {
CachedResource* resource = it->second.get();
if (resource->type() == CachedResource::ImageResource) {
CachedImage* image = const_cast<CachedImage*>(static_cast<const CachedImage*>(resource));
image->setAutoLoadWasPreventedBySettings(false);
if (image->stillNeedsLoad()) {
image->setLoading(true);
load(image, true);
}
}
}
}
終於找到這個傢伙了,原來搞了一個迴圈在呼呼的執行,傳送一個個的網路請求
整體執行流程現在來看基本清晰了。
webSettings.setBlockNetworkImage(true);
解除資料阻止
webSettings.setBlockNetworkImage(false);
實際上簡單的一句話為什麼會造成這麼強大的功力
我們來看下具體的實現
WebSettingsClassic.java
/**
* @see android.webkit.WebSettings#setBlockNetworkImage(boolean)
*/
@Override
public synchronized void setBlockNetworkImage(boolean flag) {
if (mBlockNetworkImage != flag) {
mBlockNetworkImage = flag;
postSync();
}
}
關鍵程式碼看上去只有
mBlockNetworkImage = flag;
但是不要忽略了
postSync();
這個就是通知c++層去讀取mBlockNetworkImage數值
我們看下具體的postSync函式實現
/* Post a SYNC message to handle syncing the native settings. */
private synchronized void postSync() {
// Only post if a sync is not pending
if (!mSyncPending) {
mSyncPending = mEventHandler.sendMessage(
Message.obtain(null, EventHandler.SYNC));
}
}
通知給
// create a new handler
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SYNC:
synchronized (WebSettingsClassic.this) {
if (mBrowserFrame.mNativeFrame != 0) {
nativeSync(mBrowserFrame.mNativeFrame);
}
mSyncPending = false;
}
break;
// Synchronize the native and java settings.
private native void nativeSync(int nativeFrame);
最後呼叫的函式
c++底層函式實現
WebKit/android/jni/WebSettings.cpp
//-------------------------------------------------------------
// JNI registration
//-------------------------------------------------------------
static JNINativeMethod gWebSettingsMethods[] = {
{ "nativeSync", "(I)V",
(void*) WebSettings::Sync }
};
static void Sync(JNIEnv* env, jobject obj, jint frame)
{
WebCore::Frame* pFrame = (WebCore::Frame*)frame;
ALOG_ASSERT(pFrame, "%s must take a valid frame pointer!", __FUNCTION__);
WebCore::Settings* s = pFrame->settings();
if (!s)
return;
WebCore::CachedResourceLoader* cachedResourceLoader = pFrame->document()->cachedResourceLoader();
flag = env->GetBooleanField(obj, gFieldIds->mBlockNetworkImage);
s->setBlockNetworkImage(flag);
if(!flag)
cachedResourceLoader->setBlockNetworkImage(false);
}
具體實現
CachedResourceLoader.cpp裡面
void CachedResourceLoader::setBlockNetworkImage(bool block)
{
if (block == m_blockNetworkImage)
return;
m_blockNetworkImage = block;
if (!m_autoLoadImages || m_blockNetworkImage)
return;
DocumentResourceMap::iterator end = m_documentResources.end();
for (DocumentResourceMap::iterator it = m_documentResources.begin(); it != end; ++it) {
CachedResource* resource = it->second.get();
if (resource->type() == CachedResource::ImageResource) {
CachedImage* image = const_cast<CachedImage*>(static_cast<const CachedImage*>(resource));
image->setAutoLoadWasPreventedBySettings(false);
if (image->stillNeedsLoad()) {
image->setLoading(true);
load(image, true);
}
}
}
}
終於找到這個傢伙了,原來搞了一個迴圈在呼呼的執行,傳送一個個的網路請求
整體執行流程現在來看基本清晰了。
上面程式碼是針對android4.1.1版本程式碼的分析
如果對這篇講的技術有任何疑問,第一時間獲得文章更新,每天釋出一篇技術大牛的原創文章,更多技術資訊分享。
歡迎關注個人微信公眾平臺:程式設計師互動聯盟,掃一掃下方二維碼或搜尋微訊號coder_online即可關注,線上幫您解決技術難點,給大牛直接出難題。
聯絡方式
QQ:390012381
微信:donghuitalk