为了使Android移动项目能够在较短的时间内完成开发,同时降低技术人员开发的成本投入,往往会采用Hybrid APP的开发模式。相关Hybrid APP(混合型应用)参看:http://blog.csdn.net/mahoking/article/details/30235243 采用这种模式,为了解决更好的用户体验,可访问本地资源的能力。势必需要了解与掌握Android(java)与JavaScript之间的交互、相互调用操作的方法与技术。
【转载使用,请注明出处:http://blog.csdn.net/mahoking/article/details/32707013】
【转载使用,请注明出处:http://blog.csdn.net/mahoking/article/details/32707013】
<RelativeLayout 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:background="@android:color/white" tools:context=".WebActivity" > <LinearLayout android:layout_height="wrap_content" android:background="@drawable/bgcolorblue" android:id="@+id/top_layout" android:layout_width="match_parent" android:layout_alignParentTop="true" android:orientation="horizontal"> <Button android:layout_height="wrap_content" android:background="@drawable/titlebackground" android:layout_weight="1" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_width="match_parent" android:id="@+id/javaCallJs_web_button" android:text="Java调用无参数JS"/> <Button android:layout_height="wrap_content" android:background="@drawable/titlebackground" android:layout_weight="1" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_width="match_parent" android:id="@+id/javaCallJsParam_web_button" android:text="Java调用含参数JS"/> </LinearLayout> <WebView android:layout_below="@id/top_layout" android:id="@+id/webView_web" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>
package cn.mahaochen.webviewtest; import cn.mahaochen.webviewtest.assist.ButtonListener; import cn.mahaochen.webviewtest.assist.MJavascriptInterface; import cn.mahaochen.webviewtest.assist.MWebChromeClient; import cn.mahaochen.webviewtest.assist.MWebViewClient; import android.os.Bundle; import android.app.Activity; import android.graphics.Color; import android.view.KeyEvent; import android.view.Menu; import android.webkit.WebView; import android.widget.Button; /** * @date 2014-6-20 * @author MaHaochen */ public class WebActivity extends Activity { private WebView webView; private Button paramButton; private Button noParamButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_web); initViews(); } private void initViews() { webView = (WebView) findViewById(R.id.webView_web); // 设置WebView对JavaScript的支持 webView.getSettings().setJavaScriptEnabled(true); // 从assets目录下面的加载html webView.loadUrl("file:///android_asset/web.html"); //自定义WebView的背景颜色 webView.setBackgroundColor(Color.TRANSPARENT);//先设置背景色为transparent // webView.setBackgroundResource(R.drawable.webbg);//然后设置背景图片 webView.setBackgroundResource(R.drawable.bgcolorblue); // webView.loadUrl("http://www.baidu.com"); MWebViewClient mWebViewClient = new MWebViewClient(webView,getApplicationContext()); webView.setWebViewClient(mWebViewClient); MWebChromeClient mWebChromeClient = new MWebChromeClient(getApplicationContext()); webView.setWebChromeClient(mWebChromeClient); //添加JS调用Android(Java)的方法接口 MJavascriptInterface mJavascriptInterface = new MJavascriptInterface(getApplicationContext()); webView.addJavascriptInterface(mJavascriptInterface, "WebViewFunc"); //初始化按钮,并绑定监听事件,事件的作用是调用JS的功能方法 noParamButton = (Button) findViewById(R.id.javaCallJs_web_button); paramButton = (Button) findViewById(R.id.javaCallJsParam_web_button); ButtonListener buttonListener = new ButtonListener(webView); noParamButton.setOnClickListener(buttonListener); paramButton.setOnClickListener(buttonListener); } /** * 退出监听 */ @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0 ) { if(webView.canGoBack()){ webView.goBack(); return false; }else { WebActivity.this.finish(); return true; } } return false; // return super.dispatchKeyEvent(event); } //*******************华丽的分割线*********************** @Override public boolean onCreateOptionsMenu(Menu menu) { // getMenuInflater().inflate(R.menu.web, menu); return true; } }
package cn.mahaochen.webviewtest.assist; import android.content.Context; import android.graphics.Bitmap; import android.net.http.SslError; import android.util.Log; import android.webkit.SslErrorHandler; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; /** * @date 2014-6-20 * @author MaHaochen */ public class MWebViewClient extends WebViewClient { private WebView webView; private Context context; public MWebViewClient(WebView webView) { super(); this.webView = webView; } public MWebViewClient(WebView webView, Context context) { super(); this.webView = webView; this.context = context; } /** * 在点击请求的是链接是才会调用, * 重写此方法返回true表明点击网页里面的链接还是在当前的webview里跳转,不跳到浏览器那边。 */ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { // 使用自己的WebView组件来响应Url加载事件,而不是使用默认浏览器器加载页面 webView.loadUrl(url); // 记得消耗掉这个事件。给不知道的朋友再解释一下,Android中返回True的意思就是到此为止, // 事件就会不会冒泡传递了,我们称之为消耗掉 return true; } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { // Toast.makeText(context, "WebViewClient.onPageStarted页面开始加载", Toast.LENGTH_SHORT).show(); Log.e("WebActivity", "页面加载开始"); super.onPageStarted(view, url, favicon); } @Override public void onPageFinished(WebView view, String url) { // Toast.makeText(context, "WebViewClient.onPageFinished页面加载完成", Toast.LENGTH_SHORT).show(); Log.e("WebActivity", "页面加载完成"); super.onPageFinished(view, url); } /** * 在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。 */ @Override public void onLoadResource(WebView view, String url) { // Toast.makeText(context, "WebViewClient.onLoadResource", Toast.LENGTH_SHORT).show(); Log.e("WebActivity", "onLoadResource"); super.onLoadResource(view, url); } /** * 重写此方法可以让webview处理https请求 [拓展] */ @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { super.onReceivedSslError(view, handler, error); } }
package cn.mahaochen.webviewtest.assist; import android.app.Activity; import android.content.Context; import android.webkit.JsPromptResult; import android.webkit.JsResult; import android.webkit.WebChromeClient; import android.webkit.WebView; /** * @date 2014-6-20 * @author MaHaochen */ public class MWebChromeClient extends WebChromeClient { private Context context; public MWebChromeClient(Context context) { super(); this.context = context; } // 处理Alert事件 @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) { return super.onJsAlert(view, url, message, result); } // onReceivedTitle()方法修改网页标题 @Override public void onReceivedTitle(WebView view, String title) { ((Activity)context).setTitle("可以用onReceivedTitle()方法修改网页标题"); super.onReceivedTitle(view, title); } // 处理Confirm事件 @Override public boolean onJsConfirm(WebView view, String url, String message, JsResult result) { return super.onJsConfirm(view, url, message, result); } // 处理提示事件 @Override public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { return super.onJsPrompt(view, url, message, defaultValue, result); } }
package cn.mahaochen.webviewtest.assist; import android.content.Context; import android.widget.Toast; /** * @date 2014-6-20 * @author MaHaochen */ public class MJavascriptInterface { private Context context; public MJavascriptInterface(Context context) { super(); this.context = context; } /** * JS调用Android(Java)无参数的方法 */ public void jsCallWebView() { Toast.makeText(context, "JS Call Java!", Toast.LENGTH_SHORT).show(); } /** * JS调用Android(Java)含参数的方法 * @param param */ public void jsCallWebView(String param) { Toast.makeText(context, "JS Call Java!" + param, Toast.LENGTH_SHORT).show(); } }
package cn.mahaochen.webviewtest.assist; import cn.mahaochen.webviewtest.R; import android.view.View; import android.view.View.OnClickListener; import android.webkit.WebView; /** * @date 2014-6-20 * @author MaHaochen */ public class ButtonListener implements OnClickListener{ private WebView webView; public ButtonListener(WebView webView) { super(); this.webView = webView; } @Override public void onClick(View v) { switch (v.getId()) { case R.id.javaCallJs_web_button: webView.loadUrl("javascript:javacalljs()"); // 无参数调用 break; case R.id.javaCallJsParam_web_button: webView.loadUrl("javascript:javacalljsparam(" + "'含参数'"+ ")"); // 无参数调用 break; default: break; } } }
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GBK"/> <script type="text/javascript"> //Java调用JS代码无参数 function javacalljs(){ document.getElementById("content").innerHTML += "<br\>java调用了js函数"; } //Java调用JS代码有参数 function javacalljsparam(param){ document.getElementById("content").innerHTML += "<br\>java调用了js函数含参数param"+param; } function testFunc(){ window.WebViewFunc.jsCallWebView(); } </script> <title>测试页面</title> </head> <body> <a onClick="testFunc()">无参数JS调用java代码</a><br/> <a onClick="window.WebViewFunc.jsCallWebView('含有参数')">含参数调用java代码</a><br/> <br /> <div id="content">内容显示 <a href="jump.html" target="_self">跳转新页面jump.html</a></div> </body> </html>
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GBK"/> <script type="text/javascript"> //Java调用JS代码无参数 function javacalljs(){ document.getElementById("content").innerHTML += "<br\>java调用了js函数"; } //Java调用JS代码有参数 function javacalljsparam(param){ document.getElementById("content").innerHTML += "<br\>java调用了js函数含参数param"+param; } function testFunc(){ window.WebViewFunc.jsCallWebView(); } </script> <title>测试页面</title> </head> <body> <a onClick="testFunc()">无参数JS调用java代码</a><br/> <a onClick="window.WebViewFunc.jsCallWebView('含有参数')">含参数调用java代码</a><br/> <br /> <div id="content">内容显示</div> </body> </html>