20161129

一篇简单明了的webview博客----android中使用webview与js交互全解析(转)

1.概述

首先,需要提出一个概念,那就是hybrid,主要意思就是native原生android和h5混合开发。为什么要这样做呢?大家可以想象一下针对于同一个活动,如果使用纯native的开发方式,Android和iOS两边都要维护同一套界面甚至是逻辑,这样开发和维护的成本会很大,而使用hybrid的开发方式的话,让前端的同学去写一套界面和逻辑,对于native端来说只要使用对应的容器去展示就可以了(对于Android来说这个容器当然就是WebView)。那为什么不所有的页面都使用这种方式开发呢?因为使用h5来展示界面的话用户体验始终是不如native的,所以在这两者之间我们需要一个权衡。

介绍完了何为hybrid,我们来思考下面几个场景: 
场景1:前端那边的页面有一个按钮,点击这个按钮需要显示一个native的组件(比如一个toast),或者点击这个按钮需要去在native端执行一个耗时的任务。 
场景2:还是前端页面有一个按钮,点击这个按钮的逻辑是:如果登录了,则跳转到相应的界面,如果没有登录,则跳转到登录界面。而这个登录界面是我们native维护的。 
看完上面两个场景,相信大家也发现了一个问题,hybrid这样的开发方式有一个问题需要解决,那就是前端和本地的通信。 
下面将会给大家介绍active原生Android和h5之间的通信方式。

2.如何使用webview

使用WebView控件 与其他控件的使用方法相同 在layout中使用一个”WebView”标签 
WebView不包括导航栏,地址栏等完整浏览器功能,只用于显示一个网页 
在WebView中加载Web页面,使用loadUrl() 

注意在manifest文件中加入访问互联网的权限

但是,在Android中点击一个链接,默认是调用手机上已经安装的浏览器程序来启动,因此想要通过WebView代为处理这个动作 ,那么需要通过WebViewClient

当然,我们也可以写一个类继承WebViewClient来对WebViewClient对象进行扩展

 

 

然后只需要将setWebViewClient的内容进行修改即可 

另外出于用户习惯上的考虑 需要将WebView表现得更像一个浏览器,也就是需要可以回退历史记录,因此需要覆盖系统的回退键 goBack,goForward可向前向后浏览历史页面 

例子1:WebViewClient的使用 
布局代码activity_main.xml:

1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2. xmlns:tools="http://schemas.android.com/tools"
3. android:layout_width="match_parent"
4. android:layout_height="match_parent"
5. android:paddingBottom="@dimen/activity_vertical_margin"
6. android:paddingLeft="@dimen/activity_horizontal_margin"
7. android:paddingRight="@dimen/activity_horizontal_margin"
8. android:paddingTop="@dimen/activity_vertical_margin"
9. tools:context="com.example.hybirddemo.MainActivity" >
10.
11. <WebView
12. android:layout_width="match_parent"
13. android:layout_height="match_parent"
14. android:id="@+id/webView" />
15.
16. </RelativeLayout>

MainActivity代码:

public class MainActivity extends Activity {
2.
3. private WebView webView;
4.
5. @Override
6. protected void onCreate(Bundle savedInstanceState) {
7. super.onCreate(savedInstanceState);
8. setContentView(R.layout.activity_main);
9.
10. // 获取webview控件
11. webView = (WebView) findViewById(R.id.webView);
12. //设置WebViewClient
13. /*webView.setWebViewClient(new MyWebViewClient());*/
14. //使用webview加载页面
15. webView.loadUrl("http://www.baidu.com");
16.
17. webView.setWebViewClient(new WebViewClient() {
18.
19. @Override
20. public boolean shouldOverrideUrlLoading(WebView view, String url) {
21. view.loadUrl(url);
22. return true;
23. }
24.
25. @Override
26. public void onPageStarted(WebView view, String url, Bitmap favicon) {
27. // TODO Auto-generated method stub
28. super.onPageStarted(view, url, favicon);
29. }
30.
31. @Override
32. public void onPageFinished(WebView view, String url) {
33. // TODO Aut (view, url);
34. }
35.
36. });
37.
38. }
39.
40. @Override
41. //覆盖系统的回退键
42. public boolean onKeyDown(int keyCode, KeyEvent event) {
43. if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
44. webView.goBack();
45. return true;
46. }
47.
48. return super.onKeyDown(keyCode, event);
49. }
50.
51. }

