android - Activity轮换导致服务被杀死

标签 android service android-activity android-service aidl

我有一个播放音乐的服务和一个提供用于与服务交互的 GUI 的 Activity 。该 Activity 在列表项单击上打开(我有一个录音列表),并在 onCreate 绑定(bind)该服务(并创建它) () 方法。

当调用 onDestroy() 时,我取消绑定(bind)服务(这将破坏服务) - 这应该没问题,因为我不希望服务在退出 Activity 时运行,但问题出现在方向更改上,因为它再次重新创建 Activity 和服务(旋转设备时轨道将停止并从头开始播放)。

我知道一些可能有用的标志(orientationChange),但对我来说不是一个好的做法,因为我想要在横向上有不同的布局。 另外,我可以让音乐播放器服务在我的应用程序运行时运行,但这不是一个好主意,因为用户可能不想打开播放器,而只想录制,因此播放器服务不一定在这里.

以下是一些代码 fragment :

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        LocalBroadcastManager.getInstance(this).registerReceiver(mLocalReceiver, new IntentFilter(PlayerBroadcastReceiver.ACTION_PLAYER_SERVICE_STARTED));
        setContentView(R.layout.media_player_screen);
        setVolumeControlStream(AudioManager.STREAM_MUSIC);
        AudioPlayerServiceBridge.getInstance().addCallback(this);
        AudioPlayerServiceBridge.getInstance().doBindService(this);

        init(savedInstanceState);       
        super.onCreate(savedInstanceState);
    }

@Override
protected void onDestroy() {
    LocalBroadcastManager.getInstance(this).unregisterReceiver(mLocalReceiver);
    mLocalReceiver.removeCallback();
    Log.d(AudioPlayerActivity.class.getName(), "onDestroy() -> "+AudioPlayerActivity.class.getName());
    AudioPlayerServiceBridge.getInstance().doUnbindService(this);
    AudioPlayerServiceBridge.getInstance().removeCallback(this);

    super.onDestroy();
}

和服务连接管理器:

public void doBindService(Context context) {
    // Establish a connection with the service.  We use an explicit
    // class name because there is no reason to be able to let other
    // applications replace our component.
    if(!mIsBound){
        context.bindService(new Intent(context, 
                AudioPlayerService.class), serviceConnection, Context.BIND_AUTO_CREATE);
        mIsBound = true;
    }
}

public void doUnbindService(Context context) {
    if (mIsBound) {
        // If we have received the service, and hence registered with
        // it, then now is the time to unregister.
        if (mServiceMessenger != null) {
            Message msg = Message.obtain(null, AudioPlayerService.MSG_UNREGISTER_CLIENT);
            msg.replyTo = mMessenger;
            mServiceMessenger.send(msg);
        }

        // Detach our existing connection.
        context.unbindService(serviceConnection);
        mIsBound = false;
    }
}

如果可能,请告诉我处理此问题的良好做法。

最佳答案

答案是:

我应该使用以下命令启动服务:startService(new Intent(this, service.class)) 并在此之后开始绑定(bind)。此方法可防止调用 doUnbind() 时服务被终止。所以 onCreate() 方法现在更改为:

@Override
protected void onCreate(Bundle savedInstanceState) {
    LocalBroadcastManager.getInstance(this).registerReceiver(mLocalReceiver, new IntentFilter(PlayerBroadcastReceiver.ACTION_PLAYER_SERVICE_STARTED));
    setContentView(R.layout.media_player_screen);
    setVolumeControlStream(AudioManager.STREAM_MUSIC);

    if(savedInstanceState == null)
        startService(new Intent(this, AudioPlayerService.class));

    AudioPlayerServiceBridge.getInstance().addCallback(this);
    AudioPlayerServiceBridge.getInstance().doBindService(this);

    init(savedInstanceState);       
    super.onCreate(savedInstanceState);
}

onDestroy()方法:

@Override
    protected void onDestroy() {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mLocalReceiver);
        mLocalReceiver.removeCallback();
        Log.d(AudioPlayerActivity.class.getName(), "onDestroy() -> "+AudioPlayerActivity.class.getName());
        AudioPlayerServiceBridge.getInstance().doUnbindService(this);
        AudioPlayerServiceBridge.getInstance().removeCallback(this);

        super.onDestroy();
    }

并在 onBackPressed() 中停止服务(如果需要):

@Override
public void onBackPressed() {
    Log.d(AudioPlayerActivity.class.getName(), "onBackPressed() -> "+AudioPlayerActivity.class.getName());
    isPaused = true;
    Log.d(AudioPlayerActivity.class.getName(), "Sending message to player service: MSG_RELEASE_PLAYER");
    AudioPlayerServiceBridge.getInstance().sendAsyncCall(AudioPlayerService.MSG_RELEASE_PLAYER);

    if(mSeekBarChanger != null){
        mSeekBarChanger.stopThread();
    }       

    AudioPlayerServiceBridge.getInstance().doUnbindService(this);
    stopService(new Intent(this, AudioPlayerService.class));
    super.onBackPressed();      
}

关于android - Activity轮换导致服务被杀死,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16857124/

相关文章:

javascript - 返回对象的比较 - 服务与工厂的简单示例

Android AccessibilityManager getEnabledAccessibilityServiceList 在某些情况下返回空列表

java - 添加 Activity,布局显示但不起作用它是 java 代码(在 Activity 上)

android - fragment : NullPointer with Adapter 内的 ViewPagerIndicator

java - 如何将作为服务运行的 JBoss AS 6 绑定(bind)到 0.0.0.0?

Android ViewPager 前置新 View

java - 从 Activity 调用 fragment 时应用程序崩溃

android - 垃圾收集 Activity

Android camera2 api触摸对焦示例?

java - Android 上的 SAX 被多次调用相同的数据但有偏移