您现在的位置是:首页 > 技术教程 正文

Android中使用WebView与JS交互全解析

admin 阅读: 2024-03-31
后台-插件-广告管理-内容页头部广告(手机)

这里写图片描述

这里写图片描述

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

1. <uses-permission android:name="android.permission.INTERNET"/>
  • 1

但是,在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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

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. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

这是一个很简单的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. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 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的互调,是不是很简单。

4.Android中处理JS的警告,对话框等

在Android中处理JS的警告,对话框等需要对WebView设置WebChromeClient对象,并复写其中的onJsAlert,onJsConfirm,onJsPrompt方法可以处理javascript的常用对话框 例子3:在Android中处理javascript的对话框 1) 编写html页面布局

1. <%@LANGUAGE="JAVASCRIPT" CODEPAGE="936"%> 2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 3. <html xmlns="http://www.w3.org/1999/xhtml"> 4. <head> 5. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8 " /> 6. <title>分别测试javascript的三种对话框</title> 7. <script language="javascript"> 8. function ale() 9. { 10. alert("这是一个警告对话框!"); 11. } 12. function firm() 13. { 14. if(confirm("更多信息请到我的博客去?")) 15. { 16. location.href="http://yarin.javaeye.com"; 17. } 18. else 19. { 20. alert("你选择了不去!"); 21. } 22. } 23. function prom() 24. { 25. var str=prompt("演示一个带输入的对话框","这里输入你的信息"); 26. if(str) 27. { 28. alert("谢谢使用,你输入的是:"+ str) 29. } 30. } 31. </script> 32. </head> 33. <body> 34. <p>下面我们演示3种对话框</p> 35. <p>警告、提醒对话框</p> 36. <p> 37. <input type="submit" name="Submit" value="提交" onclick="ale()" /> 38. </p> 39. <p>带选择的对话框</p> 40. <p> 41. <input type="submit" name="Submit2" value="提交" onclick="firm()" /> 42. </p> 43. <p>要求用户输入的对话框</p> 44. <p> 45. <input type="submit" name="Submit3" value="提交" onclick="prom()" /> 46. </p> 47. </body> 48. </html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

页面效果:

这里写图片描述

2) Android中布局的编写

1. <?xml version="1.0" encoding="utf-8"?> 2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3. android:orientation="vertical" 4. android:layout_width="fill_parent" 5. android:layout_height="fill_parent" 6. > 7. <LinearLayout 8. android:orientation="horizontal" 9. android:layout_width="fill_parent" 10. android:layout_height="fill_parent" 11. android:animationCache="true" 12. android:layout_weight="9"> 13. <EditText 14. android:id="@+id/EditText01" 15. android:layout_width="wrap_content" 16. android:layout_weight="9" 17. android:layout_height="wrap_content" 18. android:text="请输入网址"/> 19. <Button android:id="@+id/Button01" 20. android:layout_width="wrap_content" 21. android:layout_weight="1" 22. android:layout_height="wrap_content" 23. android:text="连接" /> 24. </LinearLayout> 25. <WebView 26. android:id="@+id/WebView01" 27. android:layout_width="fill_parent" 28. android:layout_height="fill_parent" 29. android:layout_weight="1" 30. /> 31. </LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

3) 编写自定义对话框的布局 新建prom_dialog.xml文件,在其中自定义一个带输入的对话框由TextView和EditText构成

1. <?xml version="1.0" encoding="utf-8"?> 2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3. android:gravity="center_horizontal" 4. android:orientation="vertical" 5. android:layout_width="fill_parent" 6. android:layout_height="wrap_content" 7. > 8. <TextView 9. android:id="@+id/TextView_PROM" 10. android:layout_width="fill_parent" 11. android:layout_height="wrap_content"/> 12. <EditText 13. android:id="@+id/EditText_PROM" 14. android:layout_width="fill_parent" 15. android:layout_height="wrap_content" 16. android:selectAllOnFocus="true" 17. android:scrollHorizontally="true"/> 18. </LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

4) 获取WebView控件,并进行相关的设置

这里写图片描述

5) 复写onKeyDown方法,当用户按返回键时,返回上一个加载的页面

这里写图片描述

6) 给WebView设置setWebChromeClient,并复写其中的方法

