Apache Cordova 教程:使用 Cordova 開發移動應用程序

已發表: 2022-03-11
注意:由於這是最初編寫的,因此我已更新本文以使用 [email protected][email protected][email protected]

移動應用程序無處不在,從智能手機和平板電腦到智能手錶,很快也會出現在其他可穿戴設備中。 但是,為每個單獨的移動平台進行開發可能是一項艱鉅的任務,尤其是在您的資源有限,或者您是單個開發人員而不是移動應用程序開發公司的情況下。

這就是成為精通 Apache Cordova 開發人員可以派上用場的地方,因為它提供了一種使用標準 Web 技術(HTML5、CSS3 和 JavaScript)開發移動應用程序的方法。

2009 年,一家名為 Nitobi 的初創公司創建了 PhoneGap,這是一個用於訪問本地移動資源的開源 API,其目標是使開發人員能夠使用標準 Web 技術創建移動應用程序。 在 Nitobi 的設想中,大多數移動應用程序很快就會使用 PhoneGap 開發,但開發人員仍然可以在必要時選擇編寫本機代碼,無論是由於性能問題,還是缺乏訪問特定硬件的方法。

科爾多瓦PhoneGap?

沒有這樣的事,真的。 發生的事情是,Adobe 在 2011 年收購了 Nitobi,並將開源核心捐贈給了 Apache 軟件基金會,後者將其重新命名為 Apache Cordova。 您經常遇到的一個常見類比是,Cordova 之於 PhoneGap,就像 WebKit 之於 Chrome 或 Safari。

顯然,Cordova 和 PhoneGap 之間的差異在一開始是微乎其微的。 隨著時間的推移,Adobe PhoneGap 開發了自己的一組專有功能,而 Cordova 曾經——現在仍然——得到開源社區的支持。 本 Apache Cordova 評論和教程將更詳細地研究 Cordova 應用程序開發,雖然其中一些可能適用於 PhoneGap,但本質上不應將其視為 PhoneGap 教程。

Apache Cordova 功能

本質上,Cordova 對於本地開發的應用程序沒有任何限制。 使用 Cordova 獲得的只是一個 JavaScript API,它充當本機代碼的包裝器,並且跨設備保持一致。 您可以將 Cordova 視為具有 Web 視圖的應用程序容器,它覆蓋了設備的整個屏幕。 Cordova 使用的 Web 視圖與本機操作系統使用的 Web 視圖相同。 在 iOS 上,這是默認的 Objective-C UIWebView或自定義的WKWebView類; 在 Android 上,這是android.webkit.WebView

Apache Cordova 帶有一組預先開發的插件,可以訪問設備的相機、GPS、文件系統等。隨著移動設備的發展,添加對附加硬件的支持只是開發新插件的問題。

最後,Cordova 應用程序就像本地應用程序一樣安裝。 這意味著為 iOS 構建代碼將生成 IPA 文件,為 Android 構建 APK 文件,為 Windows Phone 構建代碼將生成 XAP 文件。 如果您在開發過程中投入足夠的精力,您的用戶甚至可能沒有意識到他們沒有使用本機應用程序。

Apache Cordova 功能

Apache Cordova 開發工作流程

使用 Cordova 進行開發時,您可以遵循兩條基本路徑:

  • 當您打算將應用程序部署到盡可能多的平台時,很少或沒有特定於平台的開發,您應該使用跨平台工作流。 支持此工作流的主要工具是 Cordova 命令行界面 (CLI),它用作更高級別的抽象,用於為不同平台配置和構建應用程序。 這是比較常用的開發路徑。
  • 如果您計劃在考慮特定平台的情況下開發應用程序,則應使用以平台為中心的工作流程。 這樣,您將能夠通過將本機組件與 Cordova 組件混合,在較低級別調整和修改您的代碼。 即使您可以使用這種方法進行跨平台開發,但過程會更長,更乏味。

