AudioManager在死线程上向处理程序发送消息?

时间:2013-03-11 21:48:34

标签: java android android-audiomanager android-handler

我正在尝试以编程方式将卷提升到STREAM_MUSIC流的最大值,但是当我这样做时,我正在使用“向处理程序发送消息”问题。此外,它似乎没有100%的时间提高音量,虽然当我收到这个错误时,它会提高它的时间。

代码是:

System.out.println("Maximum volume for this stream is: "+maxstreamvol+" and it used to be set to: "+currentvol);     
final AudioManager am = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
am.setStreamVolume(AudioManager.STREAM_MUSIC, maxstreamvol, AudioManager.FLAG_SHOW_UI);
am.setStreamSolo(AudioManager.STREAM_MUSIC, true);
System.out.println("Volume Raised!"); 

在谷歌搜索后,似乎这个错误与多线程情况有关......此时的代码应该在UI线程上运行。

事实上,我甚至用它包围了它:

runOnUiThread(new Runnable() {

    public void run() {
        // code_goes_here
    }
});

并且,这产生了同样的错误。我看到的错误是:

I/System.out(24949): Maximum volume for this stream is: 15 and it used to be set to: 0
W/MessageQueue(  490): Handler (android.media.AudioManager$FocusEventHandlerDelegate$1) {42b52f28} sending message to a Handler on a dead thread
W/MessageQueue(  490): java.lang.RuntimeException: Handler (android.media.AudioManager$FocusEventHandlerDelegate$1) {42b52f28} sending message to a Handler on a dead thread
W/MessageQueue(  490):  at android.os.MessageQueue.enqueueMessage(MessageQueue.java:294)
W/MessageQueue(  490):  at android.os.Handler.enqueueMessage(Handler.java:618)
W/MessageQueue(  490):  at android.os.Handler.sendMessageAtTime(Handler.java:587)
W/MessageQueue(  490):  at android.os.Handler.sendMessageDelayed(Handler.java:558)
W/MessageQueue(  490):  at android.os.Handler.sendMessage(Handler.java:495)
W/MessageQueue(  490):  at android.media.AudioManager$1.dispatchAudioFocusChange(AudioManager.java:1894)
W/MessageQueue(  490):  at android.media.IAudioFocusDispatcher$Stub.onTransact(IAudioFocusDispatcher.java:57)
W/MessageQueue(  490):  at android.os.Binder.execTransact(Binder.java:351)
W/MessageQueue(  490):  at dalvik.system.NativeStart.run(Native Method)
I/System.out(24949): Volume Raised!

有人知道这里发生了什么吗?

2 个答案:

答案 0 :(得分:3)

您的问题可能与此主题中报告的问题有关 - onPostExecute not being called in AsyncTask (Handler runtime exception)

音频焦点更改的显示是触发Android无法完成的UI事件。目前还不清楚为什么会这样。也许音频管理器是通过一个上下文获得的,而toast用于显示音量是在另一个上下文中执行的?快速而肮脏的变化是将标志交换为FLAG_VIBRATE并检查是否有所不同。这会将问题缩小到UI更新,然后您可以继续使用。

答案 1 :(得分:0)

AudioManager使用它创建的线程来调用你的回调或进行UI操作(显示音量吐司等)
(通过Looper.myLoopergetMainLooper,请参阅this)。

因此,您应该确保在UI线程上发生对Context.getSystemService(AUDIO_MANAGER)第一次调用。
(不确定子序列调用是否会重用该实例,但即使我重新检索AudioManager,仍然会发生异常)

我今天遇到过这个问题并通过添加对我的Application.onCreate()的调用来解决它。 (有点类似this回答?)