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.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

时间: 2024-10-25 20:31:03

WebView中Js与Android本地函数的相互调用的相关文章

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

WebView是android中常用的一个组件,其作用是展示网页,并让网页和android app进行一些业务逻辑上的交互. 其坑无数,相信用过的都知道,一个一个来解决吧. 1.怎么互调: <!DOCTYPE> <html> <head> <meta charset="UTF-8"> <script type="text/javascript"> function android(bl){ if(bl){

[Android]Webview中JS接口调用Java-版本问题

问题: The javascript to java bridge on 2.3 Gingerbread is causing crashes. This is 100% reproducible using the WebViewDemo application from here: http://code.google.com/p/apps-for-android/source/browse/#svn/trunk/Samples/WebViewDemo. Note: The project

webview中js调用Android中的方法

package com.example.helloworld; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.Menu; import android.webkit.WebView; public class MainActivity extends Activity { private WebView webView = null

C#代码与JAVASCRIPT函数的相互调用

问:1.如何在JavaScript访问C#函数?2.如何在JavaScript访问C#变量?3.如何在C#中访问JavaScript的已有变量?4.如何在C#中访问JavaScript函数? 问题1答案如下:javaScript函数中执行C#代码中的函数:方法一:1.首先建立一个按钮,在后台将调用或处理的内容写入button_click中;        2.在前台写一个js函数,内容为document.getElementById("btn1").click();        3.

Android高手进阶教程(二十)之---Android与JavaScript方法相互调用!

在Android中通过WebView控件,可以实现要加载的页面与Android方法相互调用,我们要实现WebView中的addJavascriptInterface方法,这样html才能调用android方法,在这里我个人觉得有点和DWR相似. 为了让大家容易理解,我写了一个简单的Demo,具体步骤如下: 第一步:新建一个Android工程,命名为WebViewDemo(这里我在assets里定义了一个html页面). 第二步:修改main.xml布局文件,增加了一个WebView控件还有But

Android组件间的相互调用

我们研究两个问题,1.Service如何通过Broadcaster更改activity的一个TextView.(研究这个问题,考虑到Service从服务器端获得消息之后,将msg返回给activity) 2.Activity如何通过Binder调用Service的一个方法.(研究这个问题,考虑到与服务器端交互的动作,打包至Service,Activity只呈现界面,调用Service的方法) 结构图见如下:效果图如下:点击“start service”按钮,启动Service,然后更改Activ

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

# -*- coding:utf-8 -*- '''@project: jiaxy@author: Jimmy@file: study_函数的相互调用及变量的作用域.py@ide: PyCharm Community Edition@time: 2018-11-10 10:04@blog: https://www.cnblogs.com/gotesting/ ''' # 1. 函数的相互调用# 从上往下按顺序执行 def print_msg(content): print('我想说:{}'.fo

Android 与web的相互调用

这篇文章简单讲解 Android与web的简单交互. 1:Android显示web网页:利用Android的WebView控件展示网页 2:web网页调用Android方法:利用注解的方式将Android的方法公开,在javascript中调用公开的方法. 接下来,展示具体的小例子: 1:WebView显示web网页: 布局: <WebView android:id="@+id/loadWeb" android:layout_width="match_parent&qu

OC-关于OC中的对象方法和类方法的相互调用1

对象方法和类方法的区别和概念,大家都知道,关于两者之间的相互调用,本人小有总结 #import "NSString+WW.h" @implementation NSString (WW) //类方法------------------------ +(int )numberCountOfString:(NSString *)str{ //    int count=0; //    for (int i=0; i<str.length; i++) { //     char c