android: 活動和服務進行通訊

9.3.3    活動和服務進行通訊android

 上一小節中咱們學習了啓動和中止服務的方法,不知道你有沒有發現,雖然服務是在活 動裏啓動的,但在啓動了服務以後,活動與服務基本就沒有什麼關係了。確實如此,咱們在 活動裏調用了 startService()方法來啓動 MyService 這個服務,而後 MyService 的 onCreate()和 onStartCommand()方法就會獲得執行。以後服務會一直處於運行狀態,但具體運行的是什麼 邏輯,活動就控制不了了。這就相似於活動通知了服務一下:「你能夠啓動了!」而後服務就 去忙本身的事情了,但活動並不知道服務到底去作了什麼事情,以及完成的如何。ide

那麼有沒有什麼辦法能讓活動和服務的關係更緊密一些呢?例如在活動中指揮服務去 幹什麼,服務就去幹什麼。固然能夠,這就須要藉助咱們剛剛忽略的 onBind()方法了。佈局

好比說目前咱們但願在 MyService 裏提供一個下載功能,而後在活動中能夠決定什麼時候開 始下載,以及隨時查看下載進度。實現這個功能的思路是建立一個專門的 Binder 對象來對下 載功能進行管理,修改 MyService 中的代碼,以下所示:學習

 

public class MyService extends Service {測試

 

 

private DownloadBinder mBinder = new DownloadBinder();this

 

 

class DownloadBinder extends Binder {spa

 

 public void startDownload() {日誌

Log.d("MyService", "startDownload executed");xml

}對象

 

 

public int getProgress() {

Log.d("MyService", "getProgress executed");

return 0;

}

 

} 

 

@Override

public IBinder onBind(Intent intent) {

return mBinder;

}

 

……

 

 

}

能夠看到,這裏咱們新建了一個 DownloadBinder 類,並讓它繼承自 Binder,而後在它 的內部提供了開始下載以及查看下載進度的方法。固然這只是兩個模擬方法,並無實現真 正的功能,咱們在這兩個方法中分別打印了一行日誌。

接着,在 MyService 中建立了 DownloadBinder 的實例,而後在 onBind()方法裏返回了這 個實例,這樣 MyService 中的工做就所有完成了。

下面就要看一看,在活動中如何去調用服務裏的這些方法了。首先須要在佈局文件裏新 增兩個按鈕,修改 activity_main.xml 中的代碼,以下所示:

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"

android:orientation="vertical" >

……

 

<Button android:id="@+id/bind_service" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Bind Service" />

 

<Button android:id="@+id/unbind_service" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Unbind Service" />

</LinearLayout>

這兩個按鈕分別是用於綁定服務和取消綁定服務的,那到底誰須要去和服務綁定呢?當 然就是活動了。當一個活動和服務綁定了以後,就能夠調用該服務裏的 Binder 提供的方法了。 修改 MainActivity 中的代碼,以下所示:

 public class MainActivity extends Activity implements OnClickListener {

 

 

private Button startService; private Button stopService; private Button bindService; private Button unbindService;

private MyService.DownloadBinder downloadBinder;

 

 

private ServiceConnection connection = new ServiceConnection() {

 

 

@Override

public void onServiceDisconnected(ComponentName name) {

}

 

 

@Override

public void onServiceConnected(ComponentName name, IBinder service) { downloadBinder = (MyService.DownloadBinder) service; downloadBinder.startDownload();

downloadBinder.getProgress();

}

};

 

@Override

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

……

bindService = (Button) findViewById(R.id.bind_service); unbindService = (Button) findViewById(R.id.unbind_service); bindService.setOnClickListener(this);

unbindService.setOnClickListener(this);

}

 

 

@Override

public void onClick(View v) {

switch (v.getId()) {

 

 

 

……

case R.id.bind_service:

Intent bindIntent = new Intent(this, MyService.class);

bindService(bindIntent, connection, BIND_AUTO_CREATE); // 綁定服務

break;

case R.id.unbind_service:

unbindService(connection); // 解綁服務

break;

default:

break;

}

}

 

}

能夠看到,這裏咱們首先建立了一個 ServiceConnection 的匿名類,在裏面重寫了 onServiceConnected()方法和 onServiceDisconnected()方法,這兩個方法分別會在活動與服務 成功綁定以及解除綁定的時候調用。在 onServiceConnected()方法中,咱們又經過向下轉型 獲得了 DownloadBinder 的實例,有了這個實例,活動和服務之間的關係就變得很是緊密了。 如今咱們能夠在活動中根據具體的場景來調用 DownloadBinder 中的任何 public 方法,即實 現了指揮服務幹什麼,服務就去幹什麼的功能。這裏仍然只是作了個簡單的測試,在 onServiceConnected()方法中調用了 DownloadBinder 的 startDownload()和 getProgress()方法。

固然,如今活動和服務其實還沒進行綁定呢,這個功能是在 Bind Service 按鈕的點擊事 件裏完成的。能夠看到,這裏咱們仍然是構建出了一個 Intent 對象,而後調用 bindService() 方法將 MainActivity 和 MyService 進行綁定。bindService()方法接收三個參數,第一個參數就 是剛剛構建出的 Intent 對象,第二個參數是前面建立出的 ServiceConnection 的實例,第三個 參數則是一個標誌位,這裏傳入 BIND_AUTO_CREATE 表示在活動和服務進行綁定後自動 建立服務。這會使得 MyService 中的 onCreate()方法獲得執行,但 onStartCommand()方法不 會執行。

而後若是咱們想解除活動和服務之間的綁定該怎麼辦呢?調用一下 unbindService()方法 就能夠了,這也是 Unbind Service 按鈕的點擊事件裏實現的功能。

如今讓咱們從新運行一下程序吧,界面如圖 9.9 所示。

 

圖   9.9

 

點擊一下 Bind Service 按鈕,而後觀察 LogCat 中的打印日誌如圖 9.10 所示:

 

圖   9.10

 

能夠看到,首先是 MyService 的 onCreate() 方法獲得了執行,而後 startDownload() 和getProgress()方法都獲得了執行,說明咱們確實已經在活動裏成功調用了服務裏提供的方法了。 另外須要注意,任何一個服務在整個應用程序範圍內都是通用的,即 MyService 不只可以和 MainActivity 綁定,還能夠和任何一個其餘的活動進行綁定,並且在綁定完成後它們都 能夠獲取到相同的 DownloadBinder 實例。

相關文章
相關標籤/搜索