作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
菲利普·佩特科夫斯基的头像

Filip Petkovski

拥有MCS学位,并通过谷歌代码之夏(2012)有了一个坚实的开端。, 菲利普有做桌面的经验, mobile, 以及全栈web开发.

Previously At

Shopify
Share
Note: 由于这篇文章最初是写的,我已经更新了这篇文章,以便使用cordova@8.0.0, cordova-android@7.0.0和cordova-ios@4.5.4.

移动应用程序无处不在, 首先是智能手机和平板电脑, to smart watches, 并很快在其他可穿戴设备中找到, too. However, 针对每个单独的移动平台进行开发可能是一项艰巨的任务, 尤其是当你的资源有限的时候, 或者如果你是一个单独的开发者,而不是一个 移动应用开发公司.

这就是成为一个 精通Apache Cordova开发人员 能够提供一种使用标准web技术(html5)开发移动应用程序的方法, CSS3, and JavaScript.

In 2009, 一家名为Nitobi的初创公司创建了PhoneGap, 用于访问本地移动资源的开源API, 其目标是使开发人员能够使用标准的web技术创建移动应用程序. 在Nitobi的愿景中, 大多数移动应用程序将很快使用PhoneGap开发, 但是开发人员在必要时仍然可以选择编写本机代码, 可能是由于性能问题, 或者缺乏访问特定硬件的方法.

科尔多瓦PhoneGap?

没有这样的事,真的. 事情是这样的, Adobe于2011年收购了Nitobi, 并将开源核心捐赠给了Apache软件基金会, 谁把它重新命名为阿帕奇·科尔多瓦. 你经常会遇到的一个常见类比是,Cordova之于PhoneGap,就像WebKit之于Chrome或Safari.

显然,Cordova和PhoneGap之间的差异在一开始是很小的. With time, Adobe PhoneGap 开发了自己的一套专有功能, 而Cordova仍然是由开源社区支持的. 这篇Apache Cordova回顾和教程将更详细地研究Cordova应用程序开发, 虽然其中一些可能适用于PhoneGap, 这不应该被视为PhoneGap教程, per se.

Apache Cordova功能

实质上,Cordova对于本地开发的应用程序没有任何限制. 你用Cordova得到的只是一个JavaScript API, 哪个可以作为本机代码的包装器,并且跨设备保持一致. 你可以把Cordova看作是一个带有web视图的应用程序容器, 哪个覆盖了设备的整个屏幕. Cordova使用的web视图与本机操作系统使用的web视图相同. 在iOS上,这是默认的Objective-C UIWebView or a custom WKWebView class; on Android, this is android.webkit.WebView.

Apache Cordova带有一组预先开发的插件,可以访问设备的摄像头, GPS, file system, etc. 随着移动设备的发展, 添加对额外硬件的支持只是开发新插件的问题.

最后,安装Cordova应用程序 就像本地应用程序一样. 这意味着为iOS构建代码将生成一个IPA文件, Android为APK文件, 为Windows Phone构建会生成一个XAP文件. 如果你在开发过程中投入了足够的精力, 您的用户甚至可能没有意识到他们使用的不是本机应用程序.

Apache Cordova功能

Apache Cordova开发工作流

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

  • 当您打算将应用程序部署到尽可能多的平台时, 很少或没有特定于平台的开发, 您应该使用跨平台工作流. 支持这个工作流的主要工具是Cordova命令行接口(CLI)。, 哪一个可以作为配置和构建不同平台的应用程序的高级抽象. 这是更常用的开发路径.
  • 如果您计划使用特定的平台开发应用程序, 您应该使用以平台为中心的工作流. This way, 通过混合本地组件和Cordova组件,你可以在较低的层次上调整和修改你的代码. 尽管您可以使用这种方法进行跨平台开发, 这个过程会更漫长,更乏味.

通常建议从跨平台开发工作流开始, 因为切换到以平台为中心的开发是相当直接的. However, 如果您最初从以平台为中心的工作流开始, 您将无法切换到跨平台开发,因为一旦运行构建过程,CLI将覆盖您的自定义.

前提条件和Cordova安装

在安装和运行与Cordova相关的任何东西之前, 您需要为您打算构建应用程序的每个平台安装SDK. We will focus on the Android platform in this article; however, 涉及其他平台的过程是类似的.

