Android快速去掉WebView上的煩人廣告

近日,在把某網(wǎng)站用WebView打包到App里面的時候,出現(xiàn)的一個麻煩??聪聢D


廣告

額,有廣告。不影響閱讀體驗的廣告都是可以接受的。但是有一問題是因為有一個廣告div比屏幕要大,導致該網(wǎng)頁在在移動端上可以左右滑動,這個就沒法忍受了,看下圖


廣告

沒辦法了,只能把廣告去掉了.
首先看看集成網(wǎng)頁的代碼.
private WebView webView;
private WebSettings settings;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.activity_main);
    webView = (WebView) findViewById(web);
    //設置WebView屬性,能夠執(zhí)行Javascript腳本
    settings = webView.getSettings();
    settings.setJavaScriptEnabled(true);
    settings.setAppCacheEnabled(true);
    webView.setWebViewClient(new NoAdWebViewClient());
    //加載需要顯示的網(wǎng)頁
    webView.loadUrl("http://champion.gg/");

}

為了支持離線瀏覽,打開了WebView的默認緩存,設置支持js支持,設置WebClient,這里的NoAdWebViewClient在下面可以看到,在WebViewClient里面去掉廣告.

@Override
//設置回退
//覆蓋Activity類的onKeyDown(int keyCoder,KeyEvent event)方法
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
        webView.goBack(); //goBack()表示返回WebView的上一頁面
        return true;
    }
    return false;
}

重寫Activity的onKeyDown簡單back案件,當網(wǎng)頁可以back的時候讓網(wǎng)頁回到上一頁面.
來看一下NoAdWebViewClient的關鍵代碼:
繼承系統(tǒng)的WebViewClient,然后重寫onPageFinished方法。

package com.jelly.championgg;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import android.webkit.WebView;
import android.webkit.WebViewClient;

/**
 * Created by BrainWang on 05/01/2016.
 */
public class NoAdWebViewClient extends WebViewClient {
    
    private Context context;    

    public NoAdWebViewClient(Context context) {
        this.context = context;
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        String js = ADFilterTool.getClearAdDivJs(context);
        Log.v("adJs",js);
        view.loadUrl(js);
    }

}

在onPageFinished里面外面執(zhí)行的了一段Js,來看一看這段js(以下js為了方便閱讀,經(jīng)過整理):

javascript:
var adDiv0= document.getElementById('div-gpt-ad-1443488528500-4');
if(adDiv0 != null)
    adDiv0.parentNode.removeChild(adDiv0);

var adDiv1= document.getElementById('div-gpt-ad-1443727656867-1');
if(adDiv1 != null)
    adDiv1.parentNode.removeChild(adDiv1);

var adDiv2= document.getElementById('div-gpt-ad-1443488528500-5');
if(adDiv2 != null)
    adDiv2.parentNode.removeChild(adDiv2);
...

去掉廣告的原理很簡單,注入一段js把顯示廣告的div刪除就ok了,來看一下生成js的代碼:

    public static String getClearAdDivJs(Context context){
    String js = "javascript:";
    Resources res = context.getResources();
    String[] adDivs = res.getStringArray(R.array.adBlockDiv);
    for(int i=0;i<adDivs.length;i++){

        js += "var adDiv"+i+"= document.getElementById('"+adDivs[i]+"');if(adDiv"+i+" != null)adDiv"+i+".parentNode.removeChild(adDiv"+i+");";
    }
    return js;
}

通過arrays.xml去管理去要去掉的廣告div,遍歷廣告divId的集合,組合成一段js代碼,注入到網(wǎng)頁中去掉廣告.

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string-array name="adBlockDiv">
        <item>div-gpt-ad-1443488528500-4</item>
        <item>div-gpt-ad-1443727656867-1</item>
        <item>div-gpt-ad-1443488528500-5</item>
        <item>div-gpt-ad-1443488528500-6</item>
        <item>div-gpt-ad-1443488528500-7</item>
        <item>div-gpt-ad-1443727656867-0</item>
        <item>div-gpt-ad-1443488528500-2</item>
        <item>div-gpt-ad-1443488528500-3</item>
        <item>div-gpt-ad-1443488528500-1</item>
    </string-array>

</resources>

那么這些廣告div的Id是如何獲取的呢?我們通過Chrome瀏覽器可以很方便的獲取到這些Id,可以看到通過F12的調試模式可以輕易的獲取到廣告div的Id


獲取廣告ID

完成后我們就可以看到?jīng)]有廣告的頁面了,完成效果。


最后效果

其實這里還有一個問題,當網(wǎng)絡比較慢的情況下,我們的網(wǎng)頁會一直加載,然后當還沒有調用onPageFinished的時候,用戶就已經(jīng)開始操作了,所以我們可以優(yōu)化一下這種方式:
package com.jelly.championgg;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.webkit.WebView;
import android.webkit.WebViewClient;

/**
 * Created by BrainWang on 05/01/2016.
 */
public class NoAdWebViewClient extends WebViewClient {
    private Context context;
    private WebView webView;
    private boolean isClose;

    public NoAdWebViewClient(Context context,WebView webView) {
        this.context = context;
        this.webView = webView;
    }


    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        super.onPageStarted(view, url, favicon);
        if(isClose){ //如果線程正在運行就不用重新開啟一個線程了
            return;
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                isClose = true;
                while (isClose){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    handler.sendEmptyMessage(0x001);
                }
            }
        }).start();
    }

    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            String js = ADFilterTool.getClearAdDivJs(context);
            Log.v("adJs",js);
            webView.loadUrl(js);
        }
    };

    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        isClose = false;
    }

}

在NoAdWebViewClient里面我們重寫onPageStarted方法,并且開啟一個線程,每1秒的循環(huán)注入js,在這里由于不能在子線程里面操作WebView,所以利用Handler去注入js.并且在onPageFinished內關閉線程.這樣之后,即使網(wǎng)絡很慢,在沒有回調onPageFinished的時候,也不會出現(xiàn)廣告了。

代碼地址

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容