【问题标题】:Activity rotation cause service to be killed活动轮换导致服务被杀死
【发布时间】:2023-03-09 06:58:01
【问题描述】:

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

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

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

这里有一些代码sn-ps:

    @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;
    }
}

如果可能的话,请告诉我处理这个问题的好方法。

【问题讨论】:

    标签: android service android-activity android-service aidl


    【解决方案1】:

    答案是:

    我应该使用 startService(new Intent(this, service.class)) 启动服务,然后开始绑定。此方法可防止在调用 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();      
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-05
      • 1970-01-01
      • 2015-05-31
      • 2014-05-27
      • 1970-01-01
      • 2015-02-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多