通常建議從跨平台開發工作流程開始,因為切換到以平台為中心的開發相當簡單。 但是,如果您最初從以平台為中心的工作流程開始,您將無法切換到跨平台開發,因為一旦您運行構建過程,CLI 將覆蓋您的自定義設置。

先決條件和 Cordova 安裝

在安裝和運行與 Cordova 相關的任何內容之前,您需要為您打算為其構建應用程序的每個平台安裝 SDK。 本文將重點介紹Android平台; 但是,涉及其他平台的過程是相似的。

您應該下載此處找到的 Android SDK。 對於 Windows,SDK 以安裝程序的形式提供,而對於 Linux 和 OSX,它以存檔的形式提供,可以簡單地提取。 解壓/安裝軟件包後,您需要將sdk/toolssdk/platform-tools目錄添加到PATH變量中。 Cordova 使用PATH變量來查找構建過程所需的二進製文件。 如果您沒有安裝 Java,您應該繼續安裝 JDK 和 Ant。 ANT_HOMEJAVA_HOME應設置為 JDK 和 Ant 的 bin 文件夾,安裝 Android SDK 後,將ANDROID_HOME變量設置為Android/Sdk 。 三個*_HOME變量中的所有位置也應該在您的PATH變量中。

安裝 SDK 後, android命令將在您的命令行中可用。 執行它以打開 SDK 管理器並安裝最新的工具和 Android API。 您可能需要Android SDK 工具、Android SDK 平台工具、Android SDK 構建工具、SDK 平台、Google API 英特爾 x86 Atom 系統映像、Android SDK 源英特爾 x86 仿真器加速器(HAXM 安裝程序) 。 之後,您將能夠使用android avd創建一個模擬器。

Cordova CLI 依賴於 Node.js 和 Git 客戶端,因此請繼續從 nodejs.org 下載並安裝 Node,從 git-scm.com 下載並安裝 Git。 您將使用 npm 安裝 Cordova CLI 本身以及安裝其他插件,並且 Cordova 將在後台使用 git 以下載所需的依賴項。 最後,運行

npm install -g cordova

…全局安裝 Cordova CLI( npm install cordova本身是不夠的。)

總而言之,這些是您將需要的軟件包:

  • 爪哇
  • 螞蟻
  • 安卓 SDK
  • 節點JS
  • 吉特

這些環境變量需要更新:

  • PATH
  • JAVA_HOME
  • ANT_HOME
  • ANDROID_HOME

引導應用程序

如果您已成功安裝 Cordova,您現在應該可以訪問 Cordova 命令行實用程序。 打開您的終端或命令行,然後導航到您要創建第一個 Cordova 項目的目錄。 要引導應用程序,請鍵入以下命令:

 cordova create toptal toptal.hello HelloToptal

