我有一个使用 MediaPlayer 在前台服务中播放的音频文件。当用户点击与前台服务关联的通知时,我使用 Intent 启动一个 Activity,如下所示:
Intent audioPlayIntent = new Intent(context, AudioPlayActivity.class);
audioPlayIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
audioPlayIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, audioPlayIntent, 0);
然后,此 Activity 绑定到服务以向用户显示 MediaController。
这是服务中的绑定代码:
public class AudioPlayerServiceBinder extends Binder{
public AudioPlayerService getAudioService(){
return AudioPlayerService.this; //this class is declared in AudioPlayerService.java, so it has access to the Service instance.
}
}
..在活动中onStart
我调用了这个方法:
private void bindAudioService()
{
Intent i = new Intent(this, AudioPlayerService.class);
serviceConnection = new AudioServiceConnection();
bindService(i, serviceConnection, 0);
}
我在下面的 mediaController.show(5000) 行中遇到异常:
private class AudioServiceConnection implements ServiceConnection{
AudioPlayerServiceBinder audioServiceBinder;
@Override
public void onServiceConnected(ComponentName name, IBinder serviceBinder)
{
serviceConnected = true;
Log.i(TAG, "Connected to audio player service.");
audioServiceBinder = ((AudioPlayerServiceBinder) serviceBinder);
AudioPlayActivity.this.audioService = audioServiceBinder.getAudioService();
mediaController.show(5000);
}
例外是:
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
at android.view.ViewRoot.setView(ViewRoot.java:527)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
at android.view.Window$LocalWindowManager.addView(Window.java:424)
at android.widget.MediaController.show(MediaController.java:304)
at android.widget.MediaController.show(MediaController.java:249)
at com.myapp.AudioPlayActivity$AudioServiceConnection.onServiceConnected(AudioPlayActivity.java:295)
我可以通过以下方式重新创建相同的异常:
- 点击通知打开Activity
- 按返回关闭活动。
- 单击通知以打开新版本的活动。
这使我相信 mediaController 以某种方式泄漏并试图在原始 Activity 实例中显示自己。不过,我找不到任何发生这种情况的原因,因为 mediaController 在 Activity 的 onCreate() 中实例化,并且仅与 Activity 本身相关联。(然后活动处理将命令传递给服务)。