講解PhoneGap的底層原理,需要從講解PhoneGap幾個重要的類開始:
DroidGap類:
public class DroidGap extends Activity implements CordovaInterface {...}
DroidGap是接口CordovaInterface的實現類,繼承Android Activity,具有Android Activity的整個生命周期。DroidGap覆寫了Activity的 onCreate()、onPause()、onResume()、onDestroy
等方法。
1 /** 2 * Load the url into the webview. 3 * 4 * @param url 5 */ 6 public void loadUrl(String url) { 7 8 // Init web view if not already done 9 if (this.appView == null) { 10 this.init(); 11 } 12 13 // Set backgroundColor 14 this.backgroundColor = this.getIntegerProperty("backgroundColor", Color.BLACK); 15 this.root.setBackgroundColor(this.backgroundColor); 16 17 // If keepRunning 18 this.keepRunning = this.getBooleanProperty("keepRunning", true); 19 20 // Then load the spinner 21 this.loadSpinner(); 22 23 this.appView.loadUrl(url); 24 }
其中有一個比較重要的方法是loadUrl(String url),也就是在你的Activity里super.loadUrl()時調用的方法。之所以說這個方法重要,是因為我們可以把這個方法看成是PhoneGap的入口函
數。PhoneGap在loadUrl里做了一些初始化工作,會調用到init()函數。
/** * Create and initialize web container with default web view objects. */ public void init() { CordovaWebView webView = new CordovaWebView(DroidGap.this); this.init(webView, new CordovaWebViewClient(this, webView), new CordovaChromeClient(this, webView)); }
init()完成了WebView的設置等重要工作,這對理解PhoneGap底層原理有很重要的作用。從代碼中可以看到,初始化時首先實例化了
CordovaWebView類型的webView對象,這里的CordovaWebView繼承Android WebView類,后面會有講到。然后傳入不同參數重載了init()方
法。
傳入參數包括webView、CordovaWebViewClient類型的webViewClient對象和CordovaChromeClient類型ChromeClient對
象。CordovaWebViewClient和CordovaChromeClient分別繼承Android WebViewClient和ChromeClient類,這兩個類在后面也會提到。
1 /** 2 * Initialize web container with web view objects. 3 * 4 * @param webView 5 * @param webViewClient 6 * @param webChromeClient 7 */ 8 public void init(CordovaWebView webView, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient) { 9 LOG.d(TAG, "DroidGap.init()"); 10 11 // Set up web container 12 this.appView = webView; 13 this.appView.setId(100); 14 15 this.appView.setWebViewClient(webViewClient); 16 this.appView.setWebChromeClient(webChromeClient); 17 webViewClient.setWebView(this.appView); 18 webChromeClient.setWebView(this.appView); 19 20 this.appView.setLayoutParams(new LinearLayout.LayoutParams( 21 ViewGroup.LayoutParams.MATCH_PARENT, 22 ViewGroup.LayoutParams.MATCH_PARENT, 23 1.0F)); 24 25 // Add web view but make it invisible while loading URL 26 this.appView.setVisibility(View.INVISIBLE); 27 this.root.addView(this.appView); 28 setContentView(this.root); 29 30 // Clear cancel flag 31 this.cancelLoadUrl = false; 32 33 }
這里的appView也是CordovaWebView類型,是DroidGap類的一個屬性。對appView進行了初始化設置,appView實際就是剛才實例化的
webView,然后設置它的webViewClient和ChromeClient分別為剛才的傳入參數webViewClient和ChromeClient。
可能會有人不理解為什么要設置這兩個Client呢?這里需要先從Android原生角度介紹一下WebView組件以及WebViewClient和ChromeClient這兩個類的
區別:
WebView組件
WebView組件實質是移動設備的內置瀏覽器。WebView這個內置瀏覽器特性是Web能被打包成本地客戶端的基礎,可方便的用HTML5、CSS3頁面布局,這是
移動Web技術的優勢相對於原生開發。
PhoneGap針對不同平台的WebView做了擴展和封裝,使WebView這個組件變成可訪問設備本地API的強大瀏覽器,所以開發人員在PhoneGap框架下可通過
JavaScript訪問設備本地API。
WebViewClient
WebViewClient幫助WebView處理各種通知、請求事件的,具體來說包括:
onLoadResource()
onPageStarted()
onPageFinished()
onReceiveError()
onReceivedHttpAuthRequest()
WebChromeClient
WebChromeClient是輔助WebView處理Javascript的對話框,網站圖標,網站title,加載進度等
onCloseWindow(關閉WebView)
onCreateWindow()
onJsAlert (WebView上alert是彈不出來東西的,需要定制你的WebChromeClient處理彈出)
onJsPrompt()
onJsConfirm()
onProgressChanged()
onReceivedIcon()
onReceivedTitle()
不早了,今天先寫到這里吧(未完待續。。。)