phoneGap底层研究1

在phonegap中,通过android和iphone的webview实现对html网页的展示。本文的目的采用android中webview实现对html调用以及js调用java方法的。其实质也是phonegap插件的原理。

PhoneGap如何工作?

PhoneGap架构拥有强大的跨平台访问设备能力,但是其工作原理并不神秘,下面以iPhone和Android平台为例进行分析。

iPhone和Android平台共同点是都有内置的WebView组件,其具备两个特性:

1、WebView组件实质是移动设备的内置浏览器

WebView这个内置浏览器特性是Web能被打包成本地客户端的基础,可方便的用HTML5、CSS3页面布局,这是移动Web技术的优势相对于原生开发。

2、WebView提供Web和设备本地API双向通信的能力

PhoneGap针对不同平台的WebView做了扩展和封装,使WebView这个组件变成可访问设备本地API的强大浏览器,所以开发人员在PhoneGap框架下可通过JavaScript访问设备本地API。

明白以上两个特性,参照下面PhoneGap与设备本地API通信图,一个成熟的PhoneGap技术客户端运行状况如下:

应用运行在WebView组件上 —》 通过PhoneGap在各平台的扩展 —》 最终访问设备本地资源

WebView可以显示Web页面,并且,可以像普通的View那样应用到任何布局中。

WebView提供了两个方法用于显示网页的内容:loadUrl()用于加载一个指定的URL,而loadData()则用于直接向WebView写入指定的HTML文本。此外,loadDataWithBaseURL()loadData()似,但是,如果写入的HTML文本包含图片、CSS等外部资源的相对链接时,WebView就会根据指定的baseURL来正确地加载这些资源比如:"file:///android_asset/", "<html><body background="lenovo.png">"这个方法正好符合我们显示Item的需求。

WebView的属性:Android中专门通过WebSettings来设置WebView的一些属性、状态等。可以通过WebView.getSettings()得到这个设置。

WebViewClient:专门辅助WebView处理各种通知、请求等事件的类,可以通过WebView的一个

setWebViewCilent()方法来指定一个WebViewClient对象。

如:setWebViewClient(new WebViewClient(){  

    @Override public boolean shouldOverrideUrlLoading(此方法:控制新的连接在当前WebView中打开)});

如果你在HTML中添加了一些JavaScript,你会发现WebView并不会执行JavaScript,这是因为WebView默认关闭了JavaScript功能。为了能执行JavaScript,需要在加载任何URL或写入HTML文本前开启JavaScript,代码如下:

WebView web = (WebView) this.findViewById(R.id.webview);
web.getSettings().setJavaScriptEnabled(true);

WebChromeClient:辅助WebView处理JavaScript的对话框、网站图标、网站Title、加载进度等

我们还可以向WebView添加更多的代码,甚至可以监听和控制WebView执行JavaScript

为了让Webview从apk载文件中加载assets,Android SDK提供了一个schema,前缀为file:///android_asset/WebView遇到这样的schema,就去当前包中的assets目录中找内容。

如:file:///android_asset/demo.html

一个简单的列子(不完整,主要说明使用WebViewClent控制新连接在当前WebView中打开):

WebView browser=(WebView)findViewById(R.id.webkit);

browser.setWebViewClient(genWebViewClientForURL());

 
  WebSettings s = browser.getSettings();
    s.setSaveFormData(false);
    s.setSavePassword(false);
    s.setUseWideViewPort(true);
    s.setJavaScriptEnabled(true);
    s.setLightTouchEnabled(true);

private WebViewClient genWebViewClientForURL() {
  return new CiHaiWebViewClient();
}

private class CiHaiWebViewClient extends WebViewClient
{
  @Override

  public boolean shouldOverrideUrlLoading(WebView view, String url) {
   String strURL = "";
   try {
    strURL = URLDecoder.decode(url.replaceAll("fake://wistron/", ""), "utf-8");
   } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
   }
   if (strURL.equals(STR_PRE))
   {  …… } else if (strURL.equals(STR_NEXT)) { …… } else { ……  }
  }

有代码:browser.loadDataWithBaseURL("fake://wistron/", htmlText, "text/html", "utf-8", null);

这里的baseUrl:fake://wistron/故这里需要WebViewClientshouldOverrideUrlLoading()方法,且要实现URLDecoder.decode(url.replaceAll("fake://wistron/", ""), "utf-8");

目录结构如下:

android的类如下:

