Android与JS交互的细节问题
ZenKeldie
8年前
<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>