1. // 设置WebChromeClient 2. mWebView.setWebChromeClient(new WebChromeClient() { 3. 4. @Override 5. // 处理javascript中的alert 6. public boolean onJsAlert(WebView view, String url, String message, 7. final JsResult result) { 8. // 构建一个Builder来显示网页中的对话框 9. Builder builder = new Builder(MainActivity.this); 10. builder.setTitle("提示对话框"); 11. builder.setMessage(message); 12. builder.setPositiveButton(android.R.string.ok, 13. new AlertDialog.OnClickListener() { 14. 15. @Override 16. public void onClick(DialogInterface dialog, 17. int which) { 18. // TODO Auto-generated method stub 19. // 点击确定按钮之后,继续执行网页中的操作 20. result.confirm(); 21. } 22. }); 23. builder.setNegativeButton(android.R.string.cancel, 24. new OnClickListener() { 25. 26. @Override 27. public void onClick(DialogInterface dialog, 28. int which) { 29. result.cancel(); 30. 31. } 32. }); 33. builder.setCancelable(false); 34. builder.create(); 35. builder.show(); 36. 37. return true; 38. 39. } 40. 41. @Override 42. //处理javascript中的confirm 43. public boolean onJsConfirm(WebView view, String url, 44. String message, final JsResult result) { 45. Builder builder = new Builder(MainActivity.this); 46. builder.setTitle("带选择的对话框"); 47. builder.setMessage(message); 48. builder.setPositiveButton(android.R.string.ok, 49. new AlertDialog.OnClickListener() { 50. public void onClick(DialogInterface dialog, int which) { 51. result.confirm(); 52. } 53. }); 54. builder.setNegativeButton(android.R.string.cancel, 55. new DialogInterface.OnClickListener() { 56. public void onClick(DialogInterface dialog, int which) { 57. result.cancel(); 58. } 59. }); 60. builder.setCancelable(false); 61. builder.create(); 62. builder.show(); 63. return true; 64. } 65. 66. @Override 67. // 处理javascript中的prompt 68. // message为网页中对话框的提示内容 69. // defaultValue在没有输入时,默认显示的内容 70. public boolean onJsPrompt(WebView view, String url, String message, 71. String defaultValue, final JsPromptResult result) { 72. // 自定义一个带输入的对话框由TextView和EditText构成 73. LayoutInflater layoutInflater = LayoutInflater 74. .from(MainActivity.this); 75. final View dialogView = layoutInflater.inflate( 76. R.layout.prom_dialog, null); 77. 78. // 设置TextView对应网页中的提示信息 79. ((TextView) dialogView.findViewById(R.id.TextView_PROM)) 80. .setText(message); 81. // 设置EditText对应网页中的输入框 82. ((EditText) dialogView.findViewById(R.id.EditText_PROM)) 83. .setText(defaultValue); 84. //构建一个Builder来显示网页中的对话框 85. Builder builder = new Builder(MainActivity.this); 86. //设置弹出框标题 87. builder.setTitle("带输入的对话框"); 88. //设置弹出框的布局 89. builder.setView(dialogView); 90. //设置按键的监听 91. builder.setPositiveButton(android.R.string.ok, 92. new AlertDialog.OnClickListener() { 93. 94. @Override 95. public void onClick(DialogInterface dialog, 96. int which) { 97. 98. // 点击确定之后,取得输入的值,传给网页处理 99. String value = ((EditText) dialogView 100. .findViewById(R.id.EditText_PROM)) 101. .getText().toString(); 102. result.confirm(value); 103. } 104. 105. }); 106. 107. builder.setNegativeButton(android.R.string.cancel, 108. new OnClickListener() { 109. 110. @Override 111. public void onClick(DialogInterface dialog, 112. int which) { 113. // TODO Auto-generated method stub 114. result.cancel(); 115. } 116. }); 117. 118. builder.setOnCancelListener(new DialogInterface.OnCancelListener() { 119. public void onCancel(DialogInterface dialog) { 120. result.cancel(); 121. } 122. }); 123. builder.show(); 124. return true; 125. } 126. 127. @Override 128. //设置网页加载的进度条 129. public void onProgressChanged(WebView view, int newProgress) { 130. MainActivity.this.getWindow().setFeatureInt(Window.FEATURE_PROGRESS, newProgress *100); 131. super.onProgressChanged(view, newProgress); 132. } 133. 134. @Override 135. public void onReceivedTitle(WebView view, String title) { 136. MainActivity.this.setTitle(title); 137. super.onReceivedTitle(view, title); 138. } 139. 140. }); 141. mButton.setOnClickListener(new View.OnClickListener() { 142. 143. @Override 144. public void onClick(View v) { 145. //取得编辑框中我们输入的内容 146. String url = mEditText.getText().toString().trim(); 147. //判断输入的内容是不是网址 148. if(URLUtil.isNetworkUrl(url)){ 149. //装载网址 150. mWebView.loadUrl(url); 151. }else{ 152. mEditText.setText("输入网址错误,请重新输入"); 153. } 154. } 155. }); 156. 157. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157

这里写图片描述

图1 dialog.html页面

这里写图片描述

图2 javascript的警告对话框

这里写图片描述

图3 javascript的confirm对话框

这里写图片描述

图4 javascript的prompt对话框

总结:在这个项目中,使用setWebChromeClient方法来为WebView设置一个WebChromeClient对象,来辅助WebView来处理Javascript的对话框等,图4是我们自定义的对话框,图2和图3我们都只需要监听按钮的点击事件,然后通过confirm和cancel方法将我们的操作传递给Javascript进行处理。当你在图1的界面,点击第一个按钮时,会打开图2的对话框,点击第二个按钮时,会打开图3的对话框,同时在这里点击确定,会跳转到另一个页面,当点击第三个按钮时,会打开图4对话框,并且可以输入内容。

更多Android进阶指南 可以扫码 解锁 《Android十大板块文档》

1.Android车载应用开发系统学习指南(附项目实战)

2.Android Framework学习指南,助力成为系统级开发高手

3.2023最新Android中高级面试题汇总+解析,告别零offer

4.企业级Android音视频开发学习路线+项目实战(附源码)

5.Android Jetpack从入门到精通,构建高质量UI界面

6.Flutter技术解析与实战,跨平台首要之选

7.Kotlin从入门到实战,全方面提升架构基础

8.高级Android插件化与组件化(含实战教程和源码)

9.Android 性能优化实战+360°全方面性能调优

10.Android零基础入门到精通,高手进阶之路

敲代码不易,关注一下吧。ღ( ´・ᴗ・` )

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索