您应该下载找到的Android SDK here. For Windows, SDK作为安装程序提供, 而对于Linux和OSX,它是一个可以简单提取的归档文件. 解压/安装包后,您需要添加 sdk/tools and sdk /平台工具 目录到你的 PATH variable. The PATH 变量被Cordova用来查找构建过程所需的二进制文件. 如果没有安装Java,则应该继续安装JDK和Ant. ANT_HOME and JAVA_HOME 设置为JDK和Ant的bin文件夹,安装Android SDK后,设置 ANDROID_HOME variable to Android/Sdk. 三个地点的所有位置 *_HOME 变量也应该在 PATH variable.

安装SDK之后 android 命令将在命令行中可用. 执行它可以打开SDK管理器并安装最新的工具和Android API. 你可能需要 Android SDK工具, Android SDK平台工具, Android SDK构建工具, SDK Platform, 谷歌api英特尔x86 Atom系统映像, Android SDK源码 and Intel x86模拟器加速器(HAXM安装程序). 之后,您将能够创建一个模拟器 android avd.

Cordova CLI依赖于Node.js和Git客户端,所以继续从 nodejs.org, and Git from git-scm.com. 您将使用npm来安装Cordova CLI本身以及安装其他插件, Cordova将在后台使用git来下载所需的依赖项. Finally, run

NPM install -g cordova

全局安装Cordova CLI (NPM安装cordova 它本身是不够的.)

总而言之,这些是您需要的软件包:

  • Java
  • Ant
  • Android SDK
  • NodeJS
  • Git

这些环境变量需要更新:

  • PATH
  • JAVA_HOME
  • ANT_HOME
  • ANDROID_HOME

引导应用程序

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

Cordova创建total total.你好HelloToptal 

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

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

The www 文件夹包含应用程序核心. 这是您放置应用程序代码的地方,这对于所有平台都是通用的.

虽然Cordova允许您轻松地为不同的平台开发应用程序, 有时需要添加自定义. 在针对多个平台进行开发时,您不希望在各种平台中修改源文件 平台/[平台名称](资产)/ www 目录,因为它们经常被顶级目录覆盖 www files.

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

添加你的第一个平台,使用:

Cordova平台添加android

如果你后来改变了主意,你可以很容易地从构建过程中删除一个平台:

Cordova平台rm android

检查平台目录后,您将注意到 android 文件夹在里面. 对于您添加的每个平台,Cordova将在platforms中创建一个新目录,并复制 www 文件夹在里面. 例如,如果你想为Android定制你的应用程序,你可以修改 平台/ android /资产/ www 并切换到特定于平台的shell工具.

However, 请记住,如果使用CLI重新构建应用程序(用于跨平台开发), Cordova将覆盖您为每个平台所做的更改, 因此,要么确保将它们置于版本控制之下, 或者在完成跨平台开发后进行特定于平台的更改. 正如我们前面提到的,从跨平台转向特定于平台的开发是很容易的. 相反的方向则不是.

如果您希望继续使用跨平台工作流,并仍然进行特定于平台的自定义, 您应该使用顶级合并文件夹. 来自Cordova版本3.5 onward, 此文件夹已从默认应用程序模板中删除, 但如果你需要的话, 您可以简单地将其与其他顶级目录(hooks, platforms, plugins, and www).

中放置了特定于平台的定制 合并/[平台名称],并在顶级中的源文件之后应用 www folder. This way, 您可以为某些平台添加新的源文件, 或者可以使用特定于平台的源文件覆盖整个顶级源文件. 以下面的结构为例:

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

在这种情况下,Android的输出文件将包含 app.js and android.js 文件,但Windows Phone 8的输出文件将只包含 app.js 文件中找到的 merges/wp8 文件夹,自文件在 合并/(平台) 覆盖 www.

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

{
    " prepare_queue ": {
        “安装”:[],
        “卸载”:[]
    },
    " config_munge ": {
        "files": {}
    },
    “installed_plugins”:{},
    “dependent_plugins”:{}
}

让我们构建应用程序并将其部署到Android设备上. 如果你愿意,你也可以使用模拟器.

Cordova提供了几个CLI步骤来构建和运行你的应用: cordova prepare, cordova compile, cordova build (这是前两个的快捷方式), cordova emulate and cordova run (包含 build 也可以运行模拟器). 这应该不会让你感到困惑, 因为在大多数情况下,你想在模拟器中构建和运行你的应用程序:

运行——模拟器

