强制第三方 API 在不同的线程上 运行

Forcing a third party API to run on a different thread

我正在使用 MediaCodec 对音频和视频进行编码。我启动了一个 运行 使用 Dispatchers.IO:

进行编码的协程
CoroutineScope(Dispatchers.IO).launch {
    videoEncoder.setCallback(object : MediaCodec.Callback() {
        override fun onOutputBufferAvailable(mc: MediaCodec, bufferId: Int, bufferInfo: MediaCodec.BufferInfo) {
           // The thread here is "main" even though a coroutine was launched using Dispatchers.IO
           Log.i("encoder", "Thread name: " + Thread.currentThread().name)
        }
    }
}

我正在使用 MediaCodec 的异步回调来接收编码数据。但是在“主”线程上的 onOutputBufferAvailable 运行s 中的代码很糟糕。有没有办法在 IO 线程上强制编码器为 运行。不幸的是,在 onOutputBufferAvailable 中创建另一个协程不是一种选择,因为每次调用回调时都创建一个新的协程太昂贵并且会降低性能。

如果你主要关心的是运行线程中除“main”之外的代码,但你不一定需要协程上下文,那么你可以创建一个Handler 运行ning 在您的后台线程上,然后将其传递给 setCallback() 方法。

另外,请注意协程非常轻量级。您可以同时 运行 数千甚至数百万个协程,并且不会发生任何不好的事情。我不确定从协程上下文外部创建协程 - 它可能涉及一些延迟。我建议先测试性能,如果你还没有这样做的话。

嗯,这是不时发生的事情。 您实际上并不能保证调用回调的位置。 恕我直言,这里最好的方法是引导协程。 我更喜欢使用 block with a .

给你一个简单的

在你的情况下你可以做下一步:

suspendCoroutine<Int> { cont ->
            videoEncoder.setCallback(object : MediaCodec.Callback() {
                override fun onOutputBufferAvailable(
                    mc: MediaCodec,
                    bufferId: Int,
                    bufferInfo: MediaCodec.BufferInfo
                ) {
                    // The thread here is "main" even though a coroutine was launched using Dispatchers.IO
                    cont.resume(bufferId)
                }
            })
        }

P.S。注意你会等到回调被触发。

P.P.S。随时根据您的需要调整 Dispatchers 内容,提供任何内容。