博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android WebView与JavaScript交互操作(Demo)
阅读量:7125 次
发布时间:2019-06-28

本文共 9776 字,大约阅读时间需要 32 分钟。

应用场景:

       为了使Android移动项目能够在较短的时间内完成开发,同时降低技术人员开发的成本投入,往往会采用Hybrid APP的开发模式。相关Hybrid APP(混合型应用)参看:http://blog.csdn.net/mahoking/article/details/30235243 采用这种模式,为了解决更好的用户体验,可访问本地资源的能力。势必需要了解与掌握Android(java)与JavaScript之间的交互、相互调用操作的方法与技术。

【转载使用,请注明出处: 】

知识点介绍:

 

        本文重要的知识点补充是WebView对象(android.webkit.WebView)。

在Android手机中内置了一款高性能webkit内核浏览器,在Android SDK中封装为一个叫做WebView组件。 

WebKit是Mac OS X v10.3及以上版本所包含的软件框架(对v10.2.7及以上版本也可通过软件更新获取)。 同时,WebKit也是Mac OS X的Safari网页浏览器的基础。WebKit是一个开源项目,主要由KDE的KHTML修改而来并且包含了一些来自苹果公司的一些组件。 

传统上,WebKit包含一个网页引擎WebCore和一个脚本引擎JavaScriptCore,它们分别对应的是KDE的KHTML和KJS。不过, 随着JavaScript引擎的独立性越来越强,现在WebKit和WebCore已经基本上混用不分(例如Google Chrome和Maxthon 3采用V8引擎,却仍然宣称自己是WebKit内核)。

【注意事项】

1.AndroidManifest.xml中必须使用许可"android.permission.INTERNET",否则会出Web page not available错误。

2.如果访问的页面中有Javascript,则webview必须设置支持Javascript。webview.getSettings().setJavaScriptEnabled(true);  

3.如果页面中链接,如果希望点击链接继续在当前browser中响应,而不是新开Android的系统browser中响应该链接,必须覆盖 webview的WebViewClient对象。

4.对于第一点, 如果使用Android SDK提供了一个schema,前缀为"file:///android_asset/"。WebView遇到这样的schema,会去加载assets目录下的资源。如"file:///android_asset/demo.html",可不必使用许可"android.permission.INTERNET"。

        在使用WebView组件的过程中可能会接触到WebViewClient与WebChromeClient,那么这两个类到底有什么不同呢?

         WebViewClient主要帮助WebView处理各种通知、请求事件的,比如:

onLoadResource

onPageStart

onPageFinish

onReceiveError 等

         WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等比如:

onCloseWindow(关闭WebView)

onCreateWindow()

onJsAlert (WebView上alert无效,需要定制WebChromeClient处理弹出)

onJsPrompt

onJsConfirm

onReceivedTitle等

         两者存在很多的差别,在实际使用过程中,如果你只准备让WebView处理一些html的页面内容,只用WebViewClient就可以了,如果需要产生更丰富的处理效果,比如JS对话框、进度条等,就要使用到WebChromeClient。更进一步的介绍将在下面进行。

 

【转载使用,请注明出处: 】

使用方式:

第一步:

本文的演示程序的主界面为activity_web.xml,对应的Activtiy为WebActivtiy.java。

 

【activity_web.xml】

【WebActivtiy.java】