命令行由命令cordova的名稱和子命令create組成。 使用三個附加參數調用該子命令:將放置應用程序的文件夾、應用程序的命名空間及其顯示名稱。 這會在具有以下結構的文件夾中引導應用程序:

 toptal/ |-- hooks/ |-- platforms/ |-- plugins/ |-- www/ `-- config.xml

www文件夾包含您的應用程序核心。 這是您放置所有平台通用的應用程序代碼的地方。

雖然 Cordova 允許您輕鬆開發適用於不同平台的應用程序,但有時您需要添加自定義項。 在為多個平台開發時,您不想修改各種platforms/[platform-name][assets]/www目錄中的源文件,因為它們經常被頂級www文件覆蓋。

此時,您還可以打開config.xml文件並更改應用程序的元數據,例如作者和描述。

使用以下方法添加您的第一個平台:

 cordova platform add android

如果您稍後改變主意,您可以輕鬆地從構建過程中刪除一個平台:

 cordova platform rm android

檢查平台目錄後,您會注意到其中的android文件夾。 對於您添加的每個平台,Cordova 將在平台中創建一個新目錄並複制其中的www文件夾。 例如,如果您想為 Android 定制您的應用程序,您可以修改platforms/android/assets/www中的文件並切換到特定於平台的shell 工具。

但是,請記住,如果您使用 CLI(用於跨平台開發)重新構建應用程序,Cordova 將覆蓋您為每個平台所做的更改,因此請確保您將它們置於版本控制之下,或者您執行特定於平台的操作完成跨平台開發後的變化。 正如我們前面提到的,從跨平台遷移到特定於平台的開發很容易。 朝另一個方向發展則不然。

如果您想繼續使用跨平台工作流程並仍然進行特定於平台的自定義,您應該使用頂級合併文件夾。 從 Cordova 版本 3.5 開始,此文件夾已從默認應用程序模板中刪除,但如果您需要它,您可以在其他頂級目錄( hooksplatformspluginswww )旁邊簡單地創建它。

特定於平台的自定義放在merges/[platform-name]中,並在頂級www文件夾中的源文件之後應用。 這樣,您可以為某些平台添加新的源文件,也可以用特定於平台的源文件覆蓋整個頂級源文件。 以下面的結構為例:

 merges/ |-- wp8/ | `-- app.js |-- android/ | `-- android.js |-- www/ `-- app.js

在這種情況下,Android 的輸出文件將包含app.jsandroid.js文件,但 Windows Phone 8 的輸出文件將僅包含在 merges merges/wp8文件夾中找到的app.js文件,因為merges/[platform]中的文件會覆蓋www中的文件。

plugins 目錄包含每個平台的插件的信息。 此時,您應該只有android.json文件,該文件應具有以下結構:

 { "prepare_queue": { "installed": [], "uninstalled": [] }, "config_munge": { "files": {} }, "installed_plugins": {}, "dependent_plugins": {} }

讓我們構建應用程序並將其部署到 Android 設備。 如果需要,您也可以使用模擬器。

Cordova 提供了幾個 CLI 步驟來構建和運行您的應用程序: cordova preparecordova compilecordova build (這是前兩個的快捷方式)、 cordova emulatecordova run (它包含build並且也可以運行模擬器)。 這不應該讓您感到困惑,因為在大多數情況下,您希望在模擬器中構建和運行您的應用程序:

 cordova run --emulator

如果需要,您可以通過 USB 端口插入您的設備,啟用 USB 調試模式並將您的第一個 Apache Cordova 應用程序直接部署到您的設備上,只需運行:

 cordova run

