2012-05-11 73 views
6

我已閱讀documentation about Bound Services,其中顯示您可以通過消息從活動很容易地通信到遠程(即不在同一上下文中)服務,但有什麼方法可以從服務發送消息服務裝訂活動?例如,我的活動綁定到同一個應用程序的正在運行的後臺服務,向它發送一條消息,並在接收到此消息時服務將回復一條消息給該活動。如何實現此操作?你能指出我解釋這個話題的一些文件嗎?遠程服務如何將消息發送到綁定的活動?

回答

25

注意:這僅適用於進程內服務和活動,而不是遠程問題。

使用服務與活動進行通信涉及創建一個可以從活動傳遞給服務的偵聽器。

您需要創建一個綁定到活動的服務。

第一步是提供服務。在服務中確保你有一個Binder對象和返回一個活頁夾對象的方法。以下是我在服務中用於檢索活頁夾的示例。另外請注意,這個綁定器有一個方法來設置一個監聽器,它將作爲一個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; 
    } 

現在,這裏要注意的關鍵線路

binder.setListener(new BoundServiceListener() { 

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

    @Override 
    public void finishedDownloading() { 

    } 
}); 

這個地區是我居然送我BoundServiceListener接口的服務類。服務類,然後使用此處

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

此答案唯一的問題是:它只適用於本地服務。但問題清楚地問到如何用遠程服務來做到這一點。但是,無論如何謝謝你寫這篇文章。但也許請注意,這不是真正的問題的答案:) –

相關問題