热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在PhoneGap应用中拦截CordovaWebView的url

最近在用PhoneGap做混合应用,遇到了一个比较奇葩的需求,客户公司原先做了一个触屏版的webapp,之后又开始做的手机app,公司决定用PhoneGap开发,可以利用一些webapp页面,为

最近在用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调用系统浏览器或第三方浏览器
        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了,今天就写到这里了,下班回家吃饭

推荐阅读
  • 为什么三角形与菜单背景的颜色不同? - Why is the triangle a different colour shade to the menu background?
    Imnotunderstandingastowhythetrianglewhichappearswhenthemousehoversoverthemenuitem, ... [详细]
  • 我收到这个错误.我怎么能在我的情况下解决这个问题?Bitmapcannotberesolvedtoatype发生错误的行publicvoidonPageStart ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了css回到顶部按钮相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 涉及的知识点-ViewGroup的测量与布局-View的测量与布局-滑动冲突的处理-VelocityTracker滑动速率跟踪-Scroller实现弹性滑动-屏幕宽高的获取等实现步 ... [详细]
  • html结构 ... [详细]
  • 本文实例讲述了Android编程实现读取工程中的txt文件功能。分享给大家供大家参考,具体如下:1.众所周知,Android的res文件夹 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
author-avatar
手机用户2502859733
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有