這會將您的所有文件複製到platforms/*並執行所有必需的任務。

您可以通過指定要為其構建應用程序和/或什至特定模擬器的平台的名稱來限制構建過程的範圍,例如:

 cordova run android --emulator

要么

cordova run ios --emulator --target="iPhone-8-Plus"

動手實踐 Apache Cordova 教程

讓我們創建一個簡單的教程應用程序來演示 Cordova 及其插件的使用。 整個演示可以在這個 GitHub 存儲庫中找到,以便您可以下載它並通過這個簡短的 Cordova 教程來瀏覽它的一部分。

我們將使用您創建的初始設置並添加其他代碼。 假設我們想將新項目添加到虛構的 Toptal 數據庫中,並查看現有項目。 打開 index.html 並按以下方式設置兩個選項卡:

 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="format-detection" content="telephone=no" /> <meta name="msapplication-tap-highlight" content="no" /> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" /> <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css" /> <link rel="stylesheet" href="css/jquery.mobile-1.4.5.min.css" /> <link rel="stylesheet" type="text/css" href="css/toptal.css" /> <title>Hello Toptal</title> </head> <body> <div> <div> </div> </div> <footer> <ul> <li class="tab-button active" data-tab="#search-tab">Search Projects</li> <li class="tab-button" data-tab="#add-tab">Post a Project</li> </ul> </footer> <div></div> <script src="js/lib/jquery-1.11.1.min.js"></script> <script src="js/lib/jquery.mobile-1.4.5.min.js"></script> <script type="text/javascript" src="cordova.js"></script> <script type="text/javascript" src="js/SQLiteStorageService.js"></script> <script type="text/javascript" src="js/Controller.js"></script> <script type="text/javascript" src="js/index.js"></script> </body> </html>

請注意,我添加了 Bootstrap 和 jQuery Mobile 作為依賴項。 請注意,已經為構建現代混合應用程序開發了更好的解決方案和框架,但是由於大多數(如果不是全部)Web 開發人員都熟悉這兩個庫,因此將它們用於初學者教程是有意義的。 如果您願意,可以從 GitHub 下載樣式表或使用您自己的樣式表。

讓我們移動到index.js文件,並將其剝離為以下內容:

 var app = { // Application Constructor initialize: function() { if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) { document.addEventListener("deviceready", this.onDeviceReady, false); } else { this.onDeviceReady(); } }, onDeviceReady: function() { // We will init / bootstrap our application here }, }; app.initialize();

請記住,Cordova 應用程序所提倡的架構是設置單頁應用程序 (SPA)。 這樣,所有資源只在應用程序啟動時加載一次,並且只要應用程序運行,就可以一直停留在 Web 視圖中。 此外,使用 SPA,用戶將不會有頁面重新加載,這對於本機應用程序來說並不典型。 記住這一點,讓我們設置一個簡單的控制器來在兩個選項卡之間切換:

 var Controller = function() { var controller = { self: null, initialize: function() { self = this; this.bindEvents(); self.renderSearchView(); }, bindEvents: function() { $('.tab-button').on('click', this.onTabClick); }, onTabClick: function(e) { e.preventDefault(); if ($(this).hasClass('active')) { return; } var tab = $(this).data('tab'); if (tab === '#add-tab') { self.renderPostView(); } else { self.renderSearchView(); } }, renderPostView: function() { $('.tab-button').removeClass('active'); $('#post-tab-button').addClass('active'); var $tab = $('#tab-content'); $tab.empty(); $("#tab-content").load("./views/post-project-view.html", function(data) { $('#tab-content').find('#post-project-form').on('submit', self.postProject); }); }, renderSearchView: function() { $('.tab-button').removeClass('active'); $('#search-tab-button').addClass('active'); var $tab = $('#tab-content'); $tab.empty(); var $projectTemplate = null; $("#tab-content").load("./views/search-project-view.html", function(data) { $projectTemplate = $('.project').remove(); // Load projects here }); } } controller.initialize(); return controller; }

到目前為止,控制器有兩種方法,一種用於渲染 Search View,另一種用於渲染 Post Project 視圖。 讓我們在index.js文件中初始化它,首先在頂部聲明它並在 onDeviceReady 方法中構造它:

 // top of index.js var controller = null
 // inside onDeviceReady method controller = new Controller();

最後,在index.htmlindex.js引用上方添加一個腳本引用。 您可以直接從 GitHub 下載 Search 和 Post 視圖。 由於部分視圖是從文件中讀取的,因此某些瀏覽器(例如​​ Chrome)在嘗試呈現您的頁面時會抱怨跨域請求。

這裡可能的解決方案是運行本地靜態服務器,例如使用node-static npm 模塊。 此外,在這裡您可以開始考慮使用一些框架,例如 PhoneGap 和/或 Ionic。 它們都提供了一系列開發工具,包括在瀏覽器中模擬、熱重載和代碼生成(腳手架)。

現在,讓我們通過運行以下命令簡單地部署到 Android 設備:

 cordova run android

此時,您的應用程序應該有兩個選項卡。 第一個選項卡允許搜索項目:

Apache Cordova 應用程序

第二個選項卡允許發布新項目:

Apache Cordova 項目發布

我們現在所擁有的只是一個在 Web 視圖中運行的經典 Web 應用程序。 我們還沒有真正使用過任何本機功能,所以讓我們現在嘗試這樣做。 一個常見的問題是如何在設備上本地存儲數據,或者更準確地說,使用什麼類型的存儲。 有幾種方法可以去:

  • 本地存儲
  • WebSQL
  • 索引數據庫
  • 通過 Web 服務訪問的服務器端存儲
  • 提供其他選項的第三方插件

LocalStorage 可以存儲少量數據,但如果您正在構建數據密集型應用程序,它就不夠了,因為可用空間從 3 MB 到 10 MB 不等。 對於這種情況,IndexedDB 可能是更好的解決方案。 WebSQL 已被棄用,並且在某些平台上不受支持。 最後,使用 Web 服務來獲取和修改數據非常適合 SPA 範式,但是當您的應用程序脫機時它就會崩潰。 PWA 技術和 Service Worker 最近已進入 Cordova 世界以幫助解決此問題。

此外,還有許多額外的第三方插件可以填補 Cordova 核心的空白。 File 插件可能非常有用,因為它可以讓您訪問設備的文件系統,從而允許您創建和存儲文件。 現在,讓我們試試 SQLitePlugin,它為您提供本地 SQLite 數據庫。 您可以通過運行將其添加到您的項目中:

 cordova plugin add https://github.com/brodysoft/Cordova-SQLitePlugin

SQLitePlugin 為設備的 SQLite 數據庫提供 API,並作為真正的持久性機制。 我們可以通過以下方式創建一個簡單的存儲服務:

 SQLiteStorageService = function () { var service = {}; var db = window.sqlitePlugin ? window.sqlitePlugin.openDatabase({name: "demo.toptal", location: "default"}) : window.openDatabase("demo.toptal", "1.0", "DB para FactAV", 5000000); service.initialize = function() { // Initialize the database var deferred = $.Deferred(); db.transaction(function(tx) { tx.executeSql( 'CREATE TABLE IF NOT EXISTS projects ' + '(id integer primary key, name text, company text, description text, latitude real, longitude real)' ,[], function(tx, res) { tx.executeSql('DELETE FROM projects', [], function(tx, res) { deferred.resolve(service); }, function(tx, res) { deferred.reject('Error initializing database'); }); }, function(tx, res) { deferred.reject('Error initializing database'); }); }); return deferred.promise(); } service.getProjects = function() { // fetch projects } service.addProject = function(name, company, description, addLocation) { // add a new project } return service.initialize(); }

您可以從 GitHub 下載用於獲取和添加項目的代碼,並將其粘貼到相應的佔位符中。 不要忘記將 SQLiteStorageService.js 添加到 Controller.js 上方的 index.html 文件中,並通過修改 Controller 的 init 函數在控制器中對其進行初始化:

 initialize: function() { self = this; new SQLiteStorageService().done(function(service) { self.storageService = service; self.bindEvents(); self.renderSearchView(); }).fail(function(error) { alert(error); }); }

如果您看一下 service.addProject(),您會注意到它調用了 navigator.geolocation.getCurrentPosition() 方法。 Cordova 有一個地理定位插件,您可以使用它來獲取手機的當前位置,您甚至可以使用 navigator.geolocation.watchPosition() 方法在用戶位置發生變化時接收更新。

最後,讓我們添加控制器事件句柄,以便從數據庫中添加和獲取項目:

 renderPostView: function() { $('.tab-button').removeClass('active'); $('#post-tab-button').addClass('active'); var $tab = $('#tab-content'); $tab.empty(); $("#tab-content").load("./views/post-project-view.html", function(data) { $('#tab-content').find('#post-project-form').on('submit', self.postProject); }); }, postProject: function(e) { e.preventDefault(); var name = $('#project-name').val(); var description = $('#project-description').val(); var company = $('#company').val(); var addLocation = $('#include-location').is(':checked'); if (!name || !description || !company) { alert('Please fill in all fields'); return; } else { var result = self.storageService.addProject( name, company, description, addLocation); result.done(function() { alert('Project successfully added'); self.renderSearchView(); }).fail(function(error) { alert(error); }); } }, renderSearchView: function() { $('.tab-button').removeClass('active'); $('#search-tab-button').addClass('active'); var $tab = $('#tab-content'); $tab.empty(); var $projectTemplate = null; $("#tab-content").load("./views/search-project-view.html", function(data) { $('#addressSearch').on('click', function() { alert('Not implemented'); }); $projectTemplate = $('.project').remove(); var projects = self.storageService.getProjects().done(function(projects) { for(var idx in projects) { var $div = $projectTemplate.clone(); var project = projects[idx]; $div.find('.project-name').text(project.name); $div.find('.project-company').text(project.company); $div.find('.project-description').text(project.description); if (project.location) { var url = '<a target="_blank" href="https://www.google.com.au/maps/preview/@' + project.location.latitude + ',' + project.location.longitude + ',10z">Click to open map</a>'; $div.find('.project-location').html(url); } else { $div.find('.project-location').text("Not specified"); } $tab.append($div); } }).fail(function(error) { alert(error); }); }); }

要添加控制台和對話框插件,請執行以下命令:

 cordova plugin add org.apache.cordova.dialogs cordova plugin add org.apache.cordova.console

cordova.console 插件將通過在模擬器中啟用console.log()功能來幫助您進行調試。

您可以通過 Chrome 遠程調試器輕鬆調試 Android 應用程序。 連接設備後,單擊右上角(X 按鈕下方)的下拉菜單,展開更多工具,然後單擊檢查設備。 您應該會在列表中看到您的設備,並且應該能夠打開其調試控制台。

Safari 為調試在 USB 連接的設備或模擬器上運行的 iOS 應用程序提供了相同的功能。 只需在 Safari 設置 > 高級選項卡下啟用開發人員工具。

cordova.dialogs 插件啟用本機通知。 一種常見的做法是使用 cordova.dialogs API 以下列方式重新定義windows.alert方法:

 overrideBrowserAlert: function() { if (navigator.notification) { // Override default HTML alert with native dialog window.alert = function (message) { navigator.notification.alert( message, // message null, // callback "Toptal", // title 'OK' // buttonName ); }; } }

應該在deviceready事件處理程序中調用overrideBrowserAlert函數。

您現在應該能夠添加新項目並從數據庫中查看現有項目。 如果您選中“包括位置”複選框,設備將調用 Geolocation API 並將您的當前位置添加到項目中。

讓我們通過設置圖標和啟動畫面來為應用程序添加點睛之筆。 將以下內容添加到您的config.xml文件中:

 <platform name="android"> <icon src="www/img/logo.png" /> <splash src="www/img/logo.png" density="mdpi"/> <splash src="www/img/logo.png" density="hdpi"/> <splash src="www/img/logo.png" density="xhdpi"/> </platform>

最後,在www/img文件夾中放置一個徽標圖像。

Cordova 移動教程應用程序

您自己的 Cordova 應用程序

我們完成了 Apache Cordova 應用程序開發的基本步驟,並使用了我們自己的 JavaScript 架構和 CSS 樣式表。 本 Cordova 教程試圖展示 Apache Cordova 作為一種使用熟悉技術開發移動應用程序的方法的潛力,從而減少開發時間和為不同平台構建多個應用程序所需的工作量。

但是,在構建將要投入生產的應用程序時,建議您使用現有框架。 除了在預定義的體系結構中構建您的應用程序之外,這還可能為您提供一組組件,這些組件將幫助您的應用程序更接近原生的外觀和感覺。 一些值得注意的框架是 Ionic、Framework7、Weex、Ratchet、Kendo UI 和 Onsen UI。 祝你好運!

相關: Cordova 框架:Ionic 與 Framework7