应用前后台切换后出现通信不可达、网络异常
====================

#### 问题现象

用户在应用内使用网络进行通信时（或者数据传输和文件上传下载），若将应用切换至后台（例如锁屏或进行其他任务），一段时间后切回前台，可能会遇到网络连接中断、无法发送消息或文件下载失败等问题。

#### 背景知识

*   在HarmonyOS中，应用切换到后台2秒后，应用的网络资源会被冻结，并且在12秒后进行释放。此时，再继续使用网络资源，就会出现网络不可用的情况。
*   [Background Tasks Kit（后台任务开发服务）](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/background-task-kit)：为减少耗电并确保前台体验流畅，当应用退至后台时，系统会对其实施包括进程挂起与终止在内的管控措施。
    1.  [短时任务(ArkTS)](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/transient-task)：应用退至后台一小段时间后，应用进程会被挂起，无法执行对应的任务。如果应用在后台仍需要执行耗时不长的任务，如状态保存等，可以通过本文申请短时任务，扩展应用在后台的运行时间。
    2.  [长时任务(ArkTS)](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/continuous-task)：应用退至后台后，在后台需要长时间运行用户可感知的任务，如播放音乐、导航等。为防止应用进程被挂起，导致对应功能异常，可以申请长时任务，使应用在后台长时间运行。
*   由于[Socket](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/socket-connection)通信是基于IP和端口进行通信的，在应用退到后台后，网络资源被冻结时会Abort Socket，但是不会释放连接对象。在应用切换到前台后，继续使用之前的连接对象，由于底层已释放资源导致通信失败。

#### 问题定位

1.  以申请长时任务为例，查看[module.json5配置文件](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/module-configuration-file)中是否有[ohos.permission.KEEP\_BACKGROUND\_RUNNING](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/permissions-for-all#ohospermissionkeep_background_running)的权限声明，并搜索[startBackgroundRunning](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-resourceschedule-backgroundtaskmanager#backgroundtaskmanagerstartbackgroundrunning)和[stopBackgroundRunning](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-resourceschedule-backgroundtaskmanager#backgroundtaskmanagerstopbackgroundrunning)，检查申请和取消长时任务的逻辑是否完善。
2.  监听on('error')事件，判断连接链路是否异常。在连接异常情况下，发送消息报错2301107 Socket not connected。

#### 分析结论

由于应用在使用[TCPSocket](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-socket#tcpsocket)、[UDPSocket](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-socket#udpsocket)等通信时（或者使用相应网络服务进行数据传输或文件上传下载），当应用切换退到后台后，未申请短时任务或长时任务会导致网络资源被冻结和释放。同时，将应用切后台和切回前台，未正确管理对应的通信状态，继续使用之前的TCPSocket、UDPSocket等连接对象和服务器通信，导致出现网络异常。

#### 修改建议

*   如果应用有后台使用网络资源的场景，可以在使用该场景时申请短时任务或长时任务，确保网络资源不被冻结和释放。
*   参考[应用前后台切换后重连](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-network-reconnection#section6593152718515)实现在切回前台后重连。注意重连前需要调用close接口主动断开连接，否则connect连接会报错2301103 Connection aborted：
    1.  结合UIAbility组件生命周期的onForeground和onBackground，在前后台切换时，将应用前后台的状态存储在AppStorage中。
    2.  使用[@StorageProp](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-appstorage#storageprop)将AppStorage存储的前后台状态与对应的属性建立单向数据同步。并使用[@Watch](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-watch)监听状态变量的变化，当前后台状态变化后，关闭或重新连接。

#### 常见FAQ

Q：UDPsocket在手机熄屏或应用切到后台后一段时间，重新切回前台时无法收到消息的原因分析？

A：应用退后台后UDPsocket被abort了，回到前台接收线程会退出并且触发error回调。因此需要监听事件管理，在监听到error事件后重新bind，避免无法收到消息。