在PhoneGap应用中拦截CordovaWebView的url

最近在用PhoneGap做混合应用,遇到了一个比较奇葩的需求,客户公司原先做了一个触屏版的webapp,之后又开始做的手机app,公司决定用PhoneGap开发,可以利用一些webapp页面,为了解决不让app变成一个浏览器页面随便跳,所以出来了这个需求:在PhoneGap中对web页面上的链接进行拦截。

思路:

通常在android的webView中可以采用设置webViewClient的方法拦截

/**
 * 返回true意味着宿主应用程序处理URL,则返回false意味着目前的WebView处理URL
 */
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
	//返回值是true的时候控制去WebView打开,为false调用系统浏览器或第三方浏览器
<pre name="code" class="java">        url="www.baidu.com";
        view.loadUrl(url);
 Log.i("URL", "URL改变了");return true;}

 具体的操作网上有很多讲解,这里就不多说了,主要说明一点,我用了这个方法结果项目出问题了,总是提示连接失败。 

于是我开始看源码,看看cordova到底是如何工作的,我的版本是cordova-2.9.0。

下面是相关源码:

package org.apache.cordova;

public class DroidGap extends CordovaActivity
{
}
MainActivity继承的DroidGap只是一个空壳,进入CordovaActivity看看究竟,源码很多,稍微贴点

package org.apache.cordova;

import...

public class CordovaActivity extends Activity
  implements CordovaInterface
{
  public static String TAG = "CordovaActivity";
  protected CordovaWebView appView;
  protected CordovaWebViewClient webViewClient;
上面的代码是CordovaActivity类的开头部分,引入的包被我略去了,下面是进入关键代码

  public void loadUrl(String url)
  {
    if (this.appView == null) {
      init();
    }

    this.backgroundColor = getIntegerProperty("backgroundColor", -16777216);
    this.root.setBackgroundColor(this.backgroundColor);

    this.keepRunning = getBooleanProperty("keepRunning", true);

    loadSpinner();

    this.appView.loadUrl(url);
  }
上面的函数就是android在MainActivity中引入html页面调用的loadUrl方法,下面是MainActivity中的oncreate()方法

@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.init();
		super.loadUrl("file:///android_asset/www/html/index.html", 2500);
	}
从源码的loadUrl方法中执行了一个init()方法,那我们去看看到底都干了些什么

  public void init()
  {
    CordovaWebView webView = new CordovaWebView(this);
    CordovaWebViewClient webViewClient;
    CordovaWebViewClient webViewClient;
    if (Build.VERSION.SDK_INT < 11)
    {
      webViewClient = new CordovaWebViewClient(this, webView);
    }
    else
    {
      webViewClient = new IceCreamCordovaWebViewClient(this, webView);
    }
    init(webView, webViewClient, new CordovaChromeClient(this, webView));
  }

  @SuppressLint({"NewApi"})
  public void init(CordovaWebView webView, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient)
  {
    LOG.d(TAG, "CordovaActivity.init()");

    this.appView = webView;
    this.appView.setId(100);

    this.appView.setWebViewClient(webViewClient);
    this.appView.setWebChromeClient(webChromeClient);
    webViewClient.setWebView(this.appView);
    webChromeClient.setWebView(this.appView);

    this.appView.setLayoutParams(new LinearLayout.LayoutParams(-1, -1, 1.0F));

    if ((getBooleanProperty("disallowOverscroll", false)) && 
      (Build.VERSION.SDK_INT >= 9)) {
      this.appView.setOverScrollMode(2);
    }

    this.appView.setVisibility(4);
    this.root.addView(this.appView);
    setContentView(this.root);

    this.cancelLoadUrl = false;
  }
在init()的刚开始出现的 CordovaWebView就是我们显示html的控件,它继承自webView。

从之后的代码可以看出在初始化的时候给 CordovaWebView 设置了 CordovaWebViewClient,它继承自WebViewClient,这个在webView中对应的就是在文章刚开始提到的webViewClient(上面已蓝色显示),于是去CordovaWebViewClient里面看看有什么吧。源代码又很多,但是在里面发现了下面这个方法

public boolean shouldOverrideUrlLoading(WebView view, String url)
是不是很眼熟?这个方法和文章刚开始提到的webView中拦截url的方法一样,这是不是就意味着我可以用这个方法去拦截呢?下面开始尝试拦截。

由于CordovaWebViewClient里面的shouldOverrideUrlLoading不是我想要的功能,于是我重写了CordovaWebViewClient

package com.example.opalbb.tools;

import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaWebViewClient;
import org.apache.cordova.api.CordovaInterface;

import android.util.Log;
import android.webkit.WebView;

public class MyCordovaWebViewClient extends CordovaWebViewClient {

	public MyCordovaWebViewClient(CordovaInterface cordova) {
		super(cordova);
		// TODO Auto-generated constructor stub
	}

	public MyCordovaWebViewClient(CordovaInterface cordova, CordovaWebView view) {
		super(cordova, view);
		// TODO Auto-generated constructor stub
	}

	@Override
	public boolean shouldOverrideUrlLoading(WebView view, String url) {
		Log.i("在这里可以修改url", url);
		view.loadUrl(url);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return true;
	}
}
到这里似乎可以试一试拦截的效果了,先别着急,我们如何让 CordovaWebView 使用我们自己写的MyCordovaWebViewClient类呢?下面的代码是我修改了CordovaWebView的初始化函数,其实就是把上面MainActivity中的super.init()替换成下面的代码

@Override
	public void init() {
		CordovaWebView webView = new CordovaWebView(this);
		MyCordovaWebViewClient webViewClient;
		webViewClient = new MyCordovaWebViewClient(this, webView);
		init(webView, webViewClient, new CordovaChromeClient(this, webView));
	}
@Override
	public void init(CordovaWebView webView, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient) {
		LOG.d(TAG, "CordovaActivity.init()");

		this.appView = webView;
		this.appView.setId(100);

		this.appView.setWebViewClient(webViewClient);
		this.appView.setWebChromeClient(webChromeClient);
		webViewClient.setWebView(this.appView);
		webChromeClient.setWebView(this.appView);

		this.appView.setLayoutParams(new LinearLayout.LayoutParams(-1, -1, 1.0F));

		if ((getBooleanProperty("disallowOverscroll", false)) && (Build.VERSION.SDK_INT >= 9)) {
			this.appView.setOverScrollMode(2);
		}

		this.appView.setVisibility(4);
		this.root.addView(this.appView);
		setContentView(this.root);

		this.cancelLoadUrl = false;
	}
其他代码都不用改,开始运行,就可以看出我们刚才代码中的Log了,我的代码已经完成了,就不还原回去运行了,但是保证这样就可以拦截CordovaWebView的url了,今天就写到这里了,下班回家吃饭

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值