Android与JS交互的细节问题

ZenKeldie 7年前
   <p><strong>1.首先准备一个test.html文档,如下:</strong></p>    <pre>  <code class="language-javascript"><html>  <meta charset="utf-8"><head>      <title>js交互android</title>      <script type="text/javascript">          function show(){        var a = document.getElementById("text").value;          alert("警告,你输入的是:"+a);        }          function rfInfo(jsonStr) {                  document.getElementById("info").innerHTML="从Android客户端传来的作者信息:"+jsonStr.Developer;              }          function cfm() {          if(confirm("确认界面提示?"))  {            return true;          }  else   {        return false;          }         }   function pmt() {          var place = prompt("请输入位置?","");        }      </script>  </head>  <body>  <form action="">      <p>      <div id="info">从Android客户端传来的作者信息:</div>      </p>      <p>  <input type="text" id="text" value="input your msg"/>  </p>      <p>      <div id="inputinfo">输入的信息:</div>      </p>      <p><input type="button" id="btn_alert" onclick="show()"   value="Alert"/>  </p>      <p>  <input type="button" id="btn_cfm" onclick="cfm()"   value="Confirm"/></p>      <p>  <input type="button" id="btn_pmt" onclick="pmt()" value="Prompt"/>  </p>      <p>  <input type="button" id="btn_android" onclick="window.demo.adrdMethod()"                value="调用android方法"/>  </p>  </form>  </body>  </html></code></pre>    <p>注意看网页中《调用android方法》的button的点击事件,onclick中的内容就相当于指向android中adrdMethod()方法的id.</p>    <p><strong>2.Android的布局文件如下:</strong></p>    <pre>  <code class="language-javascript"><?xml version="1.0" encoding="utf-8"?>  <LinearLayout   xmlns:android="http://schemas.android.com/apk/res/android"      xmlns:tools="http://schemas.android.com/tools"      android:layout_width="match_parent"      android:layout_height="match_parent"      android:orientation="vertical"      tools:context="com.alden.l_alden.jsandandroid.MainActivity">      <Button          android:id="@+id/btn"          android:layout_width="wrap_content"      android:layout_height="wrap_content"          android:text="调用js方法"/>      <WebView          android:id="@+id/webview"          android:layout_width="match_parent"          android:layout_height="match_parent" />  </LinearLayout></code></pre>    <p><strong>3.在WebView中加载test.html页面,并且与Android交互</strong></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/d7b125db94e8c8d626dba9440be558bf.png"></p>    <p> </p>    <pre>  <code class="language-javascript">//  @SuppressLint("SetJavaScriptEnabled")  public class MainActivity extends AppCompatActivity {      private WebView webView;      private Button button;      final String  jsonStr = "{\"Developer\":\"Alden\",\"Place\":\"Nanjing\"}";      @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);          webView = (WebView) findViewById(R.id.webview);          button = (Button) findViewById(R.id.btn);         webView.setWebChromeClient(new WebChromeClient()   {              /*此处覆盖的是javascript中的alert方法。                      *当网页需要弹出alert窗口时,会执行onJsAlert中的方法                      * 网页自身的alert方法不会被调用。                      */              @Override              public boolean onJsAlert(WebView view, String url, String message, JsResult result) {                  Toast.makeText(getApplicationContext(), message,                        Toast.LENGTH_LONG).show();                  Log.d("info", "弹出了提示框");                  result.confirm();                  return true;            }    /*此处覆盖的是javascript中的confirm方法。                     *当网页需要弹出confirm窗口时,会执行onJsConfirm中的方法                     * 网页自身的confirm方法不会被调用。                   */              @Override              public boolean onJsConfirm(WebView view, String url,                              String message, JsResult result) {                  Log.d("info", "弹出了确认框");                  result.confirm();                  return true;            }              //在方法中写自己想要取代弹出js输入框的实现代码,比如一个Dialog    @Override              public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {    Log.d("info", "弹出了输入框");                  result.confirm();                  return true;            }              /*                      * 如果页面被强制关闭,弹窗提示:是否确定离开?                      * 点击确定 保存数据离开,点击取消,停留在当前页面                    */              @Override              public boolean onJsBeforeUnload(WebView view, String url,    String message, JsResult result) {                  Log.d("info", "弹出了离开确认框");                  result.confirm();                  return true;            }          });  webView.setWebViewClient(new WebViewClient() {              /*点击页面的某条链接进行跳转的话,会启动系统的默认浏览器进行加载,调出了我们本身的应用                      * 因此,要在shouldOverrideUrlLoading方法中                      */              @Override              public boolean shouldOverrideUrlLoading(WebView view, String url) {                //使用当前的WebView加载页面                view.loadUrl(url);                return true;            }  /*               * 网页加载完毕(仅指主页,不包括图片)               */              @Override              public void onPageStarted(WebView view, String url, Bitmap favicon) {                  // TODO Auto-generated method stub                  super.onPageStarted(view, url, favicon);              }              /*               * 网页加载完毕(仅指主页,不包括图片)               */              @Override              public void onPageFinished(WebView view, String url)   {                  // TODO Auto-generated method stub                  super.onPageFinished(view, url);              }              /*               * 加载页面资源               */              @Override              public void onLoadResource(WebView view, String url) {                  // TODO Auto-generated method stub       super.onLoadResource(view, url);              }              /*               * 错误提示               */              @Override              public void onReceivedError(WebView view, int errorCode,   String description, String failingUrl) {                  // TODO Auto-generated method stub  super.onReceivedError(view, errorCode, description, failingUrl);              }        });   //支持js代码(必须要的)  webView.getSettings().setJavaScriptEnabled(true);          //设置是否支持缩放          webView.getSettings().setSupportZoom(false);           //js调用android的方法接口,第二个参数就相当于js对象找android中这个方法的钥匙,  webView.addJavascriptInterface(new Object(){   //此方法内容须创建子线程操作,不然会出现下面这个错误  //Uncaught Error: Error calling method on NPObject           @JavascriptInterface         public void adrdMethod() {          new Thread(new Runnable() {                     @Override                     public void run() {                         Log.d("info", "js调用了Android方法");                     }                 }).start();              }          },"demo");            button.setOnClickListener(new View.OnClickListener() {        @Override              public void onClick(View v) {                  Log.d("info", "Android调用了js方法");                          /*                           * 通过webView.loadUrl("javascript:xxx")方式就可以调用当前网页中的名称为xxx的javascript方法                           */                  webView.loadUrl("javascript:rfInfo("+jsonStr+")");            }          });          webView.loadUrl("file:///android_asset/test.html");    }}</code></pre>    <h2><strong>总结:</strong></h2>    <p>1.Android调用js中的方法:</p>    <p>通过webView.loadUrl("javascript:xxx")方式就可以调用当前网页中的名称为xxx的javascript方法</p>    <p>2.js调用Android中的方法:</p>    <p>webView.addJavascriptInterface(Object object,String str):第一个参数是一个类对象,第二个参数是js中调用此类中的方法的标识</p>    <p>3.js调用的android的方法中的操作需要在子线程中,不然保错</p>    <p>Uncaught Error: Error calling method on NPObject ;</p>    <p>4.首先你要支持js代码(必须要的)</p>    <p>webView.getSettings().setJavaScriptEnabled(true);</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/01e5d4fa1c79</p>    <p> </p>