Java代码 复制代码 收藏代码
  1. package com.easyway.webview; 
  2.  
  3. import android.app.Activity; 
  4. import android.os.Bundle; 
  5. import android.view.KeyEvent; 
  6. import android.webkit.WebSettings; 
  7. import android.webkit.WebView; 
  8. /**
  9. * 为了方便网页和Android应用的交互,Android系统提供了WebView中JavaScript
  10. * 网页脚本调用Java类方法的机制。只要调用addJavascriptInterface方法即可映
  11. * 射一个Java对象到JavaScript对象上。
  12. * 1.先在layout文件中加入<WebView>元素  或WebView webView = new WebView(this);
  13. * 2.由于应用程序需要访问网络,所以需要在AndroidManifest.xml中请求网络权限的:
  14.    3.使用Web View
  15.    4.加载一个页面,可以用loadUrl()方法,例如:
  16.          设置WevView要显示的网页:
  17.   互联网用:webView.loadUrl("http://android.tgbus.com");
  18.   本地文件用:webView.loadUrl(file:///android_asset/xx.html);固定格式
  19.   本地文件存放在:assets文件中
  20.    5.在Web View 中使用JavaScript 如果你加载到 Web View 中的网页使用了JavaScript,那么,
  21.    需要在Websetting 中开启对JavaScript的支持,因为Web View 中默认的是JavaScript未启用。
  22. *
  23. * 如果希望点击链接由自己处理,而不是新开Android的系统browser中响应该链接。
  24.   给WebView添加一个事件监听对象(WebViewClient)
  25.   并重写其中的一些方法
  26.   shouldOverrideUrlLoading:对网页中超链接按钮的响应。
  27.   当按下某个连接时WebViewClient会调用这个方法,并传递参数:按下的url
  28.   onLoadResource  
  29.   onPageStart 
  30.   onPageFinish 
  31.   onReceiveError
  32.   onReceivedHttpAuthRequest
  33. 如果用webview点链接看了很多页以后,如果不做任何处理,点击系统“Back”键,整个浏览器会调用
  34. finish()而结束自身,如果希望浏览的网页回退而不是退出浏览器,需要在当前Activity中处理并消
  35. 费掉该Back事件。
  36.   覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法。
  37.   public boolean onKeyDown(int keyCoder,KeyEvent event){
  38.                         if(webView.canGoBack() && keyCoder == KeyEvent.KEYCODE_BACK){
  39.                                 webview.goBack();   //goBack()表示返回webView的上一页面
  40.                                 return true;
  41.                         }
  42.                         return false;
  43.                 }
  44. *
  45. * @Title:
  46. * @Description: 实现Android中WebView实现Javascript调用Java类方法
  47. * @Copyright:Copyright (c) 2011
  48. * @Company:易程科技股份有限公司
  49. * @Date:2012-5-21
  50. * @author  longgangbai
  51. * @version 1.0
  52. */ 
  53. public class AndroidWebClientActivity extends Activity { 
  54.     private WebView mWebView; 
  55.     /** Called when the activity is first created. */ 
  56.     @Override 
  57.     public void onCreate(Bundle savedInstanceState) { 
  58.         super.onCreate(savedInstanceState); 
  59.         setContentView(R.layout.main); 
  60.         mWebView = (WebView) findViewById(R.id.wv_content); 
  61.         //使用垂直滚动条 
  62.         mWebView.setVerticalScrollbarOverlay(true); 
  63.         //获取WebView相关的设置的对象 
  64.         final WebSettings settings = mWebView.getSettings(); 
  65.         settings.setSupportZoom(true); 
  66.  
  67.         //WebView启用Javascript脚本执行 
  68.         settings.setJavaScriptEnabled(true); 
  69.         //设置js可以打开window 
  70.         settings.setJavaScriptCanOpenWindowsAutomatically(true); 
  71.         //映射Java对象到一个名为”js2java“的Javascript对象上 
  72.         //JavaScript中可以通过"window.js2java"来调用Java对象的方法 
  73.         //要在webview中,调用addJavascriptInterface(OBJ,interfacename) 
  74.         //其中,obj为和javascript通信的应用程序,interfacename为提供给JAVASCRIPT调用的 名称,设置如下 
  75.         mWebView.addJavascriptInterface(new JSInvokeClass(), "js2java");  
  76.         //index.html在android的assets目录中 
  77.         mWebView.loadUrl("file:///android_asset/index.html"); 
  78.     } 
  79.     /**网页Javascript调用接口**/ 
  80.     class JSInvokeClass { 
  81.         public String getText() { 
  82.             return "调用服务器的方法返回的信息"
  83.         } 
  84.     } 
  85.   
  86.     
  87.    /**
  88.     * 利用Web View的历史记录来实现页面navigate backword.
  89.     *重载Activity中的onKeyDown方法,实现此功能:
  90.     */ 
  91.    @Override      
  92.    public boolean onKeyDown(int keyCode, KeyEvent event) {         
  93.     // Check if the key event was the BACK key and if there's history          
  94.    if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()){              
  95.        mWebView.goBack();              
  96.    return true;          
  97.    }         
  98.     // If it wasn't the BACK key or there's no web page history, bubble up to the default          
  99.    // system behavior (probably exit the activity)          
  100.    return super.onKeyDown(keyCode, event);      
  101.    }  