3.JavaScript和java的相互调用

WebSetting用处非常大,通过WebSetting可以使用Android原生的JavascriptInterface来进行js和Java的通信。 
例子2:javascript和java的相互调用

 首先我们写一段html代码:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <title>MyHtml.html</title>
5.
6. <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
7. <meta http-equiv="description" content="this is my page">
8. <meta http-equiv="content-type" content="text/html; charset=UTF-8">
9.
10. <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
11. <script type="text/javascript">
12. function showToast(toast) {
13. javascript:control.showToast(toast);
14. }
15. function log(msg) {
16. consolse.log(msg);
17. }
18. </script>
19. </head>
20.
21. <body>
22. <input type="button" value="toast" onclick="showToast('hello world!')">
23. </body>
24. </html>

这是一个很简单的HTML5页面,里面有一个button,点击这个button就执行js脚本中的showToast方法。 

 

 那么这个showToast方法做了什么呢? 

可以看到control.showToast,这个是什么我们后面再说,下面看我们Android工程中的java代码。

编写布局文件activity_main.xml 
布局的内容很简单,就是嵌套一个WebView控件 

 

 

 

 编写MainActivity.java代码

1. package com.example.hybirddemo;
2.
3. import android.annotation.SuppressLint;
4. import android.app.Activity;
5. import android.os.Bundle;
6. import android.util.Log;
7. import android.view.Menu;
8. import android.view.MenuItem;
9. import android.webkit.JavascriptInterface;
10. import android.webkit.WebSettings;
11. import android.webkit.WebView;
12. import android.widget.Toast;
13.
14. public class MainActivity extends Activity {
15.
16. private WebView webView;
17.
18. @Override
19. protected void onCreate(Bundle savedInstanceState) {
20. super.onCreate(savedInstanceState);
21. setContentView(R.layout.activity_main);
22. // 获取webview控件
23. webView = (WebView) findViewById(R.id.webView);
24. // 获取WebView的设置
25. WebSettings webSettings = webView.getSettings();
26. // 将JavaScript设置为可用,这一句话是必须的,不然所做一切都是徒劳的
27. webSettings.setJavaScriptEnabled(true);
28. //给webview添加JavaScript接口
29. webView.addJavascriptInterface(new JsInterface(), "control");
30. //通过webview加载html页面
31. webView.loadUrl("file:///android_asset/MyHtml.html");
32.
33. }
34. public class JsInterface{
35. @JavascriptInterface
36. public void showToast(String toast) {
37. Toast.makeText(MainActivity.this,toast , Toast.LENGTH_SHORT).show();
38. Log.d("html", "show toast success");
39. }
40. public void log(final String msg) {
41. webView.post(new Runnable() {
42.
43. @Override
44. public void run() {
45. webView.loadUrl("javascript log("+"'"+msg+"'"+")");
46.
47. }
48. });
49. }
50. }
51. }

上面的代码主要做了以下的步骤: 
a) 获取webview控件 
b) 获取webview的设置,将JavaScript设置为可用,打开JavaScript的通道 

 

 

c) 在Android程序中建立接口 ,并编写相关逻辑 
再去看之前js脚本中的那个showToast()方法 

这里的control就是我们的那个interface,调用了interface的showToast方法,很明显这里是js调用了Android的代码,输出了一个Toast

可以看到这个interface我们给它取名叫control,最后通过loadUrl加载页面。 

可以看到先显示一个toast,然后调用log()方法,log()方法里调用了js脚本的log()方法, js的log()方法做的事就是在控制台输出msg,这里明显是Android调用了js的方法。

d) 给webview添加我们自己编写的JavaScript接口 
通过WebView的addJavascriptInterface方法去注入一个我们自己写的interface。 

e) 使用webview控件加载我们之前编写的html文件

在真实手机上运行程序,在控制台成功输出内容:

这样我们就完成了js和java的互调,是不是很简单。

转自http://blog.csdn.net/u012124438/article/details/53371102#comments

 

posted @ 2016-11-29 15:24  别着急慢慢来  阅读(109)  评论(0编辑  收藏  举报