zoukankan      html  css  js  c++  java
  • Android WebView与JavaScript交互操作(Demo)

    版权声明:本文为博主原创文章,未经博主同意不得转载。 https://blog.csdn.net/ma_hoking/article/details/32707013

    应用场景:

           为了使Android移动项目能够在较短的时间内完毕开发。同一时候减少技术人员开发的成本投入。往往会採用Hybrid APP的开发模式。相关Hybrid APP(混合型应用)參看:http://blog.csdn.net/mahoking/article/details/30235243 採用这种模式,为了解决更好的用户体验。可訪问本地资源的能力。势必须要了解与掌握Android(java)与JavaScript之间的交互、相互调用操作的方法与技术。

    【转载使用。请注明出处:http://blog.csdn.net/mahoking/article/details/32707013

    知识点介绍:

            本文重要的知识点补充是WebView对象(android.webkit.WebView)。
    在Android手机中内置了一款高性能webkit内核浏览器。在Android SDK中封装为一个叫做WebView组件。

     
            WebKit是Mac OS X v10.3及以上版本号所包括的软件框架(对v10.2.7及以上版本号也可通过软件更新获取)。 同一时候。WebKit也是Mac OS X的Safari网页浏览器的基础。WebKit是一个开源项目。主要由KDE的KHTML改动而来而且包括了一些来自苹果公司的一些组件。 
             传统上,WebKit包括一个网页引擎WebCore和一个脚本引擎JavaScriptCore。它们分别相应的是KDE的KHTML和KJS。只是, 随着JavaScript引擎的独立性越来越强,如今WebKit和WebCore已经基本上混用不分(比如Google Chrome和Maxthon 3採用V8引擎,却仍然宣称自己是WebKit内核)。
    【注意事项】
    1.AndroidManifest.xml中必须使用许可"android.permission.INTERNET",否则会出Web page not available错误。
    2.假设訪问的页面中有Javascript。则webview必须设置支持Javascript。webview.getSettings().setJavaScriptEnabled(true);  
    3.假设页面中链接,假设希望点击链接继续在当前browser中响应,而不是新开Android的系统browser中响应该链接,必须覆盖 webview的WebViewClient对象。
    4.对于第一点, 假设使用Android SDK提供了一个schema,前缀为"file:///android_asset/"。WebView遇到这种schema。会去载入assets文件夹下的资源。

    如"file:///android_asset/demo.html"。可不必使用许可"android.permission.INTERNET"。
            在使用WebView组件的过程中可能会接触到WebViewClient与WebChromeClient,那么这两个类究竟有什么不同呢?
             WebViewClient主要帮助WebView处理各种通知、请求事件的。比方:

    • onLoadResource
    • onPageStart
    • onPageFinish
    • onReceiveError 等
                  WebChromeClient主要辅助WebView处理Javascript的对话框、站点图标、站点title、载入进度等比方:
    • onCloseWindow(关闭WebView)
    • onCreateWindow()
    • onJsAlert (WebView上alert无效,须要定制WebChromeClient处理弹出)
    • onJsPrompt
    • onJsConfirm
    • onReceivedTitle等
                 两者存在非常多的区别。在实际使用过程中,假设你仅仅准备让WebView处理一些html的页面内容,仅仅用WebViewClient就能够了。假设须要产生更丰富的处理效果,比方JS对话框、进度条等,就要使用到WebChromeClient。更进一步的介绍将在以下进行。

    【转载使用,请注明出处:http://blog.csdn.net/mahoking/article/details/32707013


    使用方式:

    第一步:
    本文的演示程序的主界面为activity_web.xml,相应的Activtiy为WebActivtiy.java。
    【activity_web.xml】
    <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>

    【WebActivtiy.java】
    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;
    	}
    }

    第二步:
            从第一步能够看到,以上补充了分别继承自WebViewClient、WebChromeClient的MWebViewClient、MWebChromeClient对象和MJavascriptInterface、ButtonListener对象。相应的对象的相关方法与操作的介绍将会在代码中较具体的叙述。
    【MWebViewClient.java】
    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); } }


    【MWebChromeClient.java】
    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);
    	}
    }

    【MJavascriptInterface.java】
    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();
    	}
    }

    【ButtonListener.java】
    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;
    		}
    	}
    }

    第三步:
            以上是所有的Java代码部分的信息。本例旨为演示WebView(Java)与JS(JavaScript)的互操作。

    所以须要补充另两个资源文件web.html与jump.html页面。该页面位于项目的assets文件夹下。


    【web.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">内容显示 <a href="jump.html" target="_self">跳转新页面jump.html</a></div>  
    </body>
    </html>

    【jump.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>

    ■注:因为本演示案例加入必要的图片文件与样式文件。才干够出现以下效果截图,所以假设获取完整的效果,请在【下载地址】栏。自行下载完整项目。


    【转载使用,请注明出处:http://blog.csdn.net/mahoking/article/details/32707013

    效果截图:


    下载地址:


    參考文献:

    1、 http://www.cnblogs.com/oakpip/archive/2011/04/08/2009800.html
    2、 http://blog.csdn.net/jackyhuangch/article/details/8310033

查看全文
  • 相关阅读:
    寒假学习报告05
    寒假学习报告04
    微信推送信息,支付宝支付接口
    Vue组件生成依赖文件,contentype
    redis之列表字典操作
    drf版本控制redis基础
    drf分页器,url控制器,解析器,响应器
    drf认证权限频率
    drf视图认证组件
    drf序列化组件
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10700309.html
  • Copyright © 2011-2022 走看看