android webview H5开发若干问题之问题三:android和js交互问题

           安卓和js的交互,无非就是安卓的java调用js方法,js调用安卓本地java方法。先来一遍大家都知道的规则。

           安卓本地调用js:

    js调用安卓方法。在这方面呢,我的理解是安卓本地用java生成一个js方法。然后js在前端调用这个java生成的js方法。

   代码为:

     

     webView.addJavascriptInterface(new AndroidToJs(activity, webView), "LocalNative");
在这里我简写了好多,把最关键的代码贴过来。首先webview对象加一个js的接口对象。这个对象是自己定义的。然后最后一个字符串参数是定义一个对象名。

这里把
AndroidToJs贴出来。
import android.app.Activity;
import android.content.Intent;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;

import com.xiaoyunchengzhu.androidandh5.module.Convert;


/**
 * Created by TL on 2016/5/31.
 */
public class AndroidToJs {

    private Activity activity;
    private WebView webView;
    private Convert convert;

    public AndroidToJs(Activity activity, WebView webView) {
        this.activity = activity;
        this.webView = webView;
        convert = new Convert(webView);
    }

    @JavascriptInterface
    public void goBack() {
        webView.post(new Runnable() {
            @Override
            public void run() {
                if (webView.canGoBack()) {
                    webView.goBack();
                }
            }
        });

    }

    //{"action":"'+action+'","params":"'+param+'"}
    @JavascriptInterface
    public void execute(String json) {
        convert.convert(json, activity);
    }



}
在类的方法中加@JavasciriptInterface注解的,就是js方法。可以被前端调用,调用规则为在HTML的js中:
      LocalNative.execute('');
      LocalNative.goBack();
在这里有一个问题就是,被声明为js方法中的参数不能是复杂的参数,比如对象等等。比如js中方法的参数可以是方法,这里就不行。为了方便,统一传字符串。json字符串来串。


那么安卓调用js方法呢?


其实这个还是比较简单的。
在java中:
String json="";
webView.post(new Runnable() {
    @Override
    public void run() {
        webView.loadUrl("javascript:WhoisE('"+json+"')");
    }
});
这里的js方法在js中的声明是
function WhoisE(json){
//处理方式
}
其中这个方法必须是全局的方法。
也就是说安卓调用js的方法,必须是调用的全局的方法。


那么为什么要在webview的post中执行呢?这是因为前端js是单线程,在交互的过程中,直接执行
 
  
 
  
 
  
  webView.loadUrl("javascript:WhoisE('"+json+"')");这个方法,有可能会出错,跨线程操作。


      基础的都讲完了,不要以为结束了。在开发过程中能这么简单的安卓调用js,js调用安卓这就可以了。
       第一,当我们的H5所需要调用本地的方法过多了怎么办,比如上百个方法,难道就一直声明@javascriptInteface上百个吗?答:不是的。
       第二,前端的js总想简单的用一个方法来实现调用安卓并且传入回调方法。比如
   
        var test={ name:'lili',age:12  };
         Local.execute('ToAnotherActivity',test,function(json){
           
         })
调用本地安卓,传入参数,然后加一个回调匿名方法。多简单。

对于第一个问题,我们这里只声明一个@JavascriptInterface就可以。根据不同的传入的json的来判断该执行哪些对象中方法。这个判断不是用case,也不是用if,
而是使用反射机制把参数转化为对应的类,方法。对应执行。
对于第二个问题,需要和第一个配合。完善js代码。具体情况看githubdemo吧。
地址: https://github.com/xiaoyunchengzhu/AndroidAndH5



 







你可能感兴趣的:(安卓移动)