WebView中Js與Android本地函數的相互調用

介紹

隨着Html5的普及,html在表現力上不必定比原生應用差,而且有很強的擴展兼容性,因此愈來愈多的應用是採用Html與Android原生混合開發模式實現。javascript

既然要實現混合開發,那麼Js與Android原生函數的相互調用就必不可少了。這裏寫了一個demo,實現點擊html中的圖片進行本地展現。html

原理

一、Android調用js很簡單,直接webView.loadUrl("javascript:JS中的方法名稱()");便可。java

二、js調用Android方法,須要使用WebView.addJavascriptInterface(Object obj, String interfaceName)這個方法告訴WebView我要添加一個Js接口調用本地函數。
android

三、demo中用到了universalimageloader與PhotoView實現圖片加載與瀏覽web

http://www.cnblogs.com/leestar54/p/4220068.htmlhttp://www.cnblogs.com/leestar54/p/4105726.html數組

四、demo中涉及到了一個JS閉包的問題,閉包中所記錄的自由變量,只是對這個變量的一個引用,而非變量的值,當這個變量被改變了,閉包裏獲取到的變量值,也會被改變.閉包

http://www.cnblogs.com/mzwr1982/archive/2012/05/20/2509295.htmlapp

實現

MainActivityiview

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);
    }
}

完成以後看起來是這樣的ide

demo地址

連接:http://pan.baidu.com/s/1dDEPPkP 密碼:7y6g

相關文章
相關標籤/搜索