package cn.mahaochen.webviewtest;import cn.mahaochen.webviewtest.assist.ButtonListener;import cn.mahaochen.webviewtest.assist.MJavascriptInterface;import cn.mahaochen.webviewtest.assist.MWebChromeClient;import cn.mahaochen.webviewtest.assist.MWebViewClient;import android.os.Bundle;import android.app.Activity;import android.graphics.Color;import android.view.KeyEvent;import android.view.Menu;import android.webkit.WebView;import android.widget.Button;/** * @date 2014-6-20 * @author MaHaochen */public class WebActivity extends Activity {  private WebView webView;  private Button paramButton;  private Button noParamButton;    @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_web);    initViews();  }  private void initViews() {    webView = (WebView) findViewById(R.id.webView_web);    // 设置WebView对JavaScript的支持    webView.getSettings().setJavaScriptEnabled(true);    // 从assets目录下面的加载html    webView.loadUrl("file:///android_asset/web.html");    //自定义WebView的背景颜色    webView.setBackgroundColor(Color.TRANSPARENT);//先设置背景色为transparent//        webView.setBackgroundResource(R.drawable.webbg);//然后设置背景图片    webView.setBackgroundResource(R.drawable.bgcolorblue);//        webView.loadUrl("http://www.baidu.com");    MWebViewClient mWebViewClient = new MWebViewClient(webView,getApplicationContext());    webView.setWebViewClient(mWebViewClient);    MWebChromeClient mWebChromeClient = new MWebChromeClient(getApplicationContext());    webView.setWebChromeClient(mWebChromeClient);    //添加JS调用Android(Java)的方法接口    MJavascriptInterface mJavascriptInterface = new MJavascriptInterface(getApplicationContext());    webView.addJavascriptInterface(mJavascriptInterface, "WebViewFunc");        //初始化按钮,并绑定监听事件,事件的作用是调用JS的功能方法    noParamButton = (Button) findViewById(R.id.javaCallJs_web_button);    paramButton = (Button) findViewById(R.id.javaCallJsParam_web_button);    ButtonListener buttonListener = new ButtonListener(webView);    noParamButton.setOnClickListener(buttonListener);    paramButton.setOnClickListener(buttonListener);  }    /**   * 退出监听   */  @Override  public boolean dispatchKeyEvent(KeyEvent event) {      if (event.getKeyCode() == KeyEvent.KEYCODE_BACK          && event.getAction() == KeyEvent.ACTION_DOWN          && event.getRepeatCount() == 0          ) {        if(webView.canGoBack()){          webView.goBack();          return false;        }else {          WebActivity.this.finish();          return true;        }      }      return false;//        return super.dispatchKeyEvent(event);  }  //*******************华丽的分割线***********************  @Override  public boolean onCreateOptionsMenu(Menu menu) {//        getMenuInflater().inflate(R.menu.web, menu);    return true;  }}
第二步:

 

        从第一步可以看到,以上补充了分别继承自WebViewClient、WebChromeClient的MWebViewClient、MWebChromeClient对象和MJavascriptInterface、ButtonListener对象。对应的对象的相关方法与操作的介绍将会在代码中较详细的叙述。

 

【MWebViewClient.java】

package cn.mahaochen.webviewtest.assist;import android.content.Context;import android.graphics.Bitmap;import android.net.http.SslError;import android.util.Log;import android.webkit.SslErrorHandler;import android.webkit.WebView;import android.webkit.WebViewClient;import android.widget.Toast;/** * @date 2014-6-20 * @author MaHaochen */public class MWebViewClient  extends WebViewClient {  private WebView webView;  private Context context;    public MWebViewClient(WebView webView) {    super();    this.webView = webView;  }  public MWebViewClient(WebView webView, Context context) {    super();    this.webView = webView;    this.context = context;  }  /**   * 在点击请求的是链接是才会调用,   * 重写此方法返回true表明点击网页里面的链接还是在当前的webview里跳转,不跳到浏览器那边。   */  @Override  public boolean shouldOverrideUrlLoading(WebView view, String url) {    // 使用自己的WebView组件来响应Url加载事件,而不是使用默认浏览器器加载页面    webView.loadUrl(url);    // 记得消耗掉这个事件。给不知道的朋友再解释一下,Android中返回True的意思就是到此为止,    // 事件就会不会冒泡传递了,我们称之为消耗掉    return true;  }    @Override  public void onPageStarted(WebView view, String url, Bitmap favicon) {//        Toast.makeText(context, "WebViewClient.onPageStarted页面开始加载", Toast.LENGTH_SHORT).show();     Log.e("WebActivity", "页面加载开始");    super.onPageStarted(view, url, favicon);  }    @Override  public void onPageFinished(WebView view, String url) {//        Toast.makeText(context, "WebViewClient.onPageFinished页面加载完成", Toast.LENGTH_SHORT).show();     Log.e("WebActivity", "页面加载完成");    super.onPageFinished(view, url);  }    /**   * 在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。   */  @Override  public void onLoadResource(WebView view, String url) {//        Toast.makeText(context, "WebViewClient.onLoadResource", Toast.LENGTH_SHORT).show();     Log.e("WebActivity", "onLoadResource");    super.onLoadResource(view, url);  }    /**   * 重写此方法可以让webview处理https请求    [拓展]   */  @Override  public void onReceivedSslError(WebView view,      SslErrorHandler handler, SslError error) {    super.onReceivedSslError(view, handler, error);  }}

【MWebChromeClient.java】

package cn.mahaochen.webviewtest.assist;import android.app.Activity;import android.content.Context;import android.webkit.JsPromptResult;import android.webkit.JsResult;import android.webkit.WebChromeClient;import android.webkit.WebView;/** * @date 2014-6-20 * @author MaHaochen */public class MWebChromeClient extends WebChromeClient {  private Context context;    public MWebChromeClient(Context context) {    super();    this.context = context;  }  // 处理Alert事件  @Override  public boolean onJsAlert(WebView view, String url, String message,      JsResult result) {    return super.onJsAlert(view, url, message, result);  }  // onReceivedTitle()方法修改网页标题  @Override  public void onReceivedTitle(WebView view, String title) {    ((Activity)context).setTitle("可以用onReceivedTitle()方法修改网页标题");    super.onReceivedTitle(view, title);  }  // 处理Confirm事件  @Override  public boolean onJsConfirm(WebView view, String url, String message,      JsResult result) {    return super.onJsConfirm(view, url, message, result);  }  // 处理提示事件  @Override  public boolean onJsPrompt(WebView view, String url, String message,      String defaultValue, JsPromptResult result) {    return super.onJsPrompt(view, url, message, defaultValue, result);  }}

【MJavascriptInterface.java】

package cn.mahaochen.webviewtest.assist;import android.content.Context;import android.widget.Toast;/** * @date 2014-6-20 * @author MaHaochen */public class MJavascriptInterface {  private Context context;  public MJavascriptInterface(Context context) {    super();    this.context = context;  }    /**   * JS调用Android(Java)无参数的方法   */  public void jsCallWebView() {    Toast.makeText(context, "JS Call Java!",        Toast.LENGTH_SHORT).show();  }  /**   * JS调用Android(Java)含参数的方法   * @param param   */  public void jsCallWebView(String param) {    Toast.makeText(context, "JS Call Java!" + param,        Toast.LENGTH_SHORT).show();  }}

【ButtonListener.java】

package cn.mahaochen.webviewtest.assist;import cn.mahaochen.webviewtest.R;import android.view.View;import android.view.View.OnClickListener;import android.webkit.WebView;/** * @date 2014-6-20 * @author MaHaochen */public class ButtonListener implements OnClickListener{  private WebView webView;  public ButtonListener(WebView webView) {    super();    this.webView = webView;  }  @Override  public void onClick(View v) {    switch (v.getId()) {    case R.id.javaCallJs_web_button:      webView.loadUrl("javascript:javacalljs()"); // 无参数调用      break;    case R.id.javaCallJsParam_web_button:    webView.loadUrl("javascript:javacalljsparam(" + "'含参数'"+ ")"); // 无参数调用      break;    default:      break;    }  }}
第三步:

 

        以上是全部的Java代码部分的信息,本例旨为演示WebView(Java)与JS(JavaScript)的互操作。所以需要补充另两个资源文件web.html与jump.html页面,该页面位于项目的assets文件夹下。

 

 

【web.html】

测试页面无参数JS调用java代码
含参数调用java代码

【jump.html】

测试页面无参数JS调用java代码
含参数调用java代码
内容显示

 

转载于:https://www.cnblogs.com/longhs/p/4746448.html

你可能感兴趣的文章
区块链应用场景:征信和权属管理
查看>>
CES Asia专题|中国移动发布全球最小通信模组,助力物联网发展
查看>>
【MySql】赶集网mysql开发36条军规
查看>>
服务越好收入越高,300万快递小哥有了终身成长体系
查看>>
ipa-server
查看>>
2018云栖大会深圳峰会-企业级互联网架构专场看点提前大放送!
查看>>
邱剑 | 美团云容器实践之路
查看>>
windows 系统监视器 以及建议阀值
查看>>
bootstrap-表单控件——按钮
查看>>
[数据结构]约瑟夫环问题
查看>>
Spring系列之AOP分析之获取Advice的过程(四)
查看>>
CSS之浮动那些事
查看>>
BPM实例方案分享:表单子表自动填入数据
查看>>
iproute(网卡限速)--使用方法
查看>>
开源项目spring-shiro-training思维导图
查看>>
Memcache 查看列出所有key的方法
查看>>
DataBinding初识
查看>>
CentOS Docker 安装
查看>>
python set(集合)
查看>>
(C#)把磁盘目录树加载在窗体菜单中
查看>>