介绍

随着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. ubuntu搭建lnmp

    http://wiki.ubuntu.org.cn/Nginx#.E5.AE.89.E8.A3.85Php.E5.92.8Cmysql

  2. MVC 强类型视图

    MVC里面的强类型视图的确是一个很强大的东西,结合EF(Entity Framework)的话更加强大,可以直接把你的数据库直接生成强视图的增删查改的视图,在视图中所有Model的属性均动态的,我们不 ...

  3. JavaScript之arguments对象讲解

    javascript的arguments对象类似于PHP的extract()函数实现. 在不确定函数参数个数的情况下,可以通过arguments访问参数,并以索引0为起始. function sayH ...

  4. javascript实现数据结构与算法系列:队列 -- 链队列和循环队列实现及示例

    1 队列的基本概念 队列(Queue):也是运算受限的线性表.是一种先进先出(First In First Out ,简称FIFO)的线性表.只允许在表的一端进行插入,而在另一端进行删除. 队首(fr ...

  5. Unity3D判断鼠标向右或向左滑动,响应不同的事件

    private var first = Vector2.zero; private var second = Vector2.zero; function Update () { } function ...

  6. LCT小结

    LCT真是灵活好用… LCT的基本思想与树链剖分差不多,都是把树剖成一条条链,只不过LCT用的是SPLAY维护的,而且,SPLAY的链是会变化的,不像剖分是定死的. LCT最重要的操作就是access ...

  7. 字典树trie的学习与练习题

    博客详解: http://www.cnblogs.com/huangxincheng/archive/2012/11/25/2788268.html http://eriol.iteye.com/bl ...

  8. POJ 2185 Milking Grid (KMP,求最小覆盖子矩阵,好题)

    题意:给出一个大矩阵,求最小覆盖矩阵,大矩阵可由这个小矩阵拼成.(就如同拼磁砖,允许最后有残缺) 正确解法的参考链接:http://poj.org/showmessage?message_id=153 ...

  9. netaddr 0.7.12

    Pythonic manipulation of IPv4, IPv6, CIDR, EUI and MAC network addresses https://pypi.python.org/pyp ...

  10. POJ 1658

    #include<iostream>//cheng da cai zi using namespace std; int main() { int i; int time; ]; cin& ...