个性化阅读
专注于IT技术分析

Apache Cordova教程:使用Cordova开发移动应用程序

本文概述

注意:由于本文是最初撰写的, 因此我更新了本文, 使其可以使用[受电子邮件保护], [受电子邮件保护]和[受电子邮件保护]

从智能手机和平板电脑到智能手表, 移动应用程序无处不在, 并且很快也出现在其他可穿戴设备中。但是, 为每个单独的移动平台进行开发可能是一项详尽的任务, 尤其是在你的资源有限或你是单个开发人员而不是移动应用程序开发公司的情况下。

通过提供一种使用标准Web技术(HTML5, CSS3和JavaScript)开发移动应用程序的方法, 可以成为一名精通Apache Cordova的开发人员的地方。

2009年, 一家名为Nitobi的初创公司创建了PhoneGap, 这是一种用于访问本地移动资源的开源API, 其目标是使开发人员能够使用标准Web技术创建移动应用程序。在Nitobi的视野中, 大多数移动应用程序将很快使用PhoneGap进行开发, 但是由于性能问题或缺少访问特定硬件的方法, 开发人员仍可以在必要时编写本机代码。

Cordova 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构建代码将生成X​​AP文件。如果你在开发过程中投入了足够的精力, 你的用户甚至可能没有意识到他们没有使用本机应用程序。

Apache Cordova功能

Apache Cordova开发工作流程

使用Cordova进行开发时, 可以遵循两个基本路径:

  • 如果你打算将应用程序部署到尽可能多的平台, 而很少或没有平台特定的开发, 则应使用跨平台工作流。支持此工作流程的主要工具是Cordova命令行界面(CLI), 它是用于为不同平台配置和构建应用程序的高级抽象。这是更常用的开发路径。
  • 如果计划在考虑特定平台的情况下开发应用程序, 则应使用以平台为中心的工作流程。这样, 通过将本机组件与Cordova组件混合, 你将能够在较低级别上进行调整和修改代码。即使可以将这种方法用于跨平台开发, 该过程也将更长且繁琐。

通常建议从跨平台开发工作流程开始, 因为切换到以平台为中心的开发非常简单。但是, 如果最初从以平台为中心的工作流开始, 则将无法切换到跨平台开发, 因为一旦运行构建过程, CLI将会覆盖你的自定义项。

先决条件和Cordova安装

在安装和运行与Cordova相关的任何东西之前, 你需要为要为其构建应用程序的每个平台安装SDK。本文将重点介绍Android平台;但是, 涉及其他平台的过程是相似的。

你应该下载此处找到的Android SDK。对于Windows, SDK是一个安装程序, 而对于Linux和OSX, 它是一个归档文件, 可以简单地将其提取。解压缩/安装软件包后, 你需要将sdk / tools和sdk / platform-tools目录添加到PATH变量中。 Cordova使用PATH变量来查找构建过程所需的二进制文件。如果你尚未安装Java, 则应继续并将JDK与Ant一起安装。 ANT_HOME和JAVA_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, Intel x86 Atom系统映像, Android SDK的源代码和Intel x86 Emulator Accelerator(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本身还不够。)

总结一下, 这些是你需要的软件包:

  • Java
  • 蚂蚁
  • Android SDK
  • 节点JS

这些环境变量将需要更新:

  • 路径
  • JAVA_HOME
  • ANT_HOME
  • ANDROID_HOME

引导应用程序

如果你已经成功安装了Cordova, 则现在应该可以访问Cordova命令行实用程序。打开终端或命令行, 然后导航到要创建第一个Cordova项目的目录。要引导应用程序, 请输入以下命令:

cordova create srcmini srcmini.hello Hellosrcmini 

命令行由命令cordova的名称组成, 后跟子命令create。使用三个附加参数调用该子命令:将放置应用程序的文件夹, 应用程序的名称空间及其显示名称。这会将应用程序引导到具有以下结构的文件夹中:

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

www文件夹包含你的应用程序核心。在这里放置所有平台通用的应用程序代码。

虽然Cordova允许你轻松地为不同平台开发应用程序, 但有时你需要添加自定义项。在针对多个平台进行开发时, 你不想在各个platform / [platform-name] [assets] / www目录中修改源文件, 因为它们经常被顶层www文件覆盖。

此时, 你还可以打开config.xml文件并更改应用程序的元数据, 例如作者和描述。

使用以下方法添加第一个平台:

cordova platform add android

如果以后改变主意, 则可以轻松地从构建过程中删除平台:

cordova platform rm android

检查平台目录后, 你会注意到其中的android文件夹。对于你添加的每个平台, Cordova将在平台中创建一个新目录, 并在其中复制www文件夹。例如, 如果要为Android定制应用程序, 则可以修改platform / android / assets / www中的文件, 然后切换到特定于平台的Shell工具。

但是, 请记住, 如果使用CLI(用于跨平台开发)重建应用程序, Cordova将覆盖你对每个平台所做的更改, 因此请确保将它们置于版本控制下, 或者执行特定于平台的操作跨平台开发完成后, 更改。如前所述, 从跨平台开发到特定于平台的开发很容易。朝另一个方向前进不是。

