2012-05-11 1 views
6

나는 서비스 (즉,하지 같은 맥락에서) 쉽게 원격으로 Activity에서 메시지를 통해 통신 할 수 있다는 것을 보여하지만 서비스에서 메시지를 보낼 수있는 방법이있는 documentation about Bound Services을 읽었습니다 에 바운드 활동? 예를 들어, 내 액티비티는 동일한 애플리케이션의 실행중인 백그라운드 서비스에 국한되어 메시지를 전송하고이 메시지를 받으면 서비스가 메시지에 응답합니다. 어떻게 구현합니까? 이 주제를 설명하는 문서를 가르쳐 주시겠습니까?원격 서비스가 바운드 활동에 메시지를 보내려면 어떻게해야합니까?

답변

4

참조 설명서의 찾을 수있는 예제는 Remote Messenger Service Sample입니다.

+0

원격 서비스 바인딩이 필요한 실제 상황이 있습니까? –

25

참고 :이 질문은 질문과 같은 원격 서비스가 아니라 in-process 서비스 및 활동에만 해당됩니다.

서비스를 사용하여 활동과 통신하려면 활동에서 서비스에 전달할 수있는 리스너를 작성해야합니다.

활동에 바인딩 된 서비스를 만들어야합니다.

첫 번째 단계는 서비스를 만드는 것입니다. 이 서비스에서 바인더 객체와 바인더 객체를 반환하는 메소드가 있는지 확인하십시오. 다음은 내 서비스에서 바인더를 검색하는 데 사용한 예입니다. 또한이 바인더에는 BoundServiceListener 유형 필드로 서비스에 저장 될 리스너를 설정하는 메소드가 있습니다.

/** 
* Class used for the client Binder. Because we know this service always 
* runs in the same process as its clients, we don't need to deal with IPC. 
*/ 
public class DownloadBgBinder extends Binder { 

    public DownloadBgService getService() { 
     // Return this instance of LocalService so clients can call public methods 
     return DownloadBgService.this; 
    } 

    public void setListener(BoundServiceListener listener) { 
     mListener = listener; 
    } 
} 

@Override 
public IBinder onBind(Intent intent) { 
    return mBinder; 
} 

지금 당신은 당신이 당신의 서비스에 업데이트를 보내는 데 사용할 수있는 바인더 객체에 전달할 수있는 인터페이스의 어떤 종류를 만들어야합니다. 아래는 BoundServiceListener입니다.

public interface BoundServiceListener { 

    public void sendProgress(double progress); 
    public void finishedDownloading(); 
} 

이제 활동에 서비스 바인딩에 사용되는 ServiceConnection 개체를 만들어야합니다. 이렇게 뭔가를 추가하십시오.

/** Defines callbacks for service binding, passed to bindService() */ 
private ServiceConnection mConnection = new ServiceConnection() { 

    @Override 
    public void onServiceDisconnected(ComponentName arg0) { 
     mBound = false; 
    } 

    @Override 
    public void onServiceConnected(ComponentName name, IBinder service) { 
     // We've bound to LocalService, cast the IBinder and get LocalService instance 
     DownloadBgBinder binder = (DownloadBgBinder) service; 
     mService = binder.getService(); 
     binder.setListener(new BoundServiceListener() { 

      @Override 
      public void sendProgress(double progress) { 
       // Use this method to update our download progress 
      } 

      @Override 
      public void finishedDownloading() { 

      } 
     }); 

     mBound = true; 
    } 

지금 여기에서 주목해야 할 핵심 라인은 실제로 서비스 클래스에 내 BoundServiceListener 인터페이스를 보내고 곳이 제품은

binder.setListener(new BoundServiceListener() { 

    @Override 
    public void sendProgress(double progress) { 
     // Use this method to update our download progress 
    } 

    @Override 
    public void finishedDownloading() { 

    } 
}); 

입니다. 서비스 클래스는 다음 지금이 어느 곳에서든지 당신이 당신의 서비스 클래스에 필요 넣을 수 있습니다 여기

if (mListener!=null) 
     mListener.finishedDownloading(); 
    if (mListener!=null) 
     mListener.sendProgress(percent); 

그 리스너 객체를 사용하고, 활동 진행 상황 업데이트를 받게됩니다.

서비스를 실제로 바인딩하고 시작하려면 활동에 다음을 포함해야합니다.

Intent intent = new Intent(this, DownloadBgService.class); 
startService(intent); 
bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 

서비스에 바인딩하더라도 시작 서비스를 호출 할 때까지 서비스가 실제로 시작되지 않습니다. 서비스에 바인딩하면 서비스가 활동에 연결됩니다.startService() 메소드는 또한 당신의 서비스를 선언하는 서비스

onStartCommand(Intent intent, int flags, int startId) 

를 호출 매니페스트

<service android:name=".services.DownloadBgService" /> 

활동이 도움이

@Override 
protected void onStop() { 
    super.onStop(); 
    // Unbind from the service 
    if (mBound) { 
     unbindService(mConnection); 
     mBound = false; 
    } 
} 

희망으로 떠날 때 또한 서비스 바인딩을 해제.

+1

좋은 예를 들어, 개념을 설명하는 데 많은 시간을 할애 해 주셔서 감사합니다. –

+0

@Danuofr이 작업 과정에서 작동합니다. 프로세스 경계를 ​​넘어 임의의 수신기를 보내는 방법이 있습니까? – dcow

+2

이 답변의 문제점은 다음과 같습니다. 로컬 서비스에만 해당됩니다. 그러나 원격 서비스를 사용하여이를 수행하는 방법에 대한 질문이 명확하게 제기됩니다. 그러나 이것을 작성해 주셔서 감사합니다. 하지만 어쩌면 이것이 진짜 질문에 대한 대답이 아니라는 점에 유의하십시오. –