
前言
很多复杂的UI界面,在AndroID中需要配合大量xml代码和java代码实现,而使用HTML5可以非常轻松的实现出来,而且具有很好的跨平台特性,让我们不必为了多个平台而重写代码,H5学习成本也较低,上手快。虽然从目前来说H5在AndroID系统中的速度可能还欠佳一些,但相信随着手机的性能不断的提高,这些问题都会被解决
使用H5开发AndroID的UI界面,最重要的就是如何实现Js代码和Java代码之间的互相调用了
在讲解之前,让我们先把项目跑起来
效果图:
准备好index.HTML文件,将它放入AndroID工程下的assets文件夹中:
<!DOCTYPE HTML PUBliC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/HTML4/loose.dtd"><HTML><head> <Meta http-equiv="Content-Type" content="text/HTML; charset=UTF-8"> <Title>JsTest</Title> <script src="app.Js"></script></head><body><table border="1" wIDth="100%" ID="table" cellspacing="0"> <tr> <td wIDth="50%" align="center">姓名</td> <td wIDth="50%" align="center">电话</td> </tr></table><hr><input ID="Jsinput"><button onclick="getMessage()">Js传值给Toast</button></body></HTML>
JavaScript的代码我单独写在一个Js文件中了,把app.Js文件也放入assets文件夹中:
function getMessage(){ var message = document.getElementByID("Jsinput"); contact.showToast(message.value);}function addPerson(persons){ var personObJs = eval(persons); var table = document.getElementByID("table"); for(var i=0; i < personObJs.length; i++){ var tr = table.insertRow(table.rows.length); var td1 = tr.insertCell(0); td1.align = "center"; var td2 = tr.insertCell(1); td2.align = "center"; td1.INNERHTML = personObJs[i].name; td2.INNERHTML = personObJs[i].phone; }}最后就是Java代码
public class MainActivity extends AppCompatActivity { private WebVIEw mWebVIEw; private button mJsMethodBtn; private JsObject Jsobj; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); mJsMethodBtn = (button) findVIEwByID(R.ID.btn_Js_method); mWebVIEw = (WebVIEw) findVIEwByID(R.ID.web_vIEw); mWebVIEw.loadUrl("file:///androID_asset/index.HTML"); WebSettings setting = mWebVIEw.getSettings(); setting.setJavaScriptEnabled(true); setting.setDefaultTextEnCodingname("utf-8"); Jsobj = new JsObject(); mWebVIEw.addJavaScriptInterface(Jsobj,"contact"); mJsMethodBtn.setonClickListener(new VIEw.OnClickListener() { @OverrIDe public voID onClick(VIEw v) { // 添加一个联系人 Jsobj.addPerson(); } }); } private class JsObject { // 此方法被Js调用 @JavaScriptInterface public voID showToast(String message) { Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show(); } // 在Web页面增加一个联系人 public voID addPerson() { String Json = "[{\"name\":\"zwt\",\"phone\":\"15949999999\"}]"; mWebVIEw.loadUrl("JavaScript:addPerson('" + Json + "')"); } } }还有布局代码:
<?xml version="1.0" enCoding="utf-8"?><linearLayoutxmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:background="#EED5B7" androID:orIEntation="vertical"> <WebVIEw androID:ID="@+ID/web_vIEw" androID:layout_wIDth="match_parent" androID:layout_height="360dp"/> <button androID:ID="@+ID/btn_Js_method" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:text="调用Js方法"/></linearLayout>
一、JavaScript调用AndroID中的方法
这里实现的场景是点击Web页面中的button,把input中输入的数据传递给AndroID系统,并通过Toast显示出来
对应的Js代码:
function getMessage(){ var message = document.getElementByID("Jsinput"); contact.showToast(message.value);}对应的java代码:
// 此方法被Js调用@JavaScriptInterfacepublic voID showToast(String message) { Toast.makeText(MainActivity.this,Toast.LENGTH_SHORT).show();}其中的“contact”其实指的就是我们在java代码中定义的JsObject类
他俩通过以下方法实现绑定:
mWebVIEw.addJavaScriptInterface(Jsobj,"contact");
第一个参数传入的是一个java对象,第二参数是指定对应的Js里调用该类时需要使用的自定义别名,这个方法的作用就是将一个Java对象和JavaScript联系起来
这里需要注意个问题,在SDK17以上的版本中,Google为了安全考虑,只允许Js调用带有@JavaScriptInterface注解的Java方法,所以我们要给被Js调用的java方法前加上@JavaScriptInterface注解
二、AndroID调用JavaScript中的方法
用户点击AndroID中的button控件后,传一个Json数据给JavaScript方法,Js解析Json数据后添加一个新的联系人显示在Web页面上
对应的Js代码:
function addPerson(persons){ var personObJs = eval(persons); var table = document.getElementByID("table"); for(var i=0; i < personObJs.length; i++){ var tr = table.insertRow(table.rows.length); var td1 = tr.insertCell(0); td1.align = "center"; var td2 = tr.insertCell(1); td2.align = "center"; td1.INNERHTML = personObJs[i].name; td2.INNERHTML = personObJs[i].phone; }}对应的java代码:
// 在Web页面增加一个联系人public voID addPerson() { String Json = "[{\"name\":\"zwt\",\"phone\":\"15949999999\"}]"; mWebVIEw.loadUrl("JavaScript:addPerson('" + Json + "')");}想要调用JavaScript中的某个方法,使用以下方法的标准格式就可以了:
mWebVIEw.loadUrl("JavaScript:xxxMethod()");“xxxMethod()”指的是JavaScript中的某个方法,如需调用其它方法,只要把后面的xxxMethod()替换成Js中对应的方法就好
三、常见问题
1.AndroID与Js互调不成功
给WebVIEw的setJavaScriptEnabled方法设置为true,使其允许Js代码执行 在API高于17的版本上,需要被Js调用的java方法前加上@JavaScriptInterface 检查Js中的别名是否写错,调用java方法时类的别名,一定要是mWebVIEw.addJavaScriptInterface(Jsobj,“contact”);里面定义的别名2.网页的alertd不出
需要重写WebChromeClIEnt中的onjsAlert()方法
mWebVIEw.setWebChromeClIEnt(new WebChromeClIEnt() { @OverrIDe public boolean onjsAlert(WebVIEw vIEw,String url,String message,JsResult result) { return super.onjsAlert(vIEw,url,result); }});如果需要把web页面的alertd出框替换成AndroID的AlertDialog,可以在onjsAlert()方法里进行重写,并设置return为true
3.Js调用java方法修改UI界面不成功
只要明白这一点:Js调用的java方法,其实是运行在另外一个子线程WebVIEwCoreThread中
测试一下:把以下语句分别放在Activity的onCreate()方法里和被Js调用的java方法中
Log.e(TAG,"运行线程name->" + Thread.currentThread().getname());
当onCreate执行时运行的log:
运行线程name->main
当JsObject类中的方法运行时的log:
运行线程name->WebVIEwCoreThread
很明显,子线程不允许修改主线程UI,所以我们想通过Js调用java代码直接修改UI界面的做法是不被允许的
如果需要修改,可以通过Handler机制去解决
4.如何让手机的返回键跳到上一个Web页面
如果不对手机系统的返回键进行处理,那么我们按返回键会直接关闭当前Activity,而不会回到上一个Web页面
解决这个问题,我们可以重写Activity中的onBackpressed()方法:
@OverrIDepublic voID onBackpressed() { super.onBackpressed(); if (mWebVIEw.canGoBack()) { mWebVIEw.goBack(); } else { finish(); }}总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对编程小技巧的支持。
您可能感兴趣的文章:android中webview控件和javascript交互实例android webview中使用Java调用JavaScript方法并获取返回值Android WebView使用方法详解 附js交互调用方法解析Android中webview和js之间的交互Android中 webView调用JS出错的解决办法Android webview与js交换JSON对象数据示例Android WebView上实现JavaScript与Java交互Android中在WebView里实现Javascript调用Java类的方法基于Android中Webview使用自定义的javascript进行回调的问题详解Android中WebView与Js交互的实现方法 总结以上是内存溢出为你收集整理的Android中实现WebView和JavaScript的互相调用详解全部内容,希望文章能够帮你解决Android中实现WebView和JavaScript的互相调用详解所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)