如果要继续使用跨平台工作流程并仍然进行特定于平台的自定义, 则应使用顶层合并文件夹。从Cordova 3.5版开始, 此文件夹已从默认应用程序模板中删除, 但是如果需要, 你可以在其他顶级目录(钩子, 平台, 插件和www)旁边创建它。

特定于平台的自定义项放置在merges / [platform-name]中, 并在顶级www文件夹中的源文件之后应用。这样, 你可以为特定平台添加新的源文件, 或者可以使用平台特定的文件覆盖整个顶级源文件。以以下结构为例:

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

在这种情况下, Android的输出文件将同时包含app.js和android.js文件, 但Windows Phone 8的输出文件将仅包含在merges / wp8文件夹中找到的app.js文件, 因为合并/ [平台]中的文件将覆盖www中的文件。

plugins目录包含有关每个平台的插件的信息。此时, 你应该只拥有android.json文件, 该文件应具有以下结构:

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

让我们构建应用程序并将其部署到Android设备上。如果需要, 你也可以使用仿真器。

Cordova提供了几个用于构建和运行你的应用程序的CLI步骤:cordova准备, cordova编译, cordova构建(这是前两个的快捷方式), cordova仿真和cordova运行(包含了构建功能, 并且也可以运行模拟器)。这不会使你感到困惑, 因为在大多数情况下, 你希望在仿真器中构建和运行你的应用程序:

cordova run --emulator

如果需要, 你可以通过USB端口插入设备, 启用USB调试模式, 然后将第一个Apache Cordova应用程序直接部署到设备上, 只需运行即可:

cordova run 

这会将所有文件复制到platform / *并执行所有必需的任务。

你可以通过指定要为其构建应用程序和/或特定仿真器的平台的名称来限制构建过程的范围, 例如:

cordova run android --emulator

or

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

动手Apache Cordova教程

让我们创建一个简单的教程应用程序, 以演示Cordova及其插件的用法。整个演示可以在此GitHub存储库中找到, 以便你可以下载该文件并通过此简短的Cordova教程进行部分学习。

我们将使用你创建的初始设置并添加其他代码。假设我们要向虚拟的srcmini数据库添加新项目, 并查看现有项目。打开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/srcmini.css" />
        <title>Hello srcmini</title>
    </head>
    <body>
        <div id="container">
            <div id="tab-content">
                    
            </div>
        </div>
        <footer>
            <ul id="menu">
                <li id="search-tab-button" class="tab-button active" data-tab="#search-tab">Search Projects</li>
                <li id="post-tab-button" class="tab-button" data-tab="#add-tab">Post a Project</li>
            </ul>
        </footer>
        <div id="dev-null" style="display: none"></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;
}

到目前为止, 控制器有两种方法, 一种用于呈现”搜索”视图, 另一种用于呈现”后项目”视图。首先在顶部声明它, 然后在onDeviceReady方法中对其进行构造, 从而在index.js文件中对其进行初始化:

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

最后, 在index.html的引用上方的index.html中添加脚本引用。你可以直接从GitHub下载搜索和发布视图。由于部分视图是从文件中读取的, 因此某些浏览器(例如Chrome)在尝试呈现你的页面时会抱怨跨域请求。

此处可能的解决方案是运行本地静态服务器, 例如使用节点静态npm模块。另外, 你可以在这里开始考虑使用诸如PhoneGap和/或Ionic之类的框架。它们都提供了一系列开发工具, 包括在浏览器中进行仿真, 热重载和代码生成(脚手架)。

现在, 我们只需运行以下命令即可将其部署到Android设备:

cordova run android

此时, 你的应用程序应具有两个选项卡。第一个选项卡允许搜索项目:

Apache Cordova应用程序

第二个选项卡允许发布新项目:

Apache Cordova项目发布

现在, 我们所拥有的只是一个在Web视图中运行的经典Web应用程序。我们还没有真正使用任何本机功能, 所以现在就尝试进行操作。一个常见的问题是如何在设备上本地存储数据, 或更准确地说, 要使用哪种类型的存储。有几种方法:

  • 本地存储
  • WebSQL
  • 索引数据库
  • 通过Web服务访问的服务器端存储
  • 第三方插件提供其他选项

LocalStorage可以存储少量数据, 但如果你要构建数据密集型应用程序, 则无法满足要求, 因为可用空间从3到10 MB不等。对于这种情况, IndexedDB可能是更好的解决方案。不建议使用WebSQL, 某些平台不支持。最后, 使用Web服务来获取和修改数据非常适合SPA范例, 但是当你的应用程序脱机时, 它就会崩溃。 PWA技术与Service Workers一起最近已进入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.srcmini", location: "default"}) :
        window.openDatabase("demo.srcmini", "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
                "srcmini", // 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

赞(0)
未经允许不得转载:srcmini » Apache Cordova教程:使用Cordova开发移动应用程序

评论 抢沙发

评论前必须登录!