【问题标题】:Cordova - Logic behind onDeviceReady Event ListenerCordova - onDeviceReady 事件侦听器背后的逻辑
【发布时间】:2017-01-25 15:21:03
【问题描述】:

我正在关注本教程:https://software.intel.com/en-us/xdk/articles/cordova-core-plugin-camera-short-code-example

它在运行 iOS 10 和 Cordova 6.5.0 的 iPhone 5s 上运行良好

但是,我不明白设备准备就绪时调用的函数中何时以及必须放置什么背后的逻辑。

如您所见,onDeviceReady 在设备准备就绪时被调用:

document.addEventListener("deviceready",onDeviceReady,false);

// device APIs are available
//
function onDeviceReady() {
    pictureSource=navigator.camera.PictureSourceType;
    destinationType=navigator.camera.DestinationType;
}

但其他 API 调用(例如拍摄实际照片)不需要该步骤(一个可以在调用它的按钮可见时立即调用的函数):

// A button will call this function
//
function capturePhoto() {
  // Take picture using device camera and retrieve image as base64-encoded string
  navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50,
    destinationType: destinationType.DATA_URL });
}

将 onDeviceReady 函数的内容放在 capturePhoto 函数中并在页面加载完成后等待几秒钟会破坏整个过程 - 为什么?

另外,为什么navigator.camera.DestinationType和官方教程要你使用Camera.DestinationType不一样?

到目前为止我从回复中学到了什么

如有错误请指正

当 DOM 加载后立即调用 javascript cordova 函数时,可能会发生本机 cordova 代码尚未准备好的情况。但是通过将该代码放在 onDocumentReady 函数中,您可以绕过它。

【问题讨论】:

    标签: javascript cordova


    【解决方案1】:

    在加载/初始化 Cordova API 后触发 deviceready 事件。如果您正在使用 Cordova API 中的函数,那么确保它已加载并因此可以使用的最佳方法是仅在库加载后启动您的应用程序逻辑。 IE。使用 deviceready 来“初始化”你的应用程序。

    这类似于在文档加载之前尝试访问HTMLElement(例如,绑定事件处理程序)。

    例如

    class App
    {
        constructor() {
            console.log("Loaded!");
    
            this.bindEvents = this.bindEvents.bind(this);
            this.click = this.click.bind(this);
        }
    
        bindEvents() {
            document.getElementById('button').addEventListener('click', this.click);
        }
    
        click() {
            navigator.camera.getPicture(...);
        }
    }
    
    document.addEventListener('deviceready', () => {
        // Do all bindings here / start using API.
        let app = new App();
        app.bindEvents();
    }, false);
    

    您的“按钮”起作用并启动相机的原因是,您的应用启动后,您恰好在单击按钮之前等待了足够长的时间。应用启动后,您可以尝试尽快单击“按钮”。您可能会在设备准备好之前点击它(取决于需要多长时间)。

    关于您的特定代码,您所做的只是为 Camera API 创建一个“别名”。

    【讨论】:

    • 但是,当 onDeviceReady 函数内部的代码位于“按钮函数”内部并且我等待相同的时间时,为什么它不起作用?到时候设备应该准备好了?
    • 你没有使用pictureSource,至少在你提供的代码中,这样不会有什么不同。尝试使用navigator.camera.DestinationType.DATA_URL 而不是destinationType。我的猜测是问题不在您提供的代码中,假设您确保在 deviceready 触发后调用capturePhoto
    • 无论我以前做过什么,它现在都可以正常工作(使用destinationType) - 但是既然你提到了它,navigator.camera.destinationType(英特尔教程)和Camera.DestinationType(Apache 教程)有什么区别跨度>
    • 顺便说一句,它是DestinationType - 区分大小写。 “常量”在 Camera 对象中正式定义。所有相机常量都“导出”到navigator.camera,以便您可以访问它们。 IE。它被公开了。看看源码here
    【解决方案2】:

    onDeviceReady 事件在cordova 完全初始化后触发一次。使用插件时,您需要做的就是确保在捕获 onDeviceReady() 事件之后调用插件接口。无需每次需要使用插件时都等待。还有其他值得一提的事件,在这里您可以阅读有关 cordova 应用程序生命周期的内容:https://cordova.apache.org/docs/en/latest/cordova/events/events.html

    尝试捕获不同的事件并打印出一些控制台日志以查看何时触发了不同的事件(顺便说一句,这是一种很好的学习技巧)。

    使用插件调用时,需要使用挂接插件函数的命名空间。有时这些函数可以从不同的对象访问,这就是为什么教程中有一些无关紧要的原因。为确保您将调用您想要的,您可以随时查看插件文档或插件 www 目录,您可以在其中找到 javascript 接口文件。

    【讨论】:

    • 但是英特尔页面上的教程和“官方”cordova 教程使用的是同一个插件——为什么会有差异?
    • 做一个快速测试:记录Camera对象和navigator.camera,看看你有什么。如果对象具有相同的接口,则根本没有区别。差异有时来自插件的版本,有时有几种方法可以进入插件界面,仅此而已。其实没什么好担心的,
    • 这实际上是一个完全不同的话题:/当我使用 iOS 模拟器或实际设备时,我还不知道 console.log() 日志存储在哪里......我是不使用 XCode 进行测试 - 我应该吗?
    • 您可以,但还有其他方法可以调试您的应用程序。如果您在 Windows 上工作,您可以使用 chrome://inspect 来调试您的应用程序。您在 Safari Development -> <your device> -> index.html. 中具有类似(但不是那么复杂)的功能,您可以看到控制台日志和来自在模拟器/真实设备上运行的应用程序的错误。当您在某些 IDE 中工作时也会有日志,例如 NetBeans(带有 cordova 插件)或 XCode。
    • 我刚刚尝试用Camera 替换navigator.camera,它工作正常。如果可以的话,我会赞成你的回复。 - 但我的设备没有显示在 Safari 中 - 它通过 USB 连接并运行我使用 cordova run ios --device 创建的应用程序
    猜你喜欢
    • 2016-11-08
    • 1970-01-01
    • 2019-01-15
    • 2018-09-04
    • 2016-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    相关资源
    最近更新 更多