如何在 Cordova Android 应用程序中使用服务工作者?

43

我想在我的 Cordova Android 应用中使用服务工作者,作为一种方便的方式来同步一些图片到服务器和从服务器上同步。我注意到 这个问题 指出这是不可能的,因为服务工作者必须通过 https: 加载,而 Cordova 将通过 file: 加载文件。

另一方面,似乎 ionic 支持服务工作者。这意味着他们已经找到了一些方法使其工作。然而,我没有使用 ionic。似乎有一个 cordova 插件支持 iOS 的服务工作者,但是我正在使用 Android。

如果可能的话,在 Cordova Android 应用程序中使用服务工作者的当前最佳实践是什么?


请告诉我这个链接是否有帮助 - http://forum.quasar-framework.org/topic/259/service-worker-on-cordova-app/2 - Gandhi
@torazaburo 这个有更新了吗? - Gandhi
@Gandhi,我倾向于认为你的回答是正确的。 - user663031
@torazaburo 感谢您的回复。如果答案对您有帮助,请在悬赏过期之前接受相同的答案 :) 干杯 - Gandhi
@torazaburo 你好,关于这个问题有什么进展吗?时间不多了,希望能尽快得到回复。 - Gandhi
显示剩余2条评论
2个回答

57
经过深入研究,我得出结论:Android 不支持 Service Workers,因为它会阻止 HTTP 或文件协议中的 Service Workers。
此外,Ionic 框架中的 Service Worker 支持也没有明确说明在混合移动应用程序中不受支持。这有点误导人,就像在这种情况下一样。 Ionic 的 Service Worker 支持只在渐进式 Web 应用程序中发挥作用,在混合移动应用程序中并不适用,如其官方博客所述。
除上述信息外,使用 Service Workers 可以实现的大多数功能已经作为插件的一部分可用,例如推送通知插件,在大多数情况下应该足够了。
归根结底,Service Workers 在 Cordova Android 中和 Ionic 框架中都不受支持。有关更多信息,请查看以下链接

1
只是为了明确:Service Workers 在 Android 应用程序的 webview 中不可用,因此对于 Android 混合应用程序也不可用,但它们在 Chrome 和 Firefox 的 Android 网页浏览器中可用,适用于 PWA(在 Ionic 中内置的浏览器平台)。 - felipeaf
@Gandhi 谢谢您提供这些信息。现在已经过去一年了,是否有任何更新?作为我的应用程序的一部分运行一个小型 HTTP 服务器怎么样? - user9315861
1
@torazaburo 我猜测服务工作者仍然不被支持。运行HTTP服务器与服务工作者是不同的。但如果你只想运行一个小型HTTP服务器,那么你得看看 - https://github.com/floatinghotpot/cordova-httpd - Gandhi
1
从Cordova-Android版本10开始,Android上的Cordova应用程序将从https://localhost(https://cordova.apache.org/announcements/2021/07/20/cordova-android-10.0.0.html)提供服务,因此似乎现在可以使用服务器选项了! - SuprMan

3

我不能接受“不行”的答复,所以开始寻找编写代码的方法来解决这个问题。

注意,我不确定我遇到的问题是否与原帖相同(如果不是,请见谅,但希望是相同的)...我的情况是这样的,为了清晰起见: 我最初手动获取并添加了项目(https://localhost/cordova.js和插件文件)到服务工作者使用的缓存中。我在第一次运行时这样做,并且第二次运行(即使离线)也可以正常工作...所以取得了一些进展。奇怪的是,在随后的运行中,大多数手动缓存的项目都被删除,因此启动未能成功完成。

然后我研究了一下是否可以完全绕过对localhost的调用,结果发现可以。实际上,在服务工作者的获取处理程序中,我有一个条件子句,如果它发现url中有localhost,则什么也不做。这样就会导致服务工作者找不到处理请求的获取处理程序,然后浏览器就像没有服务工作者一样调用获取资产。

我已经测试了在线/离线启动,确保我可以访问cordova和一些插件,一切似乎都可以正常运行。请注意,到目前为止所有的测试都是在Android上进行的。

我使用的代码示例如下(为了清晰起见,留下了一个明确的“什么也不做”注释);

 self.addEventListener('fetch', event => {
        console.log('Fetch event for ', event.request.url);
        if (event.request.url.includes("localhost")) {
            // Do Nothing
        } else {
        event.respondWith(
          caches.match(event.request, {
           // ... do the rest of the SW handling

我很想知道其他人是否尝试过这个,并且是否遇到了任何问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接