package com.easyway.webview;

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebSettings;
import android.webkit.WebView;
/**
 * 为了方便网页和Android应用的交互,Android系统提供了WebView中JavaScript
 * 网页脚本调用Java类方法的机制。只要调用addJavascriptInterface方法即可映
 * 射一个Java对象到JavaScript对象上。
 * 1.先在layout文件中加入<WebView>元素  或WebView webView = new WebView(this);
 * 2.由于应用程序需要访问网络,所以需要在AndroidManifest.xml中请求网络权限的:
   3.使用Web View
   4.加载一个页面,可以用loadUrl()方法,例如:
         设置WevView要显示的网页:
  互联网用:webView.loadUrl("http://android.tgbus.com"); 
  本地文件用:webView.loadUrl(file:///android_asset/xx.html);固定格式
  本地文件存放在:assets文件中
   5.在Web View 中使用JavaScript 如果你加载到 Web View 中的网页使用了JavaScript,那么,
   需要在Websetting 中开启对JavaScript的支持,因为Web View 中默认的是JavaScript未启用。
 * 
 * 如果希望点击链接由自己处理,而不是新开Android的系统browser中响应该链接。
  给WebView添加一个事件监听对象(WebViewClient)

  并重写其中的一些方法
  shouldOverrideUrlLoading:对网页中超链接按钮的响应。
  当按下某个连接时WebViewClient会调用这个方法,并传递参数:按下的url 
  onLoadResource   
  onPageStart  
  onPageFinish  
  onReceiveError
  onReceivedHttpAuthRequest


如果用webview点链接看了很多页以后,如果不做任何处理,点击系统“Back”键,整个浏览器会调用
finish()而结束自身,如果希望浏览的网页回退而不是退出浏览器,需要在当前Activity中处理并消
费掉该Back事件。

  覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法。

  public boolean onKeyDown(int keyCoder,KeyEvent event){
                        if(webView.canGoBack() && keyCoder == KeyEvent.KEYCODE_BACK){
                                webview.goBack();   //goBack()表示返回webView的上一页面
                                return true;
                        }
                        return false;
                }


 * 
 * @Title: 
 * @Description: 实现Android中WebView实现Javascript调用Java类方法
 * @Copyright:Copyright (c) 2011
 * @Company:易程科技股份有限公司
 * @Date:2012-5-21
 * @author  longgangbai
 * @version 1.0
 */
public class AndroidWebClientActivity extends Activity {
	private WebView mWebView;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mWebView = (WebView) findViewById(R.id.wv_content);
        //使用垂直滚动条
        mWebView.setVerticalScrollbarOverlay(true);
        //获取WebView相关的设置的对象
        final WebSettings settings = mWebView.getSettings();
        settings.setSupportZoom(true);

        //WebView启用Javascript脚本执行
        settings.setJavaScriptEnabled(true);
        //设置js可以打开window
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        //映射Java对象到一个名为”js2java“的Javascript对象上
        //JavaScript中可以通过"window.js2java"来调用Java对象的方法
        //要在webview中,调用addJavascriptInterface(OBJ,interfacename)
        //其中,obj为和javascript通信的应用程序,interfacename为提供给JAVASCRIPT调用的 名称,设置如下
        mWebView.addJavascriptInterface(new JSInvokeClass(), "js2java"); 
        //index.html在android的assets目录中
        mWebView.loadUrl("file:///android_asset/index.html");
    }
    /**网页Javascript调用接口**/
    class JSInvokeClass {
        public String getText() {
            return "调用服务器的方法返回的信息";
        }
    }
 
   
   /**
    * 利用Web View的历史记录来实现页面navigate backword.
    *重载Activity中的onKeyDown方法,实现此功能:
    */
   @Override     
   public boolean onKeyDown(int keyCode, KeyEvent event) {        
    // Check if the key event was the BACK key and if there's history         
   if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()){             
	   mWebView.goBack();             
   return true;         
   }        
    // If it wasn't the BACK key or there's no web page history, bubble up to the default         
   // system behavior (probably exit the activity)         
   return super.onKeyDown(keyCode, event);     
   } 
}

html代码如下:

Html代码 复制代码 收藏代码
  1. <!DOCTYPE HTML> 
  2. <html> 
  3. <head> 
  4. <meta name="viewport" content="width=320; user-scalable=no" /> 
  5. <meta http-equiv="Content-type" content="text/html; charset=utf-8"> 
  6. <title>jQuery Google Maps Plugin</title> 
  7. <script> 
  8. function init(){ 
  9.      //js调用java的方法 
  10.      //返回值作为text的文本值 
  11.      //调用方式:window.暴露名称.方法 
  12.      var val=window.js2java.getText(); 
  13.      var txt=document.getElementById("txt"); 
  14.      txt.value=val; 
  15. </script> 
  16. </head> 
  17. <body onload="init()"> 
  18.   文件信息:<input id="txt" type="text"> 
  19. </body> 
  20. </html> 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值