2013-07-18 2 views
1

내 앱에서 MP3 스트림의 음악을 재생하는 데 사용되는 서비스가 있습니다. 시작 (startService())하고 연결 (bindService())하므로 연결된 클라이언트가 없을 때 중지되지 않습니다. 플레이어가 일시 중지 된 상태에서 잠시 후에 일부 리소스를 정리하고 더 이상 일시 중지 된 상태로 있으면 거의 모든 리소스를 정리하고 클라이언트가 연결되어 있지 않으면 (연결되어있는 작업) stopSelf를 호출하는 서비스를 중지합니다); 어떤 클라이언트가 연결되어 있다면, 클라이언트가 연결되어 있지 않고이 부울이 참이면 stopSelf()를 호출하여 모든 클라이언트가 연결을 끊을 때 검사되는 부울 값을 설정하여 파손되도록 준비합니다.안드로이드 서비스의 onBind가 호출되지 않고 연결된 클라이언트로도 onDestroy가 호출 중임

기본적으로 서비스는 (1) 연결된 클라이언트가없고 (2) 오랜 시간 동안 일시 중지 된 경우에만 파괴됩니다.

잘 작동하지만 문제가 있습니다. onDestroy()에서 모든 리소스를 해제하고 일부 데이터 (재생중인 음악 목록과 같은)를 저장합니다. 많은 음악이 있다면 거의 30 초가 걸릴 수 있습니다. 문제는 onDestroy()가 아직 반환되지 않은이 기간에 내 앱을 다시 열 때입니다. 무슨 일이 일어나면 같은 서비스 인스턴스가 사용되고 onCreate()가 호출되지 않는다는 것입니다. 따라서 리소스가 공개 된 이후 자연스럽게 오류가 발생합니다.

이 버그는 시뮬레이션하기가 매우 어렵습니다. 나는 단지 3 번 재현 할 수있었습니다. 진행 방법을 모르겠습니다. 나는 가능한 한 빨리 onDestroy()에서 자원을 해제하고 데이터를 저장하기 위해 다른 스레드를 사용하여 복귀하는 방법을 생각했지만 데이터가 저장되기 전에 새 서비스가 시작되도록했습니다. 누군가가 안드로이드에서 서비스의 파괴/재창조를하는 방법에 대해 더 자세히 알고 있습니까? 나는 어떤 클래스가 그것을 관리하는지 모른다. 그래서 나는 그것을 더 잘 이해하기 위해 읽을 수있는 코드를 모른다.

미리 감사드립니다.

업데이트 :

방금 ​​실제 문제를 발견했습니다. 내 Activity가 연결을 끊고 다시 연결할 때 (모든 Activities를 닫고 앱을 다시 열 때) 서비스의 onBind가 호출되지 않는 것 같습니다. 그래서 리소스 클리너 (즉, 플레이어가 일시 중지되었을 때 예정된 예정된 작업)는 클라이언트가 연결되어 있지 않고 stopSelf()를 호출한다고 생각합니다 (onBind 및 onUnbind 메서드를 사용하여 연결된 클라이언트를 추적합니다). 그리고 클라이언트에 서비스가 연결되었다고해도 onDestroy()가 호출됩니다. 그런 다음 내 활동은 방금 모든 리소스를 정리 한 서비스에 계속 연결됩니다.

질문 제목도 업데이트했습니다.

업데이트 2 :

조금 더 설명. 내 응용 프로그램을 닫고 다시 열면 ServiceConnection 구현의 onServiceConnected 메서드가 bindService 뒤에 호출되지만 서비스의 onBind는 호출되지 않습니다. 그리고 클라이언트가 연결되어 있지 않다고 생각하는 것 같습니다. 문서에서 모든 클라이언트가 바인드 해제 할 때까지 시작된 서비스와 바인딩 된 서비스가 파기되지 않는다고 말하는 경우에도 파손되기 때문입니다.

+0

리소스를 해제하고 activity onDestroy 메서드가 아닌 onDestroy 메서드에서 데이터를 저장할 수 있습니다. –

+1

inDestroy 메서드를 사용하면 리소스를 해제하고 데이터를 저장하기 시작할 수 있습니다.이 시점에서 작업이 시작된 곳 (SharedPreferences 또는 다른 위치)에 플래그를 작성하고 flag = true이면 액티비티 검사에서 백그라운드 스레드를 시작하고 3 예를 들어, 플래그를 다시 확인하십시오. 작업이 끝나면 백그라운드 스레드가 서비스를 다시 시작합니다. –

+0

저는 Activity의 onDestroy()가 아니라 Service의 onDestroy()에 대해 말하고 있습니다. 활동은 서비스에서 단절된 것입니다. onUnbind()가 호출되면 내가 말한 검증을 수행합니다. –

답변

3

나는 서비스에 다시 연결할 때 내 onBind가 호출되지 않고 있음을 알았습니다. 그래서 나는 onUnbind에서 'true'를 반환하기 시작했습니다. 이 방법은 활동이 서비스에 다시 연결될 때 onRebind가 호출됩니다. 그런 다음 클라이언트가 연결되어 있고 자원 클리너가 클라이언트가 연결되어 있지 않으면 stopSelf를 호출하는 경우 추적을 계속합니다.

어쨌든, 나는 버그라고 생각합니다.모든 클라이언트가 연결 해제되고 stopService/stopSelf가 호출 될 때까지 시작된 서비스 (startService())와 바운드 (bindService())는 파괴되지 않습니다 (onDestroy()). 따라서 리소스 클리너가 stopSelf()를 호출하면 클라이언트가 연결되어 있으므로 (클라이언트가 다시 연결될 때) 서비스가 파괴되지 않아야합니다.

관련 문제