If you want, 你可以通过USB接口插入设备, 启用USB调试模式,并部署您的第一个Apache Cordova应用程序直接到您的设备简单运行:

cordova run 

这将把你所有的文件复制到 platforms/* 并执行所有要求的任务.

您可以通过指定要为其构建应用程序和/或甚至特定模拟器的平台名称来限制构建过程的范围, e.g:

运行android——模拟器

or

运行ios -emulator -target="iPhone-8-Plus"

动手Apache Cordova教程

让我们创建一个简单的教程应用程序来演示Cordova及其插件的使用. 完整的演示可以在 这个GitHub存储库 这样你就可以下载它,并通过这个简短的Cordova教程来学习它的部分内容.

我们将使用您创建的初始设置并添加其他代码. 假设我们想要向假想的Toptal数据库添加新项目, 以及查看现有的. Open up index.并以以下方式设置两个选项卡:



    
        
        
        
        
        
        
        
        Hello Toptal
    
    
        

注意,我已经添加了Bootstrap和 jQuery 移动作为依赖项. 请注意,为构建现代混合应用程序,已经开发了更好的解决方案和框架, 但是由于大多数(如果不是全部)web开发人员都熟悉这两个库, 在初学者教程中使用它们是有意义的. 您可以从GitHub下载样式表或使用自己的样式表,如果您喜欢的话.

让我们转到 index.js 文件,并将其剥离为以下内容:

var app = {
    //应用程序构造函数
    初始化:函数(){
        if (navigator.userAgent.匹配(/ (iPhone iPad iPod | | |安卓|黑莓)/)){
            document.addEventListener(“deviceready”.onDeviceReady、假);
        } else {
            this.onDeviceReady ();
        }
    },

    onDeviceReady:函数(){
        //我们将在这里init / bootstrap我们的应用程序
    },
};
app.initialize();

请记住,Cordova应用程序提倡的架构是建立一个单页面应用程序(SPA)。. This way, 所有的资源只在应用程序启动时加载一次, 并且只要应用程序正在运行,就可以一直留在web视图中. In addition, with SPAs, 用户将不会有页面重新加载,这不是典型的本地应用程序. 记住这一点,让我们设置一个简单的控制器来在两个选项卡之间切换:

var Controller = function() {
    Var控制器= {
        self: null,
        初始化:函数(){
            self = this;
            this.bindEvents();
            self.renderSearchView (); 
        },

        bindEvents:函数(){
            $('.tab-button').on('click', this.onTabClick);
        },

        onTabClick:函数(e) {
            e.preventDefault ();
            if ($(this).hasClass(“活跃的”)){
                return;
            }
            
            Var TAB = $(this).data('tab');
            If (tab === '#add-tab') {
                self.renderPostView ();
            } else {
                self.renderSearchView ();
            }
        },

        renderPostView:函数(){
            $('.tab-button').removeClass(“活跃的”);
            $ (' # post-tab-button ').addClass(“活跃的”);

            Var $tab = $ (' # tab-content ');
            $tab.empty();
            $ (" # tab-content ").load("./视图/ post-project-view., function(data) {
                $ (' # tab-content ').找到(“# post-project-form”).(“提交”,自我.postProject);
            }); 
        },
       
        renderSearchView:函数(){
            $('.tab-button').removeClass(“活跃的”);
            $ (' # search-tab-button ').addClass(“活跃的”);

            Var $tab = $ (' # tab-content ');
            $tab.empty();

            var $projectTemplate = null;
            $ (" # tab-content ").load("./视图/ search-project-view., function(data) {
                $projectTemplate = $('.project').remove();
                //在这里加载项目
            }); 
        }
    }
    controller.initialize();
    返回控制器;
}

到目前为止,控制器有两个方法, 一个用于呈现搜索视图, 另一个用于呈现Post Project视图. 让我们在 index.js 首先在顶部声明它,然后在onDeviceReady方法中构造它:

// top of index.js
Var控制器= null
//在onDeviceReady方法内部
controller = new controller ();

最后,添加一个脚本引用 index.html 上面提到的 index.js. 你可以直接从GitHub下载Search和Post视图. 因为部分视图是从文件中读取的, 一些浏览器,比如Chrome, 在尝试渲染页面时, 会抱怨跨域请求吗.

这里可能的解决方案是运行本地静态服务器,例如使用 node-static npm module. 此外,在这里你可以开始考虑使用一些框架,如PhoneGap和/或Ionic. 它们都提供了一系列的开发工具, 包括在浏览器中模拟, hot reloading, 和代码生成(脚手架).

现在,让我们通过运行以下命令简单地部署到Android设备:

Cordova运行android

此时,您的应用程序应该有两个选项卡. 第一个选项卡允许搜索项目:

Apache Cordova应用程序

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

Apache Cordova项目发布

我们现在拥有的只是一个在web视图中运行的经典web应用程序. 我们还没有用到任何原生特性,让我们试着做一下. 一个常见的问题是如何在设备上本地存储数据, 或者更准确地说, 使用什么类型的存储. 有几种方法:

  • LocalStorage
  • WebSQL
  • IndexedDB
  • 通过web服务访问的服务器端存储
  • 提供其他选项的第三方插件

LocalStorage适用于存储少量数据, 但是,如果您正在构建数据密集型应用程序,那么这还不够, 可用空间从3到10 MB不等. IndexedDB可能是这种情况下更好的解决方案. WebSQL已被弃用,并且在某些平台上不受支持. Finally, 使用web服务来获取和修改数据非常适合SPA范例, 但是当您的应用程序脱机时,它就会崩溃. PWA技术和Service Workers最近进入Cordova世界来帮助解决这个问题.

Also, 还有很多其他的, 第三方插件来填补Cordova核心的空白. File插件可能非常有用,因为它为您提供了访问设备文件系统的权限, 允许您创建和存储文件. 现在,让我们试试SQLitePlugin,它为你提供了一个本地SQLite数据库. 您可以运行以下命令将其添加到项目中:

Cordova插件添加http://github.com/brodysoft/Cordova-SQLitePlugin

SQLitePlugin为设备的SQLite数据库提供了一个API,并作为一个真正的持久化机制. 我们可以通过以下方式创建一个简单的存储服务:

SQLiteStorageService = function () {
    Var服务= {};
    var db = window.sqlitePlugin ?
        window.sqlitePlugin.openDatabase ({name: "演示.Toptal ", location: "default"}):
        window.openDatabase(“演示.toptal", "1.0", "DB para FactAV", 5000000);

    service.Initialize = function() {
        //初始化数据库 
        var deferred = $.Deferred();
        db.事务(函数(tx) {
            tx.executeSql(
                '创建表,如果不存在项目' + 
                '(id整数主键,名称文本,公司文本,描述文本,纬度真实,经度真实)'
            ,[], function(tx, res) {
                tx.executeSql('DELETE FROM projects', [], function(tx, res) {
                    deferred.解决(服务);
                }, function(tx, res) {
                    deferred.reject('初始化数据库错误');
                });
            }, function(tx, res) {
                deferred.reject('初始化数据库错误');
            });
        });
        return deferred.promise();
    }

    service.getProjects = function() {
        //获取项目
    }

    service.addProject = function(name, company, description, addLocation) {
        //添加一个新项目
    }

    return service.initialize();
}

您可以从GitHub下载获取和添加项目的代码,并将其粘贴到相应的占位符中. 不要忘记添加SQLiteStorageService.Js到你的索引.上面的html文件.通过修改控制器的init函数在控制器中初始化它:

初始化:函数(){
    self = this;
    新的SQLiteStorageService ().(功能(服务){
        self.storageService = service;
        self.bindEvents();
        self.renderSearchView ();
    }).失败(函数(错误){
        alert(error);
    });
}

如果你看一眼服务.addProject(),您会注意到它会调用导航器.geolocation.getCurrentPosition()方法. Cordova有一个地理定位插件,你可以用它来获取手机的当前位置, 你甚至可以使用导航器.geolocation.watchPosition()方法来接收用户位置变化时的更新.

最后,让我们添加控制器事件句柄,用于从数据库中添加和获取项目:

renderPostView:函数(){
    $('.tab-button').removeClass(“活跃的”);
    $ (' # post-tab-button ').addClass(“活跃的”);

    Var $tab = $ (' # tab-content ');
    $tab.empty();
    $ (" # tab-content ").load("./视图/ post-project-view., function(data) {
        $ (' # tab-content ').找到(“# post-project-form”).(“提交”,自我.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 ();
        }).失败(函数(错误){
            alert(error);
        });
    }
},


renderSearchView:函数(){
    $('.tab-button').removeClass(“活跃的”);
    $ (' # search-tab-button ').addClass(“活跃的”);

    Var $tab = $ (' # tab-content ');
    $tab.empty();

    var $projectTemplate = null;
    $ (" # tab-content ").load("./视图/ search-project-view., 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 =
                        'Click to open map';

                    $div.find('.project-location').html(url);
                } else {
                    $div.find('.project-location').text("Not specified");
                }

                $tab.append($div);
            }
        }).失败(函数(错误){
            alert(error);
        });
    });
}

要添加控制台和对话框插件,执行以下命令:

添加org插件.apache.cordova.dialogs
添加org插件.apache.cordova.console

The cordova.控制台插件将通过启用 console.log() 模拟器中的功能.

您可以通过Chrome远程调试器轻松调试Android应用程序. 一旦你连接了你的设备, 点击右上角(X按钮下方)的下拉菜单, 展开更多工具, ,单击“检查设备”. 您应该在列表中看到您的设备,并且应该能够打开它的调试控制台.

Safari提供了相同的功能来调试运行在usb连接设备或模拟器上的iOS应用程序. Just enable Developer Tools under the Safari Settings > Advanced tab.

The cordova.dialog插件启用本地通知. 一个常见的做法是重新定义 windows.alert 方法.对话框API:

overrideBrowserAlert: function() {
    if (navigator.{//用本地对话框覆盖默认的HTML警报
        window.Alert = function (message) {
            navigator.notification.alert(
                Message, //消息
                Null, //回调
                “Toptal”,//标题
                'OK' // buttonName
            );
        };
    }
}

The overrideBrowserAlert 函数中调用 deviceready event handler.

现在,您应该能够添加新项目并从数据库中查看现有项目. 如果你选择了“包含位置”复选框, 设备将调用Geolocation API,并将您的当前位置添加到项目中.

让我们通过设置图标和启动屏幕为应用程序添加最后一笔. 将以下内容添加到您的 config.xml file:


    
    
    
    

最后,在 www/img folder.

Cordova手机教程应用

你自己的Cordova应用

我们经历了Apache Cordova应用程序开发的基本步骤,并使用了我们自己的JavaScript架构和 CSS stylesheet. 这个Cordova教程试图展示Apache Cordova作为使用熟悉的技术开发移动应用程序的一种手段的潜力, 减少了为不同平台构建多个应用程序所需的开发时间和工作量.

However, 在构建将投入生产的应用程序时, 建议您使用现有的框架. 除了在预定义的体系结构中构建应用程序之外, 这还可能为您提供一组组件,这些组件将帮助您的应用程序更接近本机外观. 一些值得注意的框架是 Ionic, Framework7, Weex, Ratchet, Kendo UI, and Onsen UI. Best of luck!

了解基本知识

  • What is Cordova?

    Apache Cordova是一个使用标准web技术创建跨平台移动应用程序的框架. Essentially, 它是一个应用程序容器,它的web视图覆盖了设备的整个屏幕.

  • PhoneGap是什么?

    如今,PhoneGap指的是Adobe在Apache Cordova之上构建的一款产品. Originally, 它是由Nitobi开发的框架,后来被Adobe收购,并将其开源为Apache Cordova.

  • What is WebView?

    Android的WebView和iOS的UIWebView是各自操作系统用来全屏显示网页的类. 开发人员可以使用它们构建web浏览器, or, 以Apache Cordova为例, 使用它们来显示web应用程序,就好像它是一个本地应用程序.

  • 什么是Cordova插件?

    Apache Cordova插件允许进一步访问跨平台特性. 这些服务可以是基于硬件的服务,比如地理定位, 或者纯粹基于软件的功能,比如操作系统提供的SQLite数据库访问.

就这一主题咨询作者或专家.
Schedule a call
菲利普·佩特科夫斯基的头像
Filip Petkovski

Located in 马其顿斯科普里,

Member since March 21, 2014

About the author

拥有MCS学位,并通过谷歌代码之夏(2012)有了一个坚实的开端。, 菲利普有做桌面的经验, mobile, 以及全栈web开发.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

Previously At

Shopify

世界级的文章,每周发一次.

订阅意味着同意我们的 privacy policy

世界级的文章,每周发一次.

订阅意味着同意我们的 privacy policy

Toptal开发者

Join the Toptal® community.

\n \n \n \n \n \n \n\n\n\n

注意,我已经添加了Bootstrap和 jQuery 移动作为依赖项. 请注意,为构建现代混合应用程序,已经开发了更好的解决方案和框架, 但是由于大多数(如果不是全部)web开发人员都熟悉这两个库, 在初学者教程中使用它们是有意义的. 您可以从GitHub下载样式表或使用自己的样式表,如果您喜欢的话.

\n\n

让我们转到 index.js 文件,并将其剥离为以下内容:

\n\n
var app = {\n    //应用程序构造函数\n    初始化:函数(){\n        if (navigator.userAgent.匹配(/ (iPhone iPad iPod | | |安卓|黑莓)/)){\n            document.addEventListener(\"deviceready\", this.onDeviceReady、假);\n        } else {\n            this.onDeviceReady ();\n        }\n    },\n\n    onDeviceReady:函数(){\n        //我们将在这里init / bootstrap我们的应用程序\n    },\n};\napp.initialize();\n
\n\n

请记住,Cordova应用程序提倡的架构是建立一个单页面应用程序(SPA)。. This way, 所有的资源只在应用程序启动时加载一次, 并且只要应用程序正在运行,就可以一直留在web视图中. In addition, with SPAs, 用户将不会有页面重新加载,这不是典型的本地应用程序. 记住这一点,让我们设置一个简单的控制器来在两个选项卡之间切换:

\n\n
var Controller = function() {\n    Var控制器= {\n        self: null,\n        初始化:函数(){\n            self = this;\n            this.bindEvents();\n            self.renderSearchView (); \n        },\n\n        bindEvents:函数(){\n            $('.tab-button').on('click', this.onTabClick);\n        },\n\n        onTabClick:函数(e) {\n            e.preventDefault ();\n            if ($(this).hasClass(“活跃的”)){\n                return;\n            }\n            \n            Var TAB = $(this).data('tab');\n            If (tab === '#add-tab') {\n                self.renderPostView ();\n            } else {\n                self.renderSearchView ();\n            }\n        },\n\n        renderPostView:函数(){\n            $('.tab-button').removeClass(“活跃的”);\n            $ (' # post-tab-button ').addClass(“活跃的”);\n\n            Var $tab = $ (' # tab-content ');\n            $tab.empty();\n            $(\"#tab-content\").load(\"./视图/ post-project-view.html\", function(data) {\n                $ (' # tab-content ').找到(“# post-project-form”).(“提交”,自我.postProject);\n            }); \n        },\n       \n        renderSearchView:函数(){\n            $('.tab-button').removeClass(“活跃的”);\n            $ (' # search-tab-button ').addClass(“活跃的”);\n\n            Var $tab = $ (' # tab-content ');\n            $tab.empty();\n\n            var $projectTemplate = null;\n            $(\"#tab-content\").load(\"./视图/ search-project-view.html\", function(data) {\n                $projectTemplate = $('.project').remove();\n                //在这里加载项目\n            }); \n        }\n    }\n    controller.initialize();\n    返回控制器;\n}\n
\n\n

到目前为止,控制器有两个方法, 一个用于呈现搜索视图, 另一个用于呈现Post Project视图. 让我们在 index.js 首先在顶部声明它,然后在onDeviceReady方法中构造它:

\n\n
// top of index.js\nVar控制器= null\n
\n\n
//在onDeviceReady方法内部\ncontroller = new controller ();\n
\n\n

最后,添加一个脚本引用 index.html 上面提到的 index.js.\n你可以直接从GitHub下载Search和Post视图. 因为部分视图是从文件中读取的, 一些浏览器,比如Chrome, 在尝试渲染页面时, 会抱怨跨域请求吗.

\n\n

这里可能的解决方案是运行本地静态服务器,例如使用 node-static npm module. 此外,在这里你可以开始考虑使用一些框架,如PhoneGap和/或Ionic. 它们都提供了一系列的开发工具, 包括在浏览器中模拟, hot reloading, 和代码生成(脚手架).

\n\n

现在,让我们通过运行以下命令简单地部署到Android设备:

\n\n
Cordova运行android\n
\n\n

此时,您的应用程序应该有两个选项卡. 第一个选项卡允许搜索项目:

\n\n

\"Apache

\n\n

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

\n\n

\"Apache

\n\n

我们现在拥有的只是一个在web视图中运行的经典web应用程序. 我们还没有用到任何原生特性,让我们试着做一下. 一个常见的问题是如何在设备上本地存储数据, 或者更准确地说, 使用什么类型的存储. 有几种方法:

\n\n\n\n

LocalStorage适用于存储少量数据, 但是,如果您正在构建数据密集型应用程序,那么这还不够, 可用空间从3到10 MB不等. IndexedDB可能是这种情况下更好的解决方案. WebSQL已被弃用,并且在某些平台上不受支持. Finally, 使用web服务来获取和修改数据非常适合SPA范例, 但是当您的应用程序脱机时,它就会崩溃. PWA技术和Service Workers最近进入Cordova世界来帮助解决这个问题.

\n\n

Also, 还有很多其他的, 第三方插件来填补Cordova核心的空白. File插件可能非常有用,因为它为您提供了访问设备文件系统的权限, 允许您创建和存储文件. 现在,让我们试试SQLitePlugin,它为你提供了一个本地SQLite数据库. 您可以运行以下命令将其添加到项目中:

\n\n
Cordova插件添加http://github.com/brodysoft/Cordova-SQLitePlugin\n
\n\n

SQLitePlugin为设备的SQLite数据库提供了一个API,并作为一个真正的持久化机制. 我们可以通过以下方式创建一个简单的存储服务:

\n\n
SQLiteStorageService = function () {\n    Var服务= {};\n    var db = window.sqlitePlugin ?\n        window.sqlitePlugin.openDatabase({name: \"demo.toptal\", location: \"default\"}) :\n        window.openDatabase(\"demo.toptal\", \"1.0\", \"DB para FactAV\", 5000000);\n\n    service.Initialize = function() {\n        //初始化数据库 \n        var deferred = $.Deferred();\n        db.事务(函数(tx) {\n            tx.executeSql(\n                '创建表,如果不存在项目' + \n                '(id整数主键,名称文本,公司文本,描述文本,纬度真实,经度真实)'\n            ,[], function(tx, res) {\n                tx.executeSql('DELETE FROM projects', [], function(tx, res) {\n                    deferred.解决(服务);\n                }, function(tx, res) {\n                    deferred.reject('初始化数据库错误');\n                });\n            }, function(tx, res) {\n                deferred.reject('初始化数据库错误');\n            });\n        });\n        return deferred.promise();\n    }\n\n    service.getProjects = function() {\n        //获取项目\n    }\n\n    service.addProject = function(name, company, description, addLocation) {\n        //添加一个新项目\n    }\n\n    return service.initialize();\n}\n
\n\n

您可以从GitHub下载获取和添加项目的代码,并将其粘贴到相应的占位符中. 不要忘记添加SQLiteStorageService.Js到你的索引.上面的html文件.通过修改控制器的init函数在控制器中初始化它:

\n\n
初始化:函数(){\n    self = this;\n    新的SQLiteStorageService ().(功能(服务){\n        self.storageService = service;\n        self.bindEvents();\n        self.renderSearchView ();\n    }).失败(函数(错误){\n        alert(error);\n    });\n}\n
\n\n

如果你看一眼服务.addProject(),您会注意到它会调用导航器.geolocation.getCurrentPosition()方法. Cordova有一个地理定位插件,你可以用它来获取手机的当前位置, 你甚至可以使用导航器.geolocation.watchPosition()方法来接收用户位置变化时的更新.

\n\n

最后,让我们添加控制器事件句柄,用于从数据库中添加和获取项目:

\n\n
renderPostView:函数(){\n    $('.tab-button').removeClass(“活跃的”);\n    $ (' # post-tab-button ').addClass(“活跃的”);\n\n    Var $tab = $ (' # tab-content ');\n    $tab.empty();\n    $(\"#tab-content\").load(\"./视图/ post-project-view.html\", function(data) {\n        $ (' # tab-content ').找到(“# post-project-form”).(“提交”,自我.postProject);\n    });\n},\n\n\npostProject: function(e) {\n\n    e.preventDefault ();\n    var name = $('#project-name').val();\n    var description = $('#project-description').val();\n    var company = $('#company').val();\n    var addLocation = $('#include-location').is(':checked');\n\n    if (!name || !description || !company) {\n        alert('Please fill in all fields');\n        return;\n    } else {\n        var result = self.storageService.addProject(\n            name, company, description, addLocation);\n\n        result.done(function() {\n            alert('Project successfully added');\n            self.renderSearchView ();\n        }).失败(函数(错误){\n            alert(error);\n        });\n    }\n},\n\n\nrenderSearchView:函数(){\n    $('.tab-button').removeClass(“活跃的”);\n    $ (' # search-tab-button ').addClass(“活跃的”);\n\n    Var $tab = $ (' # tab-content ');\n    $tab.empty();\n\n    var $projectTemplate = null;\n    $(\"#tab-content\").load(\"./视图/ search-project-view.html\", function(data) {\n        $('#addressSearch').on('click', function() {\n            alert('Not implemented');\n        });\n\n        $projectTemplate = $('.project').remove();\n\n        var projects = self.storageService.getProjects().done(function(projects) {\n\n            for(var idx in projects) {\n                var $div = $projectTemplate.clone();\n                var project = projects[idx];\n\n                $div.find('.project-name').text(project.name);\n                $div.find('.project-company').text(project.company);\n                $div.find('.project-description').text(project.description);\n\n                if (project.location) {\n                    var url =\n                        'Click to open map';\n\n                    $div.find('.project-location').html(url);\n                } else {\n                    $div.find('.project-location').text(\"Not specified\");\n                }\n\n                $tab.append($div);\n            }\n        }).失败(函数(错误){\n            alert(error);\n        });\n    });\n}\n
\n\n

要添加控制台和对话框插件,执行以下命令:

\n\n
添加org插件.apache.cordova.dialogs\n添加org插件.apache.cordova.console\n
\n\n

The cordova.控制台插件将通过启用 console.log() 模拟器中的功能.

\n\n

您可以通过Chrome远程调试器轻松调试Android应用程序. 一旦你连接了你的设备, 点击右上角(X按钮下方)的下拉菜单, 展开更多工具, ,单击“检查设备”. 您应该在列表中看到您的设备,并且应该能够打开它的调试控制台.

\n\n

Safari提供了相同的功能来调试运行在usb连接设备或模拟器上的iOS应用程序. Just enable Developer Tools under the Safari Settings > Advanced tab.

\n\n

The cordova.dialog插件启用本地通知. 一个常见的做法是重新定义 windows.alert 方法.对话框API:

\n\n
overrideBrowserAlert: function() {\n    if (navigator.{//用本地对话框覆盖默认的HTML警报\n        window.Alert = function (message) {\n            navigator.notification.alert(\n                Message, //消息\n                Null, //回调\n                \"Toptal\", // title\n                'OK' // buttonName\n            );\n        };\n    }\n}\n
\n\n

The overrideBrowserAlert 函数中调用 deviceready event handler.

\n\n

现在,您应该能够添加新项目并从数据库中查看现有项目. 如果你选择了“包含位置”复选框, 设备将调用Geolocation API,并将您的当前位置添加到项目中.

\n\n

让我们通过设置图标和启动屏幕为应用程序添加最后一笔. 将以下内容添加到您的 config.xml file:

\n\n
\n    \n    \n    \n    \n\n
\n\n

最后,在 www/img folder.

\n\n

\"Cordova手机教程应用\"

\n\n

你自己的Cordova应用

\n\n

我们经历了Apache Cordova应用程序开发的基本步骤,并使用了我们自己的JavaScript架构和 CSS stylesheet. 这个Cordova教程试图展示Apache Cordova作为使用熟悉的技术开发移动应用程序的一种手段的潜力, 减少了为不同平台构建多个应用程序所需的开发时间和工作量.

\n\n

However, 在构建将投入生产的应用程序时, 建议您使用现有的框架. 除了在预定义的体系结构中构建应用程序之外, 这还可能为您提供一组组件,这些组件将帮助您的应用程序更接近本机外观. 一些值得注意的框架是 Ionic, Framework7, Weex, Ratchet, Kendo UI, and Onsen UI. Best of luck!

\n","as":"div","isContentFit":true,"sharingWidget":{"url":"http://gi2c.softlawinternationale.net/mobile/developing-mobile-applications-with-apache-cordova","title":"Apache Cordova Tutorial: Developing Mobile Apps with Cordova","text":null,"providers":["linkedin","twitter","facebook"],"gaCategory":null,"domain":{"name":"developers","title":"Engineering","vertical":{"name":"developers","title":"Developers","publicUrl":"http://gi2c.softlawinternationale.net/developers"},"publicUrl":"http://gi2c.softlawinternationale.net/developers/blog"},"hashtags":"Mobile,Development,Hybrid,ApacheCordova,移动应用"}}