Nativescript:应用进入后台时如何继续代码执行

3

(编辑以提供更新的信息)

我有一个使用Nativescript编写的应用程序,执行各种任务,如果手机进入后台模式或被锁定,我希望应用程序能够继续运行。

主要针对iOS平台,使用Nativescript Angular开发。我还不熟悉在Nativescript中使用obj C代码。

举个简单的例子,假设我想在用户点击按钮后每5秒钟将内容打印到控制台上,那么我就在组件的ts文件中编写了以下代码:

coolComponent.ts:

@Component({...})

Export class coolComponent {
...
whenButtonClicked(){
   setInterval(function(){ 
    console.log('button has been clicked. show every 5 seconds!'); 
  }, 5000);
}

没有更多的代码,当用户点击按钮时,它将每5秒打印到控制台,但当应用程序在后台或手机被锁定时停止。如何使函数即使在应用程序在后台或锁定时也继续执行?

通过查看不同的来源,比如 这里(NS文档关于后台执行)这里(应用代理文档) ,似乎第一步是创建一个自定义应用代理,让它工作,然后在info.plist中标识后台任务。

我已经大致实现了功能,像这样:

app/custom-app-delegate.ts:

import { ios, run as applicationRun } from "tns-core-modules/application";

export class CustomAppDelegate extends UIResponder implements 
    UIApplicationDelegate {

     public static ObjCProtocols = [UIApplicationDelegate];

     public applicationDidEnterBackground(application: UIApplication) {
      console.log('in background mode!')
     }
}

main.ts:

import { platformNativeScriptDynamic } from "nativescript-angular/platform";   

import { AppModule } from "./app.module";

import * as application from "tns-core-modules/application";

import { CustomAppDelegate } from "./custom-app-delegate";

application.ios.delegate = CustomAppDelegate;

platformNativeScriptDynamic().bootstrapModule(AppModule); 

app/app.module.ts:

import { CustomAppDelegate } from "./custom-app-delegate";

app/App_Resources/iOS/info.plist:

 ...
 <key>UIBackgroundModes</key>
  <array>
    <string>fetch</string>
  </array> 

编辑:创建reference.d.ts文件:

/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />
/// <reference path="./node_modules/tns-platform-declarations/android.d.ts" />

编辑:顺便提一下,为了使自定义应用程序委托起作用,我还需要下载“tns-platform-declarations”命令:

$ npm i tns-platform-declarations --save-dev

通过这个方式,当应用程序进入后台时,该应用程序会正确地读取“在后台模式下!”因此,自定义应用程序代理是有效的。

然而,在线上的示例假设自定义应用程序代理中的代码与应用程序的其余部分无关,因此当应用程序进入后台模式时,它们假定有新的任务要完成。

但这在这里并不是这种情况。我有一个正在从coolComponent函数执行的任务,当应用程序进入后台或被锁定时,我想让它继续运行。

这可能需要coolComponent.ts与custom-app-delegate进行通信,但我不知道如何做到这一点。

仅在两个文件中重复代码--在coolComponent.ts和custom-app-delegate中均出现setInterval函数--不起作用,因为这不会导致自定义应用程序代理在用户按下按钮后以相同的时间继续运行。

那么,我怎样才能使代码从coolComponent.ts开始,并在应用程序处于后台模式时继续运行?


你好,我有同样的问题,你找到解决方法了吗?如果找到了,能否告诉我如何处理它。 - Nithin Jadhav
我没有找出如何在应用程序委托中执行后台任务。相反,我尝试寻找其他解决方案(其他人已经找到了)。例如,我使用了NativeScript本地通知插件来安排并显示用户通知,即使应用程序在后台也是如此。 - SeanRtS
2个回答

0

从技术上讲,您无法强制应用程序在用户不再希望其处于活动状态时保持活动状态(通过锁定手机/最小化应用程序)。如果您想在后台运行任何内容,则必须在iOS中使用后台获取


这不是“用户不想让应用程序处于活动状态”的情况。想法是即使用户将其放在口袋中(并锁定以避免意外按键),应用程序也可以运行。 iPhone 的基本应用程序具有此功能:地图、音乐、时钟和播客都是这样工作的。 “获取”可能是在后台运行倒计时器的正确方法? - SeanRtS
有不同类型的后台模式,包括位置、获取数据等。你应该选择适合你需求的模式。但是在高层次上,这就是想法,一旦应用程序被发送到后台,你不能保持正常的应用程序代码运行。 - Manoj
我一直在研究后台执行。我已经将fetch background mode添加到info.plist中,但似乎要使其工作,您首先需要添加一个自定义应用程序委托,并通过安装tns-platform-declarations等方式使其正常工作。我已经完成了这个过程,并成功使自定义应用程序委托功能正常--它可以在应用程序进入后台模式时进行注册。但是... - SeanRtS
我如何在我的main.ts文件中“继续”代码,一旦应用程序进入后台?我看到的示例假定在后台模式下有不同的操作需要执行。在我的情况下(像大多数人一样?),应用程序正在执行任务--例如main.ts文件中的计时器--然后当应用程序进入后台时,我希望这段代码继续执行。这可能涉及到在我的main.ts文件和自定义应用程序委托之间进行通信,但我正在努力弄清楚。是否有关于在main ts文件中发生动作,然后在后台模式下继续执行的示例代码? - SeanRtS
苹果公司有一些开发者需要遵循的规则,所以最好的做法是分享代码。将所有逻辑写在一个单独的文件中,并在应用程序中调用它,在后台执行时也要这样做。 - Manoj
谢谢。我已经更新了我的答案,提供了更多的细节和代码。我认为,仅仅从一个文件中调用代码,然后从另一个文件中调用它是不够的,因为当应用程序进入后台模式时再次调用它会导致它重新开始。也许需要一些过程来告诉应用程序在进入后台时计时器的位置在哪里...但我认为这可能会变得过于复杂。是否有更简单的解决方案? - SeanRtS

0

iOS允许您仅在某些情况下在后台运行代码。例如(但不限于):

  • 后台位置更新。
  • 音频和视频播放(iPad中的PiP)
  • 远程推送通知处理
  • 等等...

如果您的应用程序不符合任何可用类别,则最好的方法是请求iOS在后台运行更长时间(默认为10秒)。这将允许您运行3分钟。只需在无限循环中继续运行任务,并在授予的180秒之前优雅地终止您的应用程序。

关于后台获取,此机制允许应用程序在后台更新其内容。 iOS将执行至少每天声明后台获取的应用程序,因此您可以在委托中从服务器执行更新。该机制不适用于您要查找的内容。


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