• Daum
  • |
  • 카페
  • |
  • 테이블
  • |
  • 메일
  • |
  • 카페앱 설치
 
슈퍼드로이드
 
 
 
카페 게시글
검색이 허용된 게시물입니다.
안드로이드 기본 강좌 19. Service 에 대해서 - bindService 구현 (2013.02.13 갱신)
슈퍼성근 추천 38 조회 22,217 11.12.15 13:09 댓글 98
게시글 본문내용
 
다음검색
첨부된 파일
댓글
  • 작성자 14.07.25 12:56

    gen에 에러가...- _-a;;
    프로젝트 clean한번 해보시겠어요..
    그런 경험이 없어서. T-T

    Messenger를 사용하면 AIDL 없이 (사실 없는 것은 아니죠. 프레임웍에 존재할뿐)
    바운드 서비스를 사용할 수 있습니다.
    하지만 마치 함수를 사용하듯이 할 수는 없죠.
    핸들러를 사용하니까요.

    어쨌든 장점은 AIDL 배포 없이 사용할 수 있다는 장점은 있습니다.

  • 14.07.25 11:53

    안녕하세요. 성근님 꿀같은 강의 잘 보면서 공부중입니당!!
    지금 서비스부분 보면서 질문 좀 드릴게 생겨서 댓글다네요~~

    마지막 oneway 예약어를 쓰는 부분에서 헤매고 있는데요..!!
    oneway를 쓰면 값이 바뀔때마다(1초마다) 로그가 찍혀야 하는데.. 그러질 않네요~~
    다른 부분은 문제없이 진행되었는데...어떤문제가 있는건가요~??
    감이 잡히질 않아서 어느 부분의 코드를 올려야 할 지 몰라 질문만 남깁니다~~ㅠㅠ

  • 작성자 14.07.25 12:53

    먼저 긴 글 읽어주셔서 감사드립니다.

    제일 마지막 예제 소스에서 확인해보았습니다.
    그런데 정상적으로 잘 동작을 하고 있네요.
    ^^ 다시 한번 확인해주세요.

  • 14.07.25 13:06

    @슈퍼성근 아....제가 성근님 강의 보면서 예제를 직접 쓰고 있거든요~~
    다시한번 성근님 예제랑 비교하면서 차근차근 살펴봐야겠네요~ 답변감사드립니다~~

  • 작성자 14.07.25 13:09

    @콩다래 아 정말 좋은 방법입니다. T-T
    직접 구현해보지 않으면 와닿지 않거든요.
    예제 소스는 바로 이를 위해 올린것 입니다.
    훌륭하십니다.

  • 14.08.07 13:51

    아 정말 좋은 내용입니다. bindservice를 이해하려고 인터넷도 보고 책도 찾아봤지만 여기만큼 정말 자세하게 설명되어있는 곳이 없네요. 하지만 ㅠㅠ 너무 길어 ㅠㅠ 길어도 너무 길어 ㅠㅠ 1편 2편으로 나눴으면더 좋았을 꺼라는 생각이 드네요 ㅎ
    그래도 정말 유익한 자료입니다!

  • 작성자 14.08.07 13:59

    너~~~무 길어 죄송해요. T-T

    사실 거기엔 좀 사연이 있어요.
    대게 어떤 주제의 기술이든 독립적으로 존재하는 것이 아니라
    관련된 기반 기술이 있고 그것들과 어우러져 파생됩니다.
    예를 들어 직렬화에서 프리미티브타입 ->Serializable -> Parcel -> Parcelable -> Bundle...
    식으로 말이죠.

    따라서 이어져 설명하는게 중요하다고 생각했거든요.
    그래서 하나의 게시글로 최대한 설명하려고 했는데.

  • 작성자 14.08.07 14:00

    너무 무식한 발상이었던것 같아요.
    굳히 게시글을 하나로 할 필요까지는...
    그렇다고 모든 글들이 하나로되어 있는것도 아니고 ㅎㅎㅎ
    정체성을 잃어버렸죠.

    다음 글들은 잘 나눠놓을께요.

    좋은 의견 감사드려요.

  • 14.08.08 14:48

    @슈퍼성근 세세한 것까지 신경써 주시고 ㅎㅎ 감사합니다~ 그래도 좋은 자료임은 틀림없이니 슈퍼성근님 강추!! 책도 추천!

  • 14.08.29 18:19

    한가지 여쭤볼께 있어서 남겨봅니다.
    서비스돌리는 app 과 그 서비스를 이용하는 외부 app 이 있씁니다.
    서비스와 외부앱간의 통신은 성공적으로 이뤄진 상태입니다.
    제가 생각했던 것은 서비스app 액티비티에서도 bind를 하고 외부app 액티비티에서 bind를 할 경우
    서로 콜백을 다르게 할줄 알았는데... 서비스app 에서 콜백할때 외부 app 에서도 콜백이 동시에 이뤄지고
    이와 반대로 외부app에서 콜백하면 서비스app에서 콜백을 합니다.
    제 생각에는 같은 콜백함수를 이용하면서 그러는거 같은데 따로 분리하려면 콜백함수를 여러개 생성해서 따로해야 하나요? 이부분을 정확히 모르겠네요;;;

  • 작성자 14.08.29 19:09

    죄송합니다.
    질문하신 내용을 이해하지 못했습니다. ^^;
    요지가 여러 클라이언트에서 동시에 특정 서비스 함수를 호출하면
    같은 콜백으로 반환된다는 말씀이신가요?

    RemoteCallbackList 내용을 보시면 콜백을 등록하는 것은
    클라이언트고, 서비스는 클라이언트가 등록한 콜백객체를
    호출해주고 있습니다.

    죄송합니다만 좀더 자세히
    질문 게시판에 올려주시면
    정확한 답을 드릴수 있을것 같네요.

  • 14.09.02 17:41

    안녕하세요. 강좌 잘 보고 있습니다.
    한가지 궁금한 점이 있는데요.

    Unbind Service를 선택시에 Toast도 발생하지 않고 두번 누르면 앱이 종료되는 현상이 발생합니다.
    Service 프로세스에서는 Unbind 로그는 찍히는데 onServiceDisconnected는 호출되지 않네요..
    어떤 문제일지 의견 주시면 감사하겠습니다.

  • 작성자 14.09.02 17:51

    안녕하세요. ^^ 제가 올린 Sample 앱이 그러한가요?
    아니면 직접 따라하신 앱이 그러한가요?
    사용하신 예제소스를 아려주시겠어요.

    그리고 onServiceDisconnected가 호출되지 않는 것은 바로
    bindService의 세번째 인자인 BIND_AUTO_CREATE 값 때문입니다.
    간략히 말씀드리자면 BIND_AUTO_CREATE 로 설정시
    startService로 서비스가 동작중이 아니더라도
    바운드서비스를 사용할 수 있도록 하는 값입니다.
    이렇게 바인딩되면 서비스 연결을 유지하기 때문에(unbind를 하더라도 말이죠)
    onServiceDisconnected가 호출되지 않습니다.

  • 작성자 14.09.02 17:52

    혹시 책을 가지고 계시다면 18장 서비스편에 상세히 설명하고 있습니다.
    아직 인터넷 강좌는 최신화가 덜되어 죄송합니다.(정리되면 최신화에 힘써야겠어요.)

  • 14.09.02 18:24

    @슈퍼성근 답변 감사드립니다.
    제가 따라한 앱에 문제인지 알고 샘플앱을 다운 받아서 확인해도 동일한 현상이었습니다.
    onServiceDisconnected 관련한 내용 답변 감사드립니다. 큰 도움 되었습니다. ^^

  • 14.11.04 23:33

    안녕하세요. 늘 잘보고 있습니다.
    서비스에 callback을 등록하는 예제에서 질문이 있어 문의드립니다.
    onCountChanged()을 실제 구현하고 있는쪽은 ClientCountTest 패키지인데,
    왜 ServiceCountTest패키지에 aidl이 포함이 되어 있나요?
    제가 이해한 바로는 실제 구현하는 패키지에 포함되어야한다고 생각하고 있었는데^^;아닌가요?

  • 작성자 14.11.04 23:45

    안녕하세요.

    잠시 헷갈리셨나봐요. ^^
    둘다 AIDL이 존재해야 합니다.
    AIDL의 역할은 서로 다른 프로세스간 함수.. 즉 데이터를 전달하는 목적입니다.

    여기서 서비스단에서 클라이언트 단의 callback을 호출하려면
    aidl을 통해야하거든요.

    이렇게 생각하시면 쉬울것 같습니다.
    클라이언트에서 일반적으로 서비스 함수를 호출하는데
    콜백은 반대가 되죠. 즉 서비스가 클라이언트 함수를 호출합니다.

    그리고 프로세스가 다른 RPC는 AIDL을 이용하는 것이니
    당연히 두곳 모두 필요합니다.

    이 부분은 위쪽 분해/조립 등의 과정을 다시 상기하시면 좋겠네요.

    수고하세요.

  • 14.11.05 00:22

    @슈퍼성근
    제가 이해가 안되어서 질문은 다르게 해보겠습니다.
    aidl시 작성시 내가 노출 즉, 외부에서 RPC를 허용하는 함수를 작성하게 되는데 서비스에서 노출시킨 함수는 이해가 되는데, 하기와 같이 클라이언트측에서 노출한 함수작성시 패키지명이 서비스 패키지로 되어있습니다.
    제가 생각할땐 package com.test.ClientCountTest; 로 작성되어야 하지 않은가 싶어 질문드린거였습니다.


    package com.test.ServiceCountTest;

    interface ICountServiceCallback
    {
    oneway void onCountChanged( int changedCount );
    }

  • 작성자 14.11.05 00:28

    @아라한 외부에 제공되는 함수 그리고 그 콜백 함수는 서비스에서 정의하는 것입니다.
    서비스 입장에서 보면
    특정 함수를 제공하고 그 결과를 콜백으로(비동기) 알려주는 것까지 제공하는 것이죠.
    다만 콜백(인터페이스) 구현은 클라이언트가 해서 그렇게 보일 순 있지만
    콜백 조차 서비스의 설계입니다.

    음 이렇게 생각하면 쉬울것 같습니다.
    View에 클릭 리스너를 구현할때
    클릭 리스너 구현은 뷰를 사용하는 곳에서 하죠.
    하지만 클릭리스너 인터페이스 자체는 뷰에 있죠.

    여기서 뷰의 클릭리스너를 서비스로 보시고
    클릭리스너를 구현하는 부분을 클라이언트라고 보시면 되겠네요.

  • 작성자 14.11.05 00:32

    @아라한 참고로 서비스 입장에서는 클라이언트 앱이 무엇인지 알 수 없어요.
    그래서 미리 클라이언트 패키지명의 AIDL 자체를 만들수 조차 없죠. ^^

    이해가 되지 않으시면 모두 저의 부족한 설명 때문입니다.
    부담가지지 마시고 얼마든지 재질문하셔도 됩니다.

    수고하세요.

  • 14.11.05 00:39

    감사합니다. 늦은 시간에 이렇게까지 피드백이 바로 올줄은 몰랐네요. ^^ 추가로 별외질문 드리겠습니다.제가 웹쪽지식이 별로 없는데 요즘은 하이브리드앱 기본이라 어떻게 접근하는게 효율적일지 모르겠습니다.별도로 jsp나 jquery,jdbc를 익혀야하나요? 필요하다면 책추천부탁드립니다.

  • 작성자 14.11.05 10:37

    ^^ 죄송합니다만 이 질문에 대해서는 노코맨트할께요.
    하이브리드 앱/웹앱... 등에 대한 개인 의견은 말씀드리기 좀 곤란해서요.
    이해부탁드립니다.

  • 14.12.23 17:24

    강의해주신 내용들 모두 실무에서 유용하게 도움이 되고 있으며, 크게 감사 드립니다.
    콜백 기능의 UseCase 관련하여 몇가지 설계상의 어려운 점에 대해 아래와 같이 문의 드립니다.

  • 14.12.23 17:22

    (Q1) 임의의 Client1, Client2, Client3이 특정 서비스 모듈에서 제공하는 CallBack API를 등록했습니다. 이때, 해당 서비스 모듈에서 이벤트가 발생하면, 상기의 설명하신 예제에서는 CallBack API를 등록한 모든 Client 들에게 Broadcasting 되고 있습니다. 그런데, 서비스의 컨디션의 의해 어떤 경우는 Client1에만, 또 어떤 경우에는 Client2, 또 어떤 경우에는 Client1과 Client2에 notify 하고자 하는데요. 범용적인 방법으로 설계해야 하는데 어떤 방법이 좋을까요? 잘 모르겠네요.
    a. 각각의 조건에 해당하는 CallBack API를 설계한다.
    b. Client에서 CallBack API를 등록할 때, Client 정보를 서비스에 제공한다.
    c. 기타 등등

  • 14.12.23 17:23

    (Q2) 임의의 Client1이 특정 서비스 모듈에서 제공하는 CallBack API를 등록하려 합니다.
    그런데, 이 Client1은 Background 실행 중에도 콜백을 호출받을 필요가 있습니다.
    a. 이 Client1 또한 서비스 모듈로 설계되어야만 하나요?
    b. (a의 답변이 yes인 경우) 서비스 모듈로 설계되어야만 한다면, 상기 예제에서 설명주셨던 Activity 대신에 서비스 컴포넌트에서 CallBack API를 등록하면 되나요? 아니면 CallBack 기능을 제거하고, 양방향으로 서비스 바인딩을 걸어 주어야 하나요?

  • 작성자 14.12.23 19:58

    좋은 질문이십니다.

    첫번째 질문에 답합니다.
    RemoteCallbackList 클래스는 내부적으로 cookie 값을 추가할 수 있습니다.
    콜백을 등록할 때 RemoteCallbackList.register(콜백, 바로 요값)
    즉 두번째 인자인데요.
    이 값에 구분자를 넣어주시면 됩니다.

    그럼 RemoteCallbackList.beginBroadcast()
    과 finishBroadcast() 사이에서
    getBroadcastCookie()라는 함수로 구분자를 받아올 수 있고
    이 값을 통해 원하는 대상 콜백만 호출하시면 됩니다.

    물론 구분자에는 패키지명 혹은 대상을 구분할 값을 클라이언트에게 받아야겠죠.
    일반적으로는 패키지명이 가장 많이 사용됩니다.

  • 작성자 14.12.23 20:04

    두번째 질문에 답합니다.
    당연히 Service형태여야 합니다.
    Service를 써야하는 경우는 단순합니다.
    화면을 가진 액티비티가 아닌 백그라운드 작업을 해야할 때입니다.
    액티비티에서 작업스레드로 처리하고, 액티비티가 종료된 후에도 돌아야 한다면
    이는 서비스 밖에 방법이 없습니다.

    b의 답.

    당연히 서비스에서 다른 서비스의 콜백을 등록하셔야 겠죠.
    콜백이 호출되는 곳이 어딘지 생각하시면 쉽습니다.
    액티비티에서 콜백을 등록하면 등록된 콜백은 액티비티가 종료하면
    받을 수 없습니다.
    즉 액티비티의 Context를 사용할 수 없게되죠. 액티비티가 종료되면
    액티비티의 Context도 사라지니까요.

  • 작성자 14.12.23 20:08

    마지막으로 힌트 한가지 드립니다.
    서비스에서 일련의 작업들을 스케쥴링하기가 쉽지 않습니다.
    Main Thread의 Handler를 이용하여 sendMessage로
    처리할 작업들을 큐에 담아 순차적으로 처리하면 편하지만
    서비스는 Main thread에서 작업하면 안됩니다.
    (이는 위에서 설명드렸죠.)
    이를 위해 HandlerThread라는 녀석이 있습니다.
    요 녀석은 작업 스레드를 만들어줄 뿐만 아니라
    Main Thread에 있는 looper, messageQueue 구조와 동일합니다.
    그래서 서비스 내에서는 HandlerThread를 기반으로 처리하는 것이 매우 편합니다.
    혹시 책이 있으시다면 HandlerThread를 참고해주셨으면 좋겠네요.

    수고하세요.

  • 14.12.24 09:15

    명쾌한 답변,,, 감사 감사 무한 감사 드립니다.

  • 15.01.15 13:48

    안녕하세요 잘 보고 있습니다. 질문드릴게 있어요
    callback 이용할 때 하나씩 하지 않고 클래스를 하나 만들어서 dto형식으로 한번에 넘기려고 했는데
    aidl에서 import를 하고 쓰려고 해도 클래스를 자꾸 찾을 수 없다고 뜨네요
    다른 곳에서 사용한 그대로 임포트를해도 철자 틀린것도 아닌데 자꾸 해당 클래스를 찾을 수 없다는
    오류만 띄워주니 미치겠습니다.
    같은 패키지 안에 넣고 임포트 안하고 사용하려고 하면 알 수 없는 클래스라고 뜨고..
    어떻게 해결해야할 지 조언좀 얻을 수 있을까요?

  • 작성자 15.03.04 18:48

    안녕하세요. 늦게 봤네요. T-T

    아마도 제 생각에는 AIDL의 경로가 잘못된 것이 아닌가 생각됩니다.
    AIDL을 제공하는 서비스측과
    AIDL을 사용하는 클라이언트의 .aidl 파일을
    패키지 경로까지 같아야 합니다.

    늦었지만 지금도 문제가 된다면 Sample을 질문게시판에 올려주시면
    쉽게 도움드릴수 있겠네요.

    수고하세요.

  • 15.03.04 18:45

    궁금한것이 있습니다. 여기서 aidl 파일에 콜백을 따로 만들어주는 이유가 무엇인가요? 위 예제코드를 보면. getCurNumber()메소드를 1초마다 호출시키면 그것도 콜백이 되지 않나요? IServiceCallback을 만들어주는 이유가 궁금합니다.

  • 작성자 15.03.04 18:55

    안녕하세요.

    getCurNumber은 함수의 리턴으로 받는 방법입니다.

    그런데 이 경우는 getCurNumber 처리가 빠르지만
    굉장히 느린 함수고 언제 작업이 끝날지 모른다고 하면,
    무작정 해당 함수의 리턴을 기다릴수 없습니다.
    제가 하려는 말은 바로 비동기 처리가 필요한 경우입니다.
    이때 바로 콜백 리스너를 등록하는 것입니다.
    즉 서비스에서 작업이 끝나면 해당 리스너를 호출해주는 것이죠.

    많은 앱을 개발하다보면 콜백 리스너는 매우 많이 사용됩니다.
    (비동기 처리가 대부분 필요하니까요.)
    꼭 이 장의 서비스의 기능이 아닌것이죠.
    단지 서비스도 콜백 리스너를 지원한다 입니다.

    수고하세요.

  • 15.03.23 10:36

    안녕하세요. 궁금한 것이 있는데요. 서비스 관련 첫번째 강의를 보면
    "그렇다 Service는 서로 다른 Process에서도 해당 기능을 사용할 수 있도록 하는 구조를 제공한다."

    서비스를 이용하면 다른 프로세스 상에서 실행되는 서비스(내 함수)도 쉽게 접근 가능하다고 생각했는데,
    여기서는 AIDL을 써서 접근을 해야한다고 설명하셨습니다.
    무슨 차이인지 궁금합니다..

  • 15.03.26 23:38

    성근님 제가 궁금해하던부분이 여기있었네요 aidl 콜백.. 많이 배우고 갑니다

  • 15.03.26 23:44

    추가적으로 server 역활을 하는 service가 갑자기 kill되고, 그 kill된 service를 client에서 알지못하는 경우가 종종 생기는데요 그럴경우 oncallbackdied의 설명도 추가 해주셨으면 좋겠습니다~

  • 15.03.27 08:55

    아~ 죄송, 책에는 써져있네요~

  • 15.05.28 20:02

    안녕하세요. 질문드릴사항이 있습니다.
    RemoteCallbackList에 등록된 client 중 일부를 선택해서 callback을 할 수 있나요?
    예를들어 server에 client1, client2, client3이 등록되어 있을 시
    특정 상황에서 client2로만 callback해주고 싶습니다.
    getbroadcastitem으로 client(app)을 식별해서 callback하는
    방법은 어떻게 해야할지 감이 안오네요.

  • 작성자 15.05.29 19:03

    안녕하세요.

    이는 cookie를 이용하시면 됩니다.
    위의 질문과 제가 단 답변으로 보면 그 내용이 있습니다.
    수고하세요.

  • 15.05.29 15:29

    callback 할 대상이 2개 이상일 경우는 어떻게 하나요? 각각 aidl을 만들어야하는가요?

  • 작성자 15.05.29 19:06

    네 따로 만드셔도 되고,

    아니면 콜백 인터페이스 클래스에
    여러개의 핸들러 함수를 등록해서 사용하셔도 되겠네요.

    예를 들어
    interfce ICountServiceCallback
    {
    void onCountChanged();

    void on1()
    void on2()
    ...
    원하는 만큼 타입 추가
    }

    수고하세요.

  • 15.07.24 08:24

    처음이라 완벽하게 숙지는 못했지만 두고두고 봐서 완벽하게 숙지할 생각입니다.
    정말 알찰내용이네요!! 자료 감사합니다!!!!

  • 작성자 15.08.24 15:32

    감사합니다

  • 15.08.21 15:49

    같은 이름의 서비스를 다른 액티비티에서 bindservice 두번 이상 하게되면 bindservice 할때마다 다른 process에서 돌아가나요? 아니면 하나만 계속 도나요?

  • 작성자 15.08.24 15:34

    서비스는 여러개가 실행되지 않습니다.
    동일한 앱이든 다른 앱이든 여러번 바인드 하더라도 기존 실핼된 서비스에 하나에 바인딩됩니다.

    수고하세요 ^^

  • 15.09.17 19:58

    @슈퍼성근 안녕하세요~ 답변 감사합니다. 한가지 문의사항있습니다.

    서비스를 bindservice로 구현했는데 이 서비스가 background에서 돌아가길 원합니다.
    즉 앱이 destory될때 unbind를 하지 않고싶은겁니다. (unbind는 특정 버튼을 눌렀을 경우에만)
    일반적으로 bind서비스를 unbind하지 않으면 앱이 destroy될때
    "has leaked ServiceConnection that was originally bound here" 라는 에러를 호출하더군요.

    검색을 해도 잘 안나오고..
    어느분은
    startservice 후에 bindservice하면된다고 하는데 그렇게 해도 앱이 destory되면 똑같은 에러가 나오더군요.

  • 15.09.17 19:59

    @슈퍼성근 어떤 라이브러리에서는 bind후에 unbind하지 않고 앱을 destory해도 위와같은 에러가 나오지 않더라구요.

    어떻게하면되는지 궁금합니다.

  • 15.11.06 15:14

    설명 끝판왕 이네요! 잘 보고 잘 이해하고 갑니다. :)

최신목록