介绍

随着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.htmlhttp://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本地函数的相互调用的更多相关文章

  1. WebView中JS调用Android Method 遇到的坑整理

    WebView是android中常用的一个组件,其作用是展示网页,并让网页和android app进行一些业务逻辑上的交互. 其坑无数,相信用过的都知道,一个一个来解决吧. 1.怎么互调: <! ...

  2. ASP.net关于C#代码与javaScript函数的相互调用

    C#代码与javaScript函数的相互调用 问:1.如何在JavaScript访问C#函数?2.如何在JavaScript访问C#变量?3.如何在C#中访问JavaScript的已有变量?4.如何在 ...

  3. python - 函数的相互调用 及 变量的作用域

    # -*- coding:utf-8 -*- '''@project: jiaxy@author: Jimmy@file: study_函数的相互调用及变量的作用域.py@ide: PyCharm C ...

  4. ASP.NET前台JS与后台CS函数如何互相调用

    摘要: 在实际的Web开发中,我们可能会常常遇到后台调用前台JS代码或者前台JS调用后台代码的情况.今天就把比较实用的前后台相互调用的方法总结出来和大家分享. 在实际的Web开发中,我们可能会常常遇到 ...

  5. JS代码和OC代码的相互调用

    JS调用OC 很多应用里面或多或少的调用了网页,来达到绚丽的效果,所谓的JS调用OC.....举个例子吧,网页上有个按钮 点击按钮跳转界面,跳转的动作由OC的代码实现. OC调用JS 还是举个例子,我 ...

  6. Android原生webview中js交互

    http://www.cnblogs.com/android-blogs/p/4891264.html Html页面和Java代码结合的方式一般用在界面经常被更改 的情况下,可以讲html放在网络中, ...

  7. android WebView中js的alert()失效

    WebView的设置代码 wv = (WebView) findViewById(R.id.webView1); wv.getSettings().setJavaScriptEnabled(true) ...

  8. Xamarin Android Webview中JS调用App中的C#方法

    参考链接:https://github.com/xamarin/recipes/tree/master/Recipes/android/controls/webview/call_csharp_fro ...

  9. android webview 中 js 模板引擎的使用

    最近在项目中要求用 webview 展示几个界面, 而后台返回的不是 html 而是 json 数据. 起初用 StringBuilder 一个一个拼 html, 后来感觉太繁琐,拼一个还行,拼多了就 ...

随机推荐

  1. C++时间标准库时间time和系统时间的使用

    #include <iostream> #include <time.h> #include <stdio.h> #include <windows.h> ...

  2. PHP7安装笔记

    PHP7安装笔记 时间 -- :: 喵了个咪 原文 http://www.hdj.me/php7-install-note 主题 PHP # 安装mcrypt yum install -y php-m ...

  3. HTML5程序设计--SVG

    SVG(Scalable Vector Graphics):可缩放矢量图形,一种二维图形表示语言. 借助SVG,我们可以实现很多同Canvas API类型的绘制操作,但在Canvas元素上绘制文本的时 ...

  4. post 方式提交XML文件调用接口

    import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Date; import java. ...

  5. MyEclipse — Maven+Spring+Struts+Hibernate 整合 [学习笔记-4]

    引入Hibernate 在pom.xml中加入jar包引用 <!-- hibernate4 --> <dependency> <groupId>org.hibern ...

  6. CoreData的简单使用(一)数据库的创建

    iOS有多种数据持久化得方式 plist文件(属性列表) preference(偏好设置,NSUserDefaults) NSKeyedArchiver(归档,用的不多) SQLite 3 (需要导入 ...

  7. SSH连接不上Linux的解决方法

    SSH连接不上Linux的解决方法: 连续弄了几次,今天早上终于把SSH连接虚拟机连接不通的问题解决了. 先简单说下概要: 主机装的是XP系统,虚拟机用的是red hat Linux. 我用的是nat ...

  8. lintcode:交换链表当中两个节点

    题目 给你一个链表以及两个权值v1和v2,交换链表中权值为v1和v2的这两个节点.保证链表中节点权值各不相同,如果没有找到对应节点,那么什么也不用做. 注意事项 你需要交换两个节点而不是改变节点的权值 ...

  9. lintcode:验证二叉查找树

    题目 给定一个二叉树,判断它是否是合法的二叉查找树(BST) 一棵BST定义为: 节点的左子树中的值要严格小于该节点的值. 节点的右子树中的值要严格大于该节点的值. 左右子树也必须是二叉查找树. 一个 ...

  10. MYSQL 当有两条重复数据时 保留一条

    delete from test  where id in (select id from (select  max(id) as id,count(text) as count from test ...