WebView中Js与Android本地函数的相互调用
介绍
随着Html5的普及,html在表现力上不一定比原生应用差,并且有很强的扩展兼容性,所以越来越多的应用是采用Html与Android原生混合开发模式实现。
既然要实现混合开发,那么Js与Android原生函数的相互调用就必不可少了。这里写了一个demo,实现点击html中的图片进行本地展示。
原理
1、Android调用js很简单,直接webView.loadUrl("javascript:JS中的方法名称()");即可。
2、js调用Android方法,需要使用WebView.addJavascriptInterface(Object obj, String interfaceName)这个方法告诉WebView我要添加一个Js接口调用本地函数。
3、demo中用到了universalimageloader与PhotoView实现图片加载与浏览
见http://www.cnblogs.com/leestar54/p/4220068.html,http://www.cnblogs.com/leestar54/p/4105726.html
4、demo中涉及到了一个JS闭包的问题,闭包中所记录的自由变量,只是对这个变量的一个引用,而非变量的值,当这个变量被改变了,闭包里获取到的变量值,也会被改变.
见http://www.cnblogs.com/mzwr1982/archive/2012/05/20/2509295.html
实现
MainActivity
package com.example.javascriptinterface; import java.util.ArrayList; import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import android.support.v7.app.ActionBarActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.graphics.Bitmap; public class MainActivity extends ActionBarActivity {
private WebView webView1;
private ProgressDialog pbar;
private Handler mHandler = new Handler(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // 初始化通用图片加载器
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheInMemory(true).cacheOnDisk(true).build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
this).defaultDisplayImageOptions(defaultOptions).build();
ImageLoader.getInstance().init(config); pbar = new ProgressDialog(MainActivity.this);
pbar.setTitle("提示");
pbar.setMessage("加载中…");
pbar.setIndeterminate(true);
webView1 = (WebView) findViewById(R.id.webView1);
webView1.setWebViewClient(new WebViewClient() { @Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
pbar.show();
} @Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
pbar.dismiss();
//网页加载完成,Weiview中注入Js
addImageClickListner();
} }); //允许webview执行JS
webView1.getSettings().setJavaScriptEnabled(true);
webView1.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView1.loadUrl("http://news.163.com/jnews/mobile/#detail/99/AI8ESHB000964J4O");
//添加JS接口,这样就可以在js中调用本地函数了。
webView1.addJavascriptInterface(new JavascriptInterface(this),
"imagelistner");
} public class JavascriptInterface { private Context context; public JavascriptInterface(Context context) {
this.context = context;
} //一定要声明该函数是JavascriptInterface
@android.webkit.JavascriptInterface
public void openImage(String img, final int index) { final String simg = img;
final int findex = index; mHandler.post(new Runnable() { @Override
public void run() {
String[] imgs = simg.split(",");
ArrayList<String> imgsUrl = new ArrayList<String>();
for (String s : imgs) {
imgsUrl.add(s);
}
Intent intent = new Intent();
intent.putExtra("index", findex);//当前点击图片index
intent.putStringArrayListExtra("infos", imgsUrl);//图片链接数组
intent.setClass(context, PhotosActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}); }
} private void addImageClickListner() { //click函数解决了闭包,用来实现显示当前点击图片
webView1.loadUrl("javascript:(function(){"
+ "var objs = document.getElementsByTagName(\"img\");"
+ "var imgurl='';"
+ "for(var i=0;i<objs.length;i++) "
+ "{"
+ "imgurl+=objs[i].src+',';"
+ " objs[i].onclick=(function(j){return function(){window.imagelistner.openImage(imgurl,j);}; })(i); "
+ "}" + "} " + ")()");
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
完成之后看起来是这样的
demo地址
链接:http://pan.baidu.com/s/1dDEPPkP 密码:7y6g
WebView中Js与Android本地函数的相互调用的更多相关文章
- WebView中JS调用Android Method 遇到的坑整理
WebView是android中常用的一个组件,其作用是展示网页,并让网页和android app进行一些业务逻辑上的交互. 其坑无数,相信用过的都知道,一个一个来解决吧. 1.怎么互调: <! ...
- ASP.net关于C#代码与javaScript函数的相互调用
C#代码与javaScript函数的相互调用 问:1.如何在JavaScript访问C#函数?2.如何在JavaScript访问C#变量?3.如何在C#中访问JavaScript的已有变量?4.如何在 ...
- python - 函数的相互调用 及 变量的作用域
# -*- coding:utf-8 -*- '''@project: jiaxy@author: Jimmy@file: study_函数的相互调用及变量的作用域.py@ide: PyCharm C ...
- ASP.NET前台JS与后台CS函数如何互相调用
摘要: 在实际的Web开发中,我们可能会常常遇到后台调用前台JS代码或者前台JS调用后台代码的情况.今天就把比较实用的前后台相互调用的方法总结出来和大家分享. 在实际的Web开发中,我们可能会常常遇到 ...
- JS代码和OC代码的相互调用
JS调用OC 很多应用里面或多或少的调用了网页,来达到绚丽的效果,所谓的JS调用OC.....举个例子吧,网页上有个按钮 点击按钮跳转界面,跳转的动作由OC的代码实现. OC调用JS 还是举个例子,我 ...
- Android原生webview中js交互
http://www.cnblogs.com/android-blogs/p/4891264.html Html页面和Java代码结合的方式一般用在界面经常被更改 的情况下,可以讲html放在网络中, ...
- android WebView中js的alert()失效
WebView的设置代码 wv = (WebView) findViewById(R.id.webView1); wv.getSettings().setJavaScriptEnabled(true) ...
- Xamarin Android Webview中JS调用App中的C#方法
参考链接:https://github.com/xamarin/recipes/tree/master/Recipes/android/controls/webview/call_csharp_fro ...
- android webview 中 js 模板引擎的使用
最近在项目中要求用 webview 展示几个界面, 而后台返回的不是 html 而是 json 数据. 起初用 StringBuilder 一个一个拼 html, 后来感觉太繁琐,拼一个还行,拼多了就 ...
随机推荐
- iis express 启动多个网站
iis express一次只能运行一个网站, 执行iisexpress 不加参数. 将执行配置文件中的第一个网站. iis express一次只能运行一个 应用程序池. 可以使用这个特点实现一次 ...
- js实用功能
//日期格式转换 Date.prototype.format = function (format) { /* * eg:format="yyyy-MM-dd hh:mm: ...
- cts 测试环境安装 ubuntu
1 下载cts测试包 和 sdk 包 http://source.android.com/compatibility/downloads.html ----cts 包 http://develope ...
- Hadoop 系统配置 map 100% reduce 0%
之前在本地配置了hadoop伪分布模式,hdfs用起来没问题,mapreduce的单机模式也没问题. 今天写了个程序,想在伪分布式上跑一下mapreduce,结果出现 map 100% reduce ...
- hadoop安装问题
1. 运行start-dfs.sh启动HDFS守护进程,start-yarn.sh面向YARN的资源器和节点管理器,资源管理器web地址是http://localhost:8080/.输入stop.d ...
- list<T> 自定义比较器进行排序
今天在研究List<T> 集合如何排序,我试过很多,但是都不行,然后看到msdn中的这个比较器排序,自己测试了代码,No Problem.给大家分享一下. 类型 T 的默认比较器按如下方式 ...
- JQuery的ajax方法
1.使用方式: 由于是全局方法,所以调用简单:$.ajax(); 2.可输入参数: 最好是写成一个json形式,个人不建议用链式,那样看上去不太好. 参数名称 类型 描述 dataType strin ...
- 深入浅出ES6(十):集合
作者 Jason Orendorff github主页 https://github.com/jorendorff 前段时间,官方名为“ECMA-262,第六版,ECMAScript 2015语言 ...
- 谈谈三层架构中Model的作用
Model又叫实体类,这个东西,大家可能觉得不好分层.包括我以前在内,是这样理解的:UI<-->Model<-->BLL<-->Model<-->DAL ...
- iOS开发--开发者帐号
iOS应用上线 http://www.jianshu.com/p/ffddc5e5f0b9 http://www.jianshu.com/p/986e02d38f1b 好不容易终于申请下来了ios 公 ...