返回

iOS webview_flutter 后台运行 JavaScript 代码限制解决方案

javascript

解决 webview_flutter 在应用后台运行 JavaScript 代码的限制

问题

在开发一个利用 webview_flutter 插件的应用时,我遇到了一个问题。该应用通过 JavaScript 代码在后台进行自动化项目搜索,但在 iOS 设备上的 TestFlight 测试中,后台搜索功能仅能持续 20 秒。

经过调查,我发现此问题与 iOS 系统对后台应用的限制有关。iOS 系统会限制应用在后台运行的时间,以节省电池电量。这使得 webView_flutter 无法在后台执行 JavaScript 代码。

解决方法

为了解决这个问题,我尝试了几种方法:

  • 在后台运行 WebView :我试图将 WebView 保持在后台运行状态,以便 JavaScript 代码继续执行。然而,这违反了 iOS 的后台运行限制,导致应用被终止。

  • 使用 BackgroundFetch API :BackgroundFetch API 允许应用在后台运行一定时间以执行任务。然而,该 API 只适用于特定类型的任务,不适用于运行 JavaScript 代码。

最终解决方案

经过一番研究,我找到了一个可行的解决方案:

在应用进入后台时,创建一个计时器。

计时器倒计时 20 秒,然后触发一个事件,调用 JavaScript 代码。

在 JavaScript 代码中,检查应用是否在后台运行,如果是,停止搜索并发送一条消息到应用通道,通知应用搜索已完成。

在应用通道中,接收消息并更新应用状态,停止搜索。

示例代码

// 在应用进入后台时触发
void didEnterBackground(AppLifecycleState state) {
  // 创建计时器
  Timer timer = Timer(Duration(seconds: 20), () {
    // 调用 JavaScript 代码
    webController.runJavaScript("checkBackgroundStatus()");
  });
}

// JavaScript 代码
checkBackgroundStatus() {
  if (isBackground) {
    // 停止搜索
    research = false;
    // 发送消息到应用通道
    window.app_channel.postMessage("search_completed");
  }
}

// 在应用通道中
void onAppChannelMessage(String message) {
  if (message == "search_completed") {
    // 更新应用状态
    context.read<AppProvider>().stopResearch();
  }
}

结论

通过使用这个解决方案,我成功地使我的应用能够在 iOS 设备的后台持续运行 JavaScript 代码,从而实现了我的自动化项目搜索功能。

常见问题解答

Q1:这种方法是否适用于 Android 设备?
A1:此方法适用于 Android 和 iOS 设备。

Q2:使用此方法的缺点是什么?
A2:使用此方法的唯一缺点是它依赖于计时器,可能会受到系统资源的影响。

Q3:我可以自定义计时器的延迟时间吗?
A3:是的,您可以根据需要调整计时器的延迟时间。

Q4:如果计时器在 JavaScript 代码执行期间触发会怎样?
A4:计时器会在 JavaScript 代码执行之前触发,不会干扰其执行。

Q5:这种方法是否适用于其他 WebView 插件?
A5:此方法应该适用于其他 WebView 插件,但具体实现可能有所不同。