音频后台播放应用突然正常退出问题定位

使用音频播放接口播放音频,在create AVsession 和startBackgroundRunning前提下应用切入后运行,10s左右后,应用被杀死,无crash日志。

HarmonyOS
2024-06-13 23:38:21
浏览
收藏 0
回答 2
待解决
回答 2
按赞同
/
按时间
鱼弦CTO
1

在 HarmonyOS 上,应用程序在后台播放音频时突然退出且没有崩溃日志,这通常涉及系统的资源管理策略、权限配置以及后台进程的行为。以下是一些可能导致问题的原因及其解决方法:


原因和解决方法


权限问题:


确保你的应用具有必要的权限来进行后台音频播放。在 config.json 文件中添加相关权限,例如:



"reqPermissions": [
    {
        "name": "ohos.permission.SYSTEM_ALERT_WINDOW"
    },
    {
        "name": "ohos.permission.MEDIA_LOCATION"
    },
    {
        "name": "ohos.permission.INTERNET"
    }
]


AVSession 和 Service 配置不正确:


使用 AVSession 时,请确保正确配置了后台服务,并已注册 AVSession。



// 创建 AVSession
std::shared_ptr<AVSession> avSession = AVSessionManager::GetInstance().CreateSession("MyAudioSession", AV_SESSION_TYPE_MEDIA);

// 启动后台运行
avSession->StartBackgroundRunning();


后台任务限制:


系统可能对后台任务有时间限制,如果任务超过限制,系统会终止该任务。可以通过 WorkScheduler 来确保后台任务的执行。


内存限制和优化:


HarmonyOS 可能会因为内存不足而杀死后台应用,请确保应用优化了内存使用。

电量优化设置:


用户设备的电量优化设置可能会影响后台应用的运行,建议用户将应用添加到电量优化的白名单中。


应用生命周期管理:


检查应用的生命周期管理代码,确保在切换到后台时正确处理了保存状态和资源释放。

调试和诊断步骤

日志分析:


虽然没有崩溃日志,但你仍然可以通过系统日志查看更多信息。使用 DevEco Studio 或其他调试工具捕获 logcat 日志,寻找可能的线索。



hdc_std shell hilog -r # 重置日志
hdc_std shell hilog # 查看实时日志


增加调试输出:


在关键点添加日志输出,以便了解应用在后台运行时的行为。例如,在 AVSession 的创建和销毁处、Service 的启动和停止处添加日志。

使用 Profiler:


使用 HarmonyOS Profiler 工具分析应用的性能,查看是否存在内存泄漏或资源占用过高的问题。

检查系统资源管理器 (ResourceManager):


确认系统资源管理器没有错误地回收了你的应用资源,可以通过增加资源管理器的日志来辅助调试。


样例代码


以下提供一个简化的示例,展示如何正确创建 AVSession 并启动后台运行:



#include <memory>
#include "avsession_manager.h"
#include "avsession.h"
#include "ohos/aafwk/content/want.h"
#include "ohos/application_info.h"

using namespace OHOS::AVSession;

class MyAudioService {
public:
    MyAudioService() {
        session_ = AVSessionManager::GetInstance().CreateSession("MyAudioSession", AV_SESSION_TYPE_MEDIA);
    }

    void StartPlayback() {
        if (session_) {
            session_->SetAVMetaData(/* Metadata */);
            session_->StartBackgroundRunning();
            // 开始音频播放逻辑
        }
    }

    void StopPlayback() {
        if (session_) {
            session_->StopBackgroundRunning();
            // 停止音频播放逻辑
        }
    }

private:
    std::shared_ptr<AVSession> session_;
};

// 示例:启动音频服务并开始播放
int main() {
    MyAudioService audioService;
    audioService.StartPlayback();

    // 模拟后台运行
    std::this_thread::sleep_for(std::chrono::seconds(20));

    audioService.StopPlayback();
    return 0;
}


请根据实际需求调整和完善上述代码,并确保在后台运行时正确处理了所有相关资源和状态。

分享
微博
QQ
微信
回复
6天前
jshyb

使用工具

hdc shell

定位过程

1、后台播放应用闪退,且无crash 等日志,复现问题添加日志进行分析。render callback 正在回调的时候停止,音频还未播放完,应用就exit code 0,无异常退出。

2、前台播放无问题,后台播放应用闪退,怀疑与后台播放有关。后台播放需要有AVSession 和长时任务,分析长时任务代码,并断点调试,未发现问题。

3、长时任务存在限制条件,如果创建了长时任务,但是5s 内未检查到对应的长时任务的发生,系统就会释放长时任务。

场景1:若应用申请了长时任务,但未真正执行申请类型的长时任务或申请类型的任务已结束,系统会对应用进行管控。例如系统检测到应用申请了AUDIO_PLAYBACK(音频播放),但实际未播放音乐,系统则会终止对应的进程

4、Demo 实例代码如下。音频录制后完成后,立即创建了avsession 和 startBackgroundRunning,后面播放是用户行为,可能会发生在音频录制完成后5s,这样系统就释放了长时任务。

5、修改代码,去掉长时任务,播放音频后切后台,12s后,应用会被kill 掉。实际验证与约束结果一致。

6、修改代码,在播放前 create AVsession 和startBackgroundRunning,后台任务播放正常。

7、修改后,依然存在切后台10s内应用被kill 的现象。问题场景是在JS 主线程 创建的长时任务,在子线程调用的render 相关接口。长时任务是应用级别,与多进程无关。

8、使用研发排查手段:使用cmd 进入hdc shell,执行命令ℎ��������������−��1910−��"−−������������������"hidumper−s1910−a"−−detection" 和ℎ��������������−��1903−��"−��−−������"hidumper−s1903−a"−C−−all",59版本不支持该命令。

# hidumper -s 1910 -a "--detection" 
 
-------------------------------[ability]------------------------------- 
 
 
  ----------------------------------SuspendManager--------------------------------- 
  { 
    "audioPlayer": { 
      "AVSessionInfos": [ 
        { 
          "pid": 15236, 
          "sessionId": "E91B9F43129D80910BA4C6861AA4196855DB97191EB295F5D1894EA0B068B6AB", 
          "uid": 20020134         // av的uid与render 的uid一致, 
        } 
      ], 
      "audioRenderInfos": [ 
        { 
          "sessionId": 100291, 
          "streamType": 1, 
          "uid": 20020134 
        } 
      ] 
    }, 
    "audioRecorder": [], 
    "bluetooth": { 
      "ble switch": false, 
      "bredr switch": false, 
      "devicePairRecords": [], 
      "gattAppRegisterInfos": [], 
      "gattConnectRecords": [], 
      "sppConnectRecords": [] 
    }, 
    "commonTask": { 
      "audioPlay": [], 
      "audioRecord": [], 
      "bluetooth": [], 
      "location": [], 
      "multiDevice": [] 
    }, 
    "disSchedule": { 
      "calleeRecords": [], 
      "callerRecords": [] 
    }, 
    "location": { 
      "location switch": true, 
      "locationRecords": [] 
    } 
  } 
# 
# hidumper -s 1903  -a "-C --all" 
 
-------------------------------[ability]------------------------------- 
 
 
  ----------------------------------BackgroundTaskManager--------------------------------- 
  No.1    continuousTaskKey: 20020134_EntryAbility 
continuousTaskValue: 
  bundleName: com.samples.audio 
abilityName: EntryAbility 
isFromWebview: false 
isFromNewApi: true 
backgroundMode: audioPlayback 
uid: 20020134   // 长时任务的UID 
userId: 100 
pid: 15236 
notificationLabel: 
  wantAgentBundleName: com.samples.audio 
wantAgentAbilityName: com.samples.audio.EntryAbility 
 
#

9、升级版本到66后,后台播放正常,hdc 命令显示长时任务运行正常。

根因总结

1、长时任务限制:长时任务启动后会在5s内持续检查是否有音频播放,如果未检测到音频播放,系统会在切后台后10s左右对应用进行管控,将APP kill掉,日志会显示APP exit 02、59版本长时任务可能存在bug,66版本正常且可以用命令查看后台长时任务。

解决方案

在开启长时任务时需要保证音频播放在开始长时任务前或者是音频播放5s内。

分享
微博
QQ
微信
回复
2024-06-14 22:49:13
相关问题
FormExtensionAbility进程自动退出问题
1141浏览 • 0回复 待解决
OH _Audio播放音频问题
633浏览 • 1回复 待解决
AudioCapturer录音+AudioRenderer播放音频
646浏览 • 1回复 待解决
应用性能问题定位和优化指导
1211浏览 • 1回复 待解决
SoundPool实现音频播放功能
618浏览 • 1回复 待解决
音频播放长时任务不生效
598浏览 • 1回复 待解决
鸿蒙 如何使用 player 播放网络音频
6007浏览 • 1回复 已解决
使用AudioRenderer开发音频播放功能
482浏览 • 1回复 待解决
AVplayer开发音频播放功能
482浏览 • 1回复 待解决
AVPlayer实现音频播放(c++侧)
421浏览 • 1回复 待解决
使用AudioRenderer播放pcm音频流失败
616浏览 • 1回复 待解决
怎么使用player播放网络音频呢?
2324浏览 • 1回复 待解决
后台播放声音会直接无声
555浏览 • 1回复 待解决
xampp的mysql出问题怎么处理?
1474浏览 • 1回复 待解决
SoundPool播放音频是否支持WMV格式
787浏览 • 1回复 待解决
鸿蒙-如何实现播放一段音频
9806浏览 • 2回复 待解决
求大佬告知如何后台播放音乐
880浏览 • 1回复 待解决
ets开发应用怎么退出当前应用
2373浏览 • 1回复 待解决
鸿蒙Dev远程真机能否播放音频
4040浏览 • 1回复 待解决