You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中OboeSinePlayer示例代码崩溃问题求助

解决Oboe正弦播放器崩溃问题

我帮你梳理下导致崩溃的几个核心原因,以及对应的解决办法:

1. 最关键的问题:OboeSinePlayer对象生命周期过短

你在JNI方法oboeSinePlayer()里创建了一个局部的OboeSinePlayer实例,方法执行完后这个对象就会被销毁,但音频流还在运行,回调onAudioReady时会引用已经被释放的对象,这必然导致崩溃。

修复方案:

把OboeSinePlayer改成全局静态实例,保证它的生命周期和App一致:

// 在OboeSinePlayer.cpp顶部声明全局实例
static OboeSinePlayer sOboePlayer;

// 修正JNI方法的返回类型(Java层是void,之前写了jstring会导致不匹配)
extern "C" JNIEXPORT void JNICALL Java_com_example_gettingstartedoboe_MainActivity_oboeSinePlayer(JNIEnv *env, jobject /* this */) {
    sOboePlayer.start();
}

2. 解决liboboe.so找不到的问题(UnsatisfiedLinkError)

  • 先确认CMakeLists.txt里的OBOE_DIR路径完全正确,指向你本地Oboe仓库的根目录
  • 添加Oboe动态库编译选项,确保liboboe.so会被打包到APK:
    在CMakeLists.txt里add_subdirectory之前添加:
    set(OBOE_BUILD_SHARED_LIBS ON)
    
  • 检查App的build.gradle,确保指定了正确的ABI架构,和Oboe编译的架构匹配:
    android {
        defaultConfig {
            ndk {
                abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
            }
        }
    }
    

3. 处理SIGILL致命信号错误

这个错误通常是指令集不兼容,或者代码存在未定义行为:

  • 检查OboeSinePlayer的成员变量初始化顺序:你的mPhaseIncrement依赖kTwoPi、kFrequency、kSampleRate,虽然当前声明顺序没问题,但把初始化移到构造函数里更稳妥,避免潜在的初始化顺序问题:
    // 在OboeSinePlayer类里添加构造函数
    OboeSinePlayer() {
        mPhaseIncrement = kTwoPi * kFrequency / static_cast<double>(kSampleRate);
    }
    
  • 确保Oboe编译时使用的NDK版本和你的App一致,避免指令集不兼容。

4. 必须添加错误处理,排查潜在问题

你的start()方法里没有检查Oboe的操作结果,很多错误会被掩盖。添加日志和错误检查:

// 先引入日志头文件
#include <android/log.h>
#define LOG_TAG "OboePlayer"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

bool OboeSinePlayer::start() {
    oboe::AudioStreamBuilder builder;
    // 检查openManagedStream的结果
    oboe::Result result = builder.setSharingMode(oboe::SharingMode::Shared)
        ->setPerformanceMode(oboe::PerformanceMode::LowLatency)
        ->setChannelCount(kChannelCount)
        ->setSampleRate(kSampleRate)
        ->setFormat(oboe::AudioFormat::Float)
        ->setCallback(this)
        ->openManagedStream(managedStream);
    
    if (result != oboe::Result::OK) {
        LOGE("Failed to open audio stream: %s", oboe::convertToText(result));
        return false;
    }

    // 检查start的结果
    result = managedStream->requestStart();
    if (result != oboe::Result::OK) {
        LOGE("Failed to start audio stream: %s", oboe::convertToText(result));
        return false;
    }
    return true;
}

5. 调整MainActivity的调用顺序

虽然不是崩溃直接原因,但把音频启动放在UI初始化之后更合理:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    TextView tv = findViewById(R.id.sample_text);
    tv.setText(stringFromJNI());
    oboeSinePlayer(); // 移到这里,避免在UI未初始化时启动音频
}

按照这些步骤修改后,应该能解决崩溃问题,实现持续的正弦音播放。

内容的提问来源于stack exchange,提问作者Al G Johnston

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:27:22