Android应用开发 WebView与服务器端的Js交互

简介:
复制代码
复制代码
最近公司再添加功能的时候,有一部分功能是用的html,在一个浏览器或webview中展示出html即可。当然在这里我们当然用webview控件喽

 

WebApp的好处:

在应用里嵌套web的好处有这么几点,1,跨平台,不仅可以在Android上运行,也可以在iOS上运行,而且样式什么的绝对统一,因为都是加载的html,用的都是同一套html

2,修改灵活,容易更新版本。例如大家常看到的app里面的广告页,大多是嵌套的html,这样只要后台替换一下页面的内容,手机端就会改变展现内容,跟新版本也是如此,因为界面什么得成了在服务器端,所以要是想跟新界面什么得,只需要在后台修改在发布即可,不需要用户再重新下载app。这个好处我觉得对ios是有很大帮助的,哈哈,绕开苹果审核嘛,由于html我们可以随意替换,审核时可以把违规的部分隐藏,上线之后就可以随意改了,哈哈,你们懂得。

 

当然,开发webapp当然也有局限,就是网速什么的,这个咱无法改变,这里也不废话。不过在开发中呢,如果只是页面之间的交互的话,我们只需提供一个webview控件即可,

可是要是涉及到和手机设备或软件交互的话(如打开相册,摄像头等等),这就需要我们和页面经行js交互,js交互可以说是双向的,一种是,我们调用页面的,就是调用服务端的js方法,另一个呢则是服务端调用我们Android里面的代码,调用其实很简单,下面说一下怎样调用。

当然我们先等有一个WebView,先创建一个Activity,然后设置布局,穿件WebView,布局和Activity如下:

activity_webview.xml



[html] view plain copy print?在CODE上查看代码片派生到我的代码片 01.<?xml version="1.0" encoding="utf-8"?> 02.<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 03. android:layout_width="match_parent" 04. android:layout_height="match_parent" 05. android:orientation="vertical" > 06. <WebView 07. android:id="@+id/webview" 08. android:layout_width="match_parent" 09. android:layout_height="match_parent" 10. /> 11. 12.</LinearLayout> 然后是activity, WebViewActivity.activity [java] view plain copy print?在CODE上查看代码片派生到我的代码片 01.import android.app.Activity; 02.import android.os.Bundle; 03.import android.webkit.WebSettings; 04.import android.webkit.WebView; 05. 06.public class WebViewActivity extends Activity { 07. private static final String url = "http://192.168.30.199:8080/song/test.html"; 08. private WebView mWebView; 09. @Override 10. protected void onCreate(Bundle savedInstanceState) { 11. super.onCreate(savedInstanceState); 12. setContentView(R.layout.activity_webviw); 13. initView(); 14. } 15. 16. private void initView() { 17. mWebView = (WebView) findViewById(R.id.webview); 18. //或的WebView的Setting 19. WebSettings settings = mWebView.getSettings(); 20. //设置支持js,看方法名字就知道啥意思 21. settings.setJavaScriptEnabled(true); 22. //加载网页路径 23. mWebView.loadUrl(url); 24. } 25.} 上面就是一个简单的webview,然后很常规的设置属性,然后再加载要加载的页面路径,这样一般就可在网页里面自由点击跳转了,但是要和手机交互的话需要我们写js交互的代码了。 首先说怎样调用服务器端的js方法,很简单,和加载网页路径基本上一样如下: [java] view plain copy print?在CODE上查看代码片派生到我的代码片 01.mWebView.loadUrl("javascript:forSmallPhoto()"); 就这么简单的一句话你就可以调用服务器端的js方法了,其中JavaScript:是固定写法forSmallPhoto()则是服务端的js方法名字,这是一个无参数的方法,当然也可以传参,这需要我们拼凑字符串,mWebView.loadUrl("javascript:forSmallPhoto('" + data + "')");其中data就是一个变量,也就是你要传的参数值,当然也可以支持多参数传送,这得看你服务器端的js方法有几个参数了,其实就是我们调用一个方法一样,只不过这个方法是在服务器端的。我们调用服务器js,是为了,当Android完成某些功能后,需要告诉服务器,则我们可以调用js来告诉他我们完成了。 在一种就是,服务端调用我们的Android代码了,这里Android中也是封装好了接口 我们可以通过void android.webkit.WebView.addJavascriptInterface(Object object, String name)的方法来实现服务器端调用我们的代码,其中这个方法有两个参数,一个是object,另一个是String类型的; 只要webview调用了这个方法就可以调用我们的代码了。而要调用的代码我们写在Object里面,首先我们就先实现这个Object,我们创建一个类,JavaScriptInterface。Android中APi Guides中提供的Demo中取得累的名字是JavaScriptInterface,那我们也用这个名字把。然后实现它,然后随便在里面写一个方法,如下面 JavaScriptInterface.Java类 [java] view plain copy print?在CODE上查看代码片派生到我的代码片 01.import java.util.HashMap; 02.import java.util.Map; 03. 04.import android.content.Context; 05.import android.os.Handler; 06.import android.os.Message; 07.import android.text.TextUtils; 08.import android.util.Log; 09.import android.webkit.JavascriptInterface; 10.import android.widget.Toast; 11. 12./** 13. * 14. * Title: JavaScriptInterface.java Description: 15. * 16. * @author Liusong 17. * @version V1.0 18. */ 19.public class JavaScriptInterface { 20. 21. /** Instantiate the interface and set the context */ 22. public JavaScriptInterface() { 23. } 24. 25. /** Show a toast from the web page */ 26. @JavascriptInterface 27. public void showToast() { 28. Log.i("TAG", "调用成功==================》》》》》"); 29. 30. } 31. 32.} 这样就完成了一个简单的JavaScriptInterface类,这个类的方法是自己随便写的,其中,先说一下这里要注意的几点,首先重要的@JavascriptInterface这个注解,你会发现去掉也不会报错,但是这个是很早重要的,如果你想让服务器端调用你的方法,你就要加上这个注解@JavascriptInterface。在4.4api中说道,一定要加这个注解,负责调用不会成功,其实我在开发中,用红米1s,4.3的系统,就没法调用成功了,当时还纳闷,因为当时手里的文档是4.2的,很是郁闷。所以在这里强掉,一定要在自己写的方法前面加上@JavascriptInterface。 还有一个注意的是方法的参数,这里是一个无参方法,当然这里你也可以写一个有参方法,这里先提一下,待会会配合html里面的js说道,我们先说void android.webkit.WebView.addJavascriptInterface(Object object, String name)这个方法里面的第二个参数,第二个参数你可以理解为是标识符,就是服务器端调用你方法时,需要找到你,怎么找到?就是通过这个标识符,标识符是自己随便定的,但是,你要告诉后台开发人员你的标识符是什么,我们这里把这第二个参数设置为“Android”。下面我给出我测试的html代码结合着看你就明白了。 test.html [html] view plain copy print?在CODE上查看代码片派生到我的代码片 01.<!doctype html> 02.<html> 03.<head> 04. <meta name="viewport" content="width=device-width, initial-scale=1" charset="GBK"> 05. <title>测试</title> 06.</head> 07. 08.<body> 09. 10.<div data-role="page" > 11. 12.<script type="text/javascript"> 13. function callAndroidAction(action) { 14. Android.showToast(); alert("我敢保证,你现在用的是演示一"); 15. } 16. function forSmallPhoto(action) { 17. alert("我敢保证,你现在用的是演示一"+action); 18. } 19.</script> 20. 21. <div data-role="header"> 22. <h1>调用图库</h1> 23. <!-- <a href="#" class="ui-btn">返回</a>--> 24. </div> 25. 26. <div data-role="main" class="ui-content"> 27. 28. <div style="width: 98%;margin: 0 auto; text-align: center"> 29. <a href="#" class=" ui-btn ui-btn-inline" onclick="callAndroidAction(0)">调用图库 </a> 30. 31. <a href="#" class=" ui-btn ui-btn-inline" onclick="callAndroidAction('2')"> 充值 </a> 32. 33. </div> 34. 35. 36. </div> 37. 38. 39.</div> 40. 41.</body> 42. 43. 44.</html> 这个代码有点乱,就将就这看吧,我是把这个页面放在自己的tomcat上的,其中这个html中大家发现 [html] view plain copy print?在CODE上查看代码片派生到我的代码片 01.<script type="text/javascript"> 02. function callAndroidAction(action) { 03. Android.showToast(); 04. alert("我敢保证,你现在用的是演示一"); 05. } 06. function forSmallPhoto(action) { 07. alert("我敢保证,你现在用的是演示一"+action); 08. } 09.</script> 这个js方法没,看见里面的Android标识符没,没错,后台就是这么调用我们代码的,Android.showToast();就是这么调用的,就是这么简单,不要想的太难,我们就需按我上面说的那样,把Object实现,把标识符写好就ok了。饭后,后台就会通过标识符和你Object的方法名字调用你的方法。这里要说一下,你Object(即JavaScriptInterface,我们上面已经实现)里的方法的参数要和后台调用你的方法的参数个数和类型一直,就像我们平时调用方法是一样的。这一点知道了就好了。 这样就可以了。 所以WebViewActivity里面加上这一句就可以了。 [java] view plain copy print?在CODE上查看代码片派生到我的代码片 01.view.addJavascriptInterface(new JavaScriptInterface(),"Android"); 这样js就说完了。 模版 当后台要调用我们的代码,我们就写一个方法,如果调用多次我们就写多个,这样太麻烦,所以我们来写一个通用的方法,就是无论后台调用你代码干不同的事,都调用你这个方法,那怎么区分不同的执行动作呢?用传的参数,我们在JavaScriptInterface里面写一个方法,这里就叫callAndroidAction,我设计的是给这个方法三个参数, public void callAndroidAction(String action, String url,String json),第一个参数action,即用来表示要执行的动作,第二个则是url,不管是服务其给的下载路径还是,访问其他页面的路径,在一个json就是其他一些参数,由于传的参数不固定,我们就用一个参数,一个参数时就传过来,多个参数时可以通过json字符串传过来,就没必要麻烦一个一个的写参数了。 然后我们在设计一个回调,让操作的代码拿出去,怎大体就是这样了 [java] view plain copy print?在CODE上查看代码片派生到我的代码片 01.import java.util.HashMap; 02.import java.util.Map; 03. 04.import android.content.Context; 05.import android.os.Handler; 06.import android.os.Message; 07.import android.text.TextUtils; 08.import android.util.Log; 09.import android.webkit.JavascriptInterface; 10.import android.widget.Toast; 11. 12./** 13. * 14. * Title: JavaScriptInterface.java Description: 15. * 16. * @author Liusong 17. * @version V1.0 18. */ 19.public class JavaScriptInterface { 20. 21. private Handler mHandler; 22. 23. /** Instantiate the interface and set the context */ 24. public JavaScriptInterface(Handler handler) { 25. mHandler = handler; 26. } 27. 28. /** Show a toast from the web page */ 29. @JavascriptInterface 30. public void showToast(final String toast) { 31. Log.i("TAG", "调用成功==================》》》》》"); 32. } 33. 34. @JavascriptInterface 35. public void callAndroidAction(String action, String url,String json) { 36. Map<String, String> params = new HashMap<String, String>(); 37. if(!TextUtils.isEmpty(url)){ 38. params.put("url", url); 39. } 40. if(!TextUtils.isEmpty(json)){ 41. params.put("json", json); 42. } 43. Message msg = Message.obtain(); 44. msg.what = Integer.valueOf(action); 45. msg.obj = params; 46. mHandler.sendMessage(msg); 47. } 48.} 这样我们就从服务其拿到的参数都给Handler了,则WebViewActivity里面就要这样写了 [java] view plain copy print?在CODE上查看代码片派生到我的代码片 01.import java.util.HashMap; 02.import java.util.Map; 03. 04.import android.app.Activity; 05.import android.os.Bundle; 06.import android.os.Handler; 07.import android.os.Message; 08.import android.webkit.WebSettings; 09.import android.webkit.WebView; 10. 11.public class WebViewActivity extends Activity { 12. private static final String url = "http://192.168.30.199:8080/song/test.html"; 13. 14. //执行动作 15. public static final int SELECT_IMAGE = 0;// 打开图库 16. public static final int OPEN_PAGE = 1;// 跳转其他特定页面 17. public static final int CLOSE_OR_BACK = 2;// 关闭或 18. 19. private WebView mWebView; 20. @Override 21. protected void onCreate(Bundle savedInstanceState) { 22. super.onCreate(savedInstanceState); 23. setContentView(R.layout.activity_webviw); 24. initView(); 25. } 26. <p> 27. private void getIntentDatas() { 28. // TODO Auto-generated method stub 29. url = getIntent().getStringExtra("url"); 30. }</p><p> </p> private void initView() { 31. mWebView = (WebView) findViewById(R.id.webview); 32. //或的WebView的Setting 33. WebSettings settings = mWebView.getSettings(); 34. //设置支持js,看方法名字就知道啥意思 35. settings.setJavaScriptEnabled(true); 36. mWebView.addJavascriptInterface(new JavaScriptInterface(handler), "Android"); 37. //加载网页路径 38. mWebView.loadUrl(url); 39. } 40. 41. private Handler handler = new Handler(){ 42. public void handleMessage(Message msg) { 43. switch (msg.what) { 44. case SELECT_IMAGE://执行打开图库, 45. 46. //如果有参数,取服务端传过来的参数(url,json) 47. Map<String, String> params = (HashMap<String, String>)msg.obj; 48. break; 49. 50. //其他功能,可随着自己功能的增加,在这里增加,只需和后台商量好动作的action值即可 51. default: 52. break; 53. } 54. }; 55. }; 56.} 最后再让WebViewActivity通用,就是通过传url参数 [java] view plain copy print?在CODE上查看代码片派生到我的代码片 01.private void getIntentDatas() { 02. // TODO Auto-generated method stub 03. url = getIntent().getStringExtra("url"); 04.} 
复制代码
复制代码


相关文章
|
1月前
|
Ubuntu 网络协议 Java
【Android平板编程】远程Ubuntu服务器code-server编程写代码
【Android平板编程】远程Ubuntu服务器code-server编程写代码
|
3月前
|
JavaScript 前端开发 API
释放 Node.js 的力量:服务器端 JavaScript 综合指南
释放 Node.js 的力量:服务器端 JavaScript 综合指南
31 0
|
3月前
|
安全 API Android开发
Android网络和数据交互: 解释Retrofit库的作用。
Android网络和数据交互: 解释Retrofit库的作用。
38 0
|
5天前
|
JavaScript 前端开发 UED
Vue工具和生态系统: Vue.js和服务器端渲染(SSR)有关系吗?请解释。
Vue.js是一个渐进式JavaScript框架,常用于开发单页面应用,但其首屏加载较慢影响用户体验和SEO。为解决此问题,Vue.js支持服务器端渲染(SSR),在服务器预生成HTML,加快首屏速度。Vue.js的SSR可手动实现或借助如Nuxt.js的第三方库简化流程。Nuxt.js是基于Vue.js的服务器端渲染框架,整合核心库并提供额外功能,帮助构建高效的应用,改善用户体验。
7 0
|
7天前
|
Android开发 开发者
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
Android&#39;s AsyncTask simplifies asynchronous tasks for brief background work, bridging UI and worker threads. It involves execute() for starting tasks, doInBackground() for background execution, publishProgress() for progress updates, and onPostExecute() for returning results to the main thread.
8 0
|
7天前
|
网络协议 安全 API
Android网络和数据交互: 什么是HTTP和HTTPS?在Android中如何进行网络请求?
HTTP和HTTPS是网络数据传输协议,HTTP基于TCP/IP,简单快速,HTTPS则是加密的HTTP,确保数据安全。在Android中,过去常用HttpURLConnection和HttpClient,但HttpClient自Android 6.0起被移除。现在推荐使用支持TLS、流式上传下载、超时配置等特性的HttpsURLConnection进行网络请求。
8 0
|
1月前
|
监控 JavaScript 安全
监控内网电脑软件设计与实现:基于Node.js的服务器端架构分析
在当今信息技术高度发达的时代,监控内网电脑的需求日益增长。企业需要确保网络安全,个人用户也需要监控家庭网络以保护隐私和安全。本文将介绍一种基于Node.js的服务器端架构,用于设计和实现监控内网电脑软件。
99 0
|
1月前
|
移动开发 JavaScript Android开发
Android与Html5交互
Android与Html5交互
|
1月前
|
Ubuntu 网络协议 Java
在Android平板上使用code-server公网远程Ubuntu服务器编程
在Android平板上使用code-server公网远程Ubuntu服务器编程
|
2月前
|
XML Android开发 数据格式
安卓和webview交互
安卓和webview交互
25 0