2013-07-01 1 views
2

내 앱에 항상 실행하고 싶은 로컬 서비스가 있습니다. 서비스가 다른 스레드를 시작하게하여 수행하고 요청에 응답하여 Handler에 전송합니다. 서비스에 바인딩하면 백그라운드 스레드의 Handler가 반환되므로 클라이언트 작업이 요청을 발행 할 수 있습니다.Android 로컬 서비스 바인딩 및 백그라운드 스레드

지금까지 그렇게 좋았습니다.

내 응용 프로그램은 초기 상태를 설정하기 위해 서비스를 사용해야하는 Fragment을 사용합니다. 프래그먼트가 사용자 입력에 대한 응답으로 인스턴스화되면 그 때까지 서비스가 프래그먼트의 부모 작업에 바인딩되기 때문에 괜찮습니다. 즉, ServiceConnection.onServiceConnected이 프레임 워크에서 호출되었으며 해당 활동은 Handler에 대해 파편이 서비스와 통신하는 데 사용할 수 있음을 알고 있습니다.

오리엔테이션 변경에 대한 응답으로 내 활동을 다시 인스턴스화 할 때 문제가 발생합니다. 이 상황에서 프레임 워크는 주 스레드의 메시지 루프 인 이전의 모든 활동 조각을ServiceConnection.onServiceConnected이 호출되기 전에 다시 작성하여 레크리에이션에서 서비스에 액세스 할 수 없음을 나타냅니다 단계.

유일한 해결책은 서비스가 백그라운드 스레드와 관련된 응용 프로그램 전역 상태로 처리기를 게시하는 것입니다. (나는 다른 기법이 있지만 그 목적을 위해 Application을 서브 클래 싱하고있다.) 결국 나는 그것의 'serviceness'보다는 'threadness'를 사용하고있다.

Android가 어색하고 복잡하게 만들고 싶어하는 것처럼 보이기 위해 간단하고 효과적인 방법 인 것 같습니다. 글로벌 상태에 대한 일반적인 일반적인 예약 외에도, 내 접근 방식이 간과하는 Android 관련 고려 사항이 있습니까? 또는 내가 바라는 동일한 목적을 달성하기위한 더 좋은 방법은 무엇입니까?

답변

1

정확하게 이해하면 IntentService을 살펴 보는 것이 좋습니다. IntentService는 바인딩시 자체 스레드를 시작하고 인 텐트가 수신되면 처리합니다. 벌써 살펴 봤니?

+0

감사합니다. 그것은 나를 좋은 길로 인도했다. 내 배경 스레드가 reincur하고 싶지 않은 특정 초기화를 가지고 있기 때문에'IntentService'를 사용하고 싶지는 않지만,'startService (Intent)'가 아마도 필요한 것일 것입니다. 나는 이것을 충분히 고려하지 않았다. – JulianSymes

+0

실제로 백그라운드 스레드의 핸들러에 대한 참조로 임의의 오브젝트를 전달해야하므로 실제로 작동하지 않을 것이라고 생각하며 인 텐트 메커니즘을 통해 이러한 오브젝트를 전달할 수 있다고 생각하지 않습니다. Handler에게 보내는 메시지에 이들을 넣어야합니다. – JulianSymes

+0

내가 틀렸다고 정정하되, 전달하려고하는 객체를 Parcelable 인터페이스를 구현하도록 만들 수 없습니까? 이렇게하면 이러한 객체를 마샬링/언 마샬링하고 IntentService에서 새로 생성 된 Thread에 전달할 수 있습니다. 이 작업을 수행하는 방법에 대한 링크를 살펴보십시오. http://android-er.blogspot.com/2013/03/example-to-implement-parcelable.html – Emmanuel

1

안드로이드는 일을하는 방식이 - 어색하지만 종종 - 어색한 문제를 풀기위한 것이기 때문에 - 공정해야합니다.

  • 중 하나가 안드로이드의 아키텍처를 사용하여 모든 길을 갈,
  • 또는 (UI의 일반적인 제외)을 피하려고 : 당신은 할 수

    .

두 가지 방법을 결합하는 것은 까다로운 데 그 이유는 두 가지 방법 모두 최악의 경우가 많기 때문입니다.

실제 참조를 전달해야하기 때문에 바운드 서비스를 사용하고 있다는 것을 이해합니다. (의도적으로 인텐시티 기반 서비스로 전환하는 것은 불가능합니다) 서비스 및 응용 프로그램 서브 클래스를 모두 제거합니다 . 당신이 설명하는 시나리오에서 그들 중 누구도 전혀 필요하지 않습니다. 간단하고 순수한 Java 싱글 톤이 가능합니다.

다른 조합은 Android 방식을 채택하는 것입니다. 이 경우 Service에 연결하는 코드 주위에 래퍼를 만들어 서브 클래스를 Loader으로 만듭니다. 이 방법을 사용하면 LoaderManager에 의해 관리되는 단일 연결 인스턴스를 가질 수 있습니다.

아마도 API의 원래 작성자는 모든 데이터가 콘텐츠 공급자로부터 읽히고 비동기 서비스 (또는 아는 사람이 아닌)에 의해 수정되도록 응용 프로그램을 다시 작성하기를 원할 것입니다.

+0

감사합니다. 내가 기억할 수있는 한, 서비스를 사용하는 본래의 이유는 BroadcastReceiver가 경고하는 알람에 대한 응답으로 작업해야한다는 것이었고, 내 스레드가 죽어가는 것을 막을 수있는 것이 있는지 확신 할 수 없었습니다. 그것이 서비스에서 시작되지 않은 경우. 나는 오해 했습니까? – JulianSymes

+1

스레드는 서비스와 관련이 없습니다 (어떻게 작동합니까?!). 그래서 서비스 내부 또는 다른 곳에서 스레드가 만들어 지는지는 중요하지 않습니다. 프로세스가 살아 있어야한다면 (문에 발을 들여 놓는 것과 같이) 서비스를 확장하고 Context # startService를 호출하여 완전히 빈 클래스를 생성 할 수 있습니다. Context # stopService를 호출 할 때까지 "실행 중"(의미하는대로 ...)으로 간주됩니다. 어떤 식 으로든 건드리지 않거나 코드를 넣을 필요가 없습니다. – fdreger

+0

스레드가 서비스와 어떻게 연관되어 있는지에 대한 질문은 나에게도 발생했지만, 시작하지 않으면 안드로이드가 리소스 고갈 상황에서 애플리케이션 구성 요소를 관리하려는 시도를 쉽게 물리 칠 수있는 것처럼 보입니다. 단일 인스턴스를 관리하려면 내 백그라운드 스레드의 AlarmService에서 startService를 호출하고 서비스의 onCreate가 스레드를 시작하도록하는 것이 가장 간단합니다. – JulianSymes

관련 문제