介绍

随着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. 创建第一个MVC

    创建第一个MVC(asp.net)和默认路由设置 Asp.net的MVC已经出到了4.0,我用的是visual studio2013,接下来努力学下MVC,学之前的话我建议大家先去学下三层(分别是DA ...

  2. Topcoder srm 632 div2

    脑洞太大,简单东西就是想复杂,活该一直DIV2; A:水,基本判断A[I]<=A[I-1],ANS++; B:不知道别人怎么做的,我的是100*N*N;没办法想的太多了,忘记是连续的数列 我们枚 ...

  3. css display visibility

    当visibility被设置为"hidden"的时候,元素虽然被隐藏了,但它仍然占据它原来所在的位置.注意,当元素被隐藏之后,就不能再接收到其它事件了. display属性就有一点 ...

  4. 【剑指offer】连续子数组最大和

    思路dp很清楚,就是要注意细节. int FindGreatestSumOfSubArray(vector<int> array) { ; ], tempsum = array[]; // ...

  5. iOS项目的完整重命名方法图文教程

    原文链接:http://www.cocoachina.com/ios/20150104/10824.html iOS项目的完整重命名方法图文教程 前言:在iOS开发中,有时候想改一下项目的名字,都会遇 ...

  6. POJ 1665

    #include<iostream>//chengdacaizi 08.11.12 #include<iomanip> #define p 3.1415927 using na ...

  7. 从Config文件中读取节点的配置信息

    下面是web.config中与本内容有关的细节 <appSettings> <add key="servername" value="www" ...

  8. hdu 1531(差分约束)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1531 差分约束的题之前也碰到过,刚好最近正在进行图论专题的训练,就拿来做一做. ①:对于差分不等式,a ...

  9. jqGrid中实现radiobutton的两种做法

    http://blog.sina.com.cn/s/blog_4f925fc30102e27j.html   jqGrid中实现radiobutton的两种做法 ------------------- ...

  10. Linux服务器 scp 不需要密码配置与密钥转换(id_rsa->ppk)

    案例:▲服务器A对服务器B.C进行ssh连接,免输入密码    或▲服务器A向服务器B.C复制文件(源文件在服务器A上),免输入密码 主机A:192.168.0.221主机B:192.168.0.22 ...