Android应用开发-------------WebView(一)之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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</LinearLayout>

然后是activity,

WebViewActivity.activity

import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;

public class WebViewActivity extends Activity {
	private static final String url = "http://192.168.30.199:8080/song/test.html";
	private WebView mWebView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_webviw);
		initView();
	}

	private void initView() {
		mWebView = (WebView) findViewById(R.id.webview);
		//或的WebView的Setting
		WebSettings settings = mWebView.getSettings();
		//设置支持js,看方法名字就知道啥意思
		settings.setJavaScriptEnabled(true);
		//加载网页路径
		mWebView.loadUrl(url);
	}
}

上面就是一个简单的webview,然后很常规的设置属性,然后再加载要加载的页面路径,这样一般就可在网页里面自由点击跳转了,但是要和手机交互的话需要我们写js交互的代码了。

首先说怎样调用服务器端的js方法,很简单,和加载网页路径基本上一样如下:

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类

import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.widget.Toast;

/**
 *
 * Title: JavaScriptInterface.java Description:
 *
 * @author Liusong
 * @version V1.0
 */
public class JavaScriptInterface {	

	/** Instantiate the interface and set the context */
	public JavaScriptInterface() {
	}

	/** Show a toast from the web page */
	@JavascriptInterface
	public void showToast() {
		Log.i("TAG", "调用成功==================》》》》》");

	}

}

这样就完成了一个简单的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

<!doctype html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1" charset="GBK">
    <title>测试</title>
</head>

<body>

<div data-role="page" >

<script type="text/javascript">
	 function callAndroidAction(action) {
		Android.showToast();		alert("我敢保证,你现在用的是演示一");
    }
	 function forSmallPhoto(action) {
		alert("我敢保证,你现在用的是演示一"+action);
    }
</script>

    <div data-role="header">
        <h1>调用图库</h1>
        <!--   <a href="#" class="ui-btn">返回</a>-->
    </div>

    <div data-role="main" class="ui-content">

        <div style="width: 98%;margin: 0 auto; text-align: center">
            <a href="#" class=" ui-btn ui-btn-inline" onclick="callAndroidAction(0)">调用图库  </a>

			<a href="#" class=" ui-btn ui-btn-inline" onclick="callAndroidAction('2')"> 充值  </a>

        </div>

    </div>

</div>

</body>

</html>

这个代码有点乱,就将就这看吧,我是把这个页面放在自己的tomcat上的,其中这个html中大家发现

<script type="text/javascript">
    function callAndroidAction(action) {
		Android.showToast();
		alert("我敢保证,你现在用的是演示一");
    }
   function forSmallPhoto(action) {
		alert("我敢保证,你现在用的是演示一"+action);
    }
</script>

这个js方法没,看见里面的Android标识符没,没错,后台就是这么调用我们代码的,Android.showToast();就是这么调用的,就是这么简单,不要想的太难,我们就需按我上面说的那样,把Object实现,把标识符写好就ok了。饭后,后台就会通过标识符和你Object的方法名字调用你的方法。这里要说一下,你Object(即JavaScriptInterface,我们上面已经实现)里的方法的参数要和后台调用你的方法的参数个数和类型一直,就像我们平时调用方法是一样的。这一点知道了就好了。

这样就可以了。

所以WebViewActivity里面加上这一句就可以了。

view.addJavascriptInterface(new JavaScriptInterface(),"Android");

这样js就说完了。

模版

当后台要调用我们的代码,我们就写一个方法,如果调用多次我们就写多个,这样太麻烦,所以我们来写一个通用的方法,就是无论后台调用你代码干不同的事,都调用你这个方法,那怎么区分不同的执行动作呢?用传的参数,我们在JavaScriptInterface里面写一个方法,这里就叫callAndroidAction,我设计的是给这个方法三个参数,

public void callAndroidAction(String action, String url,String json),第一个参数action,即用来表示要执行的动作,第二个则是url,不管是服务其给的下载路径还是,访问其他页面的路径,在一个json就是其他一些参数,由于传的参数不固定,我们就用一个参数,一个参数时就传过来,多个参数时可以通过json字符串传过来,就没必要麻烦一个一个的写参数了。

然后我们在设计一个回调,让操作的代码拿出去,怎大体就是这样了

import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.widget.Toast;

/**
 *
 * Title: JavaScriptInterface.java Description:
 *
 * @author Liusong
 * @version V1.0
 */
public class JavaScriptInterface {

	private Handler mHandler;

	/** Instantiate the interface and set the context */
	public JavaScriptInterface(Handler handler) {
		mHandler = handler;
	}

	/** Show a toast from the web page */
	@JavascriptInterface
	public void showToast(final String toast) {
		Log.i("TAG", "调用成功==================》》》》》");
	}

	@JavascriptInterface
	public void callAndroidAction(String action, String url,String json) {
		Map<String, String> params = new HashMap<String, String>();
		if(!TextUtils.isEmpty(url)){
			params.put("url", url);
		}
		if(!TextUtils.isEmpty(json)){
			params.put("json", json);
		}
		Message msg = Message.obtain();
		msg.what = Integer.valueOf(action);
		msg.obj = params;
		mHandler.sendMessage(msg);
	}
}

这样我们就从服务其拿到的参数都给Handler了,则WebViewActivity里面就要这样写了

import java.util.HashMap;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.webkit.WebSettings;
import android.webkit.WebView;

public class WebViewActivity extends Activity {
	private static final String url = "http://192.168.30.199:8080/song/test.html";

	//执行动作
	public static final int SELECT_IMAGE = 0;// 打开图库
	public static final int OPEN_PAGE = 1;// 跳转其他特定页面
	public static final int CLOSE_OR_BACK = 2;// 关闭或

	private WebView mWebView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_webviw);
		initView();
	}
 	<p>
	 private void getIntentDatas() {
  		// TODO Auto-generated method stub
 		 url = getIntent().getStringExtra("url");
 	}</p><p> </p>	private void initView() {
		mWebView = (WebView) findViewById(R.id.webview);
		//或的WebView的Setting
		WebSettings settings = mWebView.getSettings();
		//设置支持js,看方法名字就知道啥意思
		settings.setJavaScriptEnabled(true);
		mWebView.addJavascriptInterface(new JavaScriptInterface(handler), "Android");
		//加载网页路径
		mWebView.loadUrl(url);
	}

	private Handler handler = new Handler(){
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case SELECT_IMAGE://执行打开图库,

				//如果有参数,取服务端传过来的参数(url,json)
				Map<String, String> params = (HashMap<String, String>)msg.obj;
				break;

			//其他功能,可随着自己功能的增加,在这里增加,只需和后台商量好动作的action值即可
			default:
				break;
			}
		};
	};
}

最后再让WebViewActivity通用,就是通过传url参数

 private void getIntentDatas() {
  // TODO Auto-generated method stub
  url = getIntent().getStringExtra("url");
 }

这样就可以了。

如果要demo可以留言

时间: 2024-10-27 13:27:20

Android应用开发-------------WebView(一)之WebView与服务器端的Js交互的相关文章

WebView 加载网页和java 与js交互

[mw_shl_code=java,true]WebView是一个可以显示网页的控件.需求:通过WebView加载assets下的html文件.实现页面的缩放.向menu键添加:前进.后退和刷新,实现对网页的操作点击网页中的链接,仍然使用本WebView浏览器,而非调用系统的浏览器网页中有button,点击button,调用android的Toast点击WebView隐藏地址栏和button,点击menu键显示地址栏和button.WebView加载网页的方式WebView webview =

android混合开发,webview的java与js互操作

android原生应用,用webview加载应用中的网页,并且java代码与js代码可以互相操作. 这是混合开发的基石,最基本也最重要的东西,实验代码在这里. 概括说说—— java调js:调用webView.load("javascript:someFunction()"); 这样可以调用webView里页面上的全局方法.这不是什么新鲜东西,你在网页中也可以这么做,试试在浏览器地址栏输入javascript:alert("427studio");也可以在浏览器地址

Android开发学习笔记:WebView 二

WebView是Android中一个非常实用的组件,它和Safai.Chrome一样都是基于Webkit网页渲染引擎,可以通过加载HTML数据的方式便捷地展现软件的界面.使用WebView开发软件有一下几个优点: 1.可以打开远程URL页面,也可以加载本地HTML数据: 2.可以无缝的在java和javascript之间进行交互操作: 3.高度的定制性,可根据开发者的需要进行多样性定制. 下面就通过例子来介绍一下WebView的使用方法. 我们先建一个webview项目,项目结构如左图: 在这个

Android开发之正确使用WebView

Android和iOS系统都提供了标准的浏览器控件,在Android中是WebView,iOS中为UIWebView.在iOS中你实例化一个UIWebView即可调用loadRequest来加载一个网页,但是在Android中你不仅需要创建一个WebView,还需要做一些其他的事情,建议初次使用WebView的读者按照以下步骤使用: (1)在要实现WebView的XML中添加一个WebView,并按照自己的要求进行排版,如下: <FrameLayout        android:layout

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

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

Android 4.2版本以下使用WebView组件addJavascriptInterface方法存在JS漏洞

JS注入漏洞存在的Android版本:Android < 4.2 综述:Android的SDK中提供了一个WebView组件,用于在应用中嵌入一个浏览器来进行网页浏览.WebView组件中的addJavascriptInterface方法用于实现本地Java和JavaScript的交互.这个方法可以通过js脚本在本地执行任意Java代码,从而以当前用户身份执行任意命令. 尽管Android官方已经提醒了此功能在访问不可信网页内容时存在严重安全风险,很多应用开发人员仍未意识到此问题,大量Andro

Android WebView Memory Leak WebView内存泄漏

在这次开发过程中,需要用到webview展示一些界面,但是加载的页面如果有很多图片就会发现内存占用暴涨,并且在退出该界面后,即使在包含该webview的Activity的destroy()方法中,使用webview.destroy();webview=null;对内存占回收用还是没有任何效果.有人说,一旦在你的xml布局中引用了webview甚至没有使用过,都会阻碍重新进入Application之后对内存的gc.包括使用MapView有时一会引发OOM,几经周折在网上看到各种解决办法,在这里跟大

[Android学习系列2]用webview写界面,加载本地js,js,html文件

以jquery mobile为例 1.在android界面拖入一个webview,然后添加一个internet权限 <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <uses-permission android:name="android.permission.INTERNET"/> <application ........

Webview Android与js交互

Android 中可以通过webview来实现和js的交互,在程序中调用js代码,只需要将webview控件的支持js的属性设置为true Android(Java)与JavaScript(HTML)交互有四种情况: 1) Android(Java)调用HTML中js代码 2) Android(Java)调用HTML中js代码(带参数) 3) HTML中js调用Android(Java)代码 4) HTML中js调用Android(Java)代码(带参数) 下面示例总结这四种情况,直接上干货: