Android startservice & bindservice的區別

Android startservice & bindservice的區別

作爲一個android開發者,service大家應該已經接觸過了,接觸Android的第一節課,就是將Android的四大組件,那麼作爲四大組件之一的service,你是否足夠了解呢?

  1. service和thread的區別你是否知道?service真的能執行長時間的後臺操作麼?

  2. 你是否知道startservice和bindservice的區別呢?

  3. service的生命週期,我們是否應該主動結束一個service呢?service是否會導致內存泄露呢?

  4. service與intentservice的區別是什麼?

上邊是關於service的一些問題,問題1,我們已經在之前的博客上講解過,詳細內容見博客http://blog.csdn.net/u014088294/article/details/49907385

關於問題4,也可以參考我們之前的文章 ,http://blog.csdn.net/u014088294/article/details/44279399

我們主要解答問題2,startservice與bindservice的區別。

Developer上提到,service主要有兩種形式,

  1. started
  2. bound

上邊的started呢,對應與startservice,bound對應於bindservice,他們都是啓動service的方式。

startservice

我們可以通過startservice來啓動一個service,啓動後,service在後臺運行。通常來說,該service是無法返回結果的(這也是與bindservice的區別之一),比如我們可以下載一個文件。
和startservice對應的是stopservice,我們可以來顯式的結束一個service。
service的生命週期也比較簡單,和startservice相關的有三個函數,分別是onCreate,onStartCommand,onDestory。

當我們首次startserivce啓動一個service的時候,會調用service的onCreate函數,創建該服務,然後調用onStartCommand函數,執行操作。如果我們多次通過startservice啓動服務,那麼onCreate只會調用一次,直接調用onStartCommand
我們可以調用stopsevice來結束一個service。同樣,我們也可以多次調用(第一次調用已經結束,但是後來繼續調用並不會產生異常)。

當一個service通過startservice啓動後,它就獨立於調用者而運行(也就是說,調用者的生命週期和它的生命週期沒有關係),因此呢,service應該在任務完成的時候調用stopSelf函數或者調用者stopservice來結束該服務

Developer上提到,當我們的service執行完的時候,爲了避免消耗系統資源或電量,應該結束該service。否則,該服務將會一直運行在後臺,直到設備內存不足等原因把他關閉掉。

然而,startservice並不能解決我們所有的需求,比如,我有時候,需要service的返回結果,我需要和service交互,startservice顯然不能完成。那麼我們可以使用到bindservice

bindservice

Developer這樣提到,

A bound service offers a client-server interface that allows components to interact with the service, send requests, get results, and even do so across processes with interprocess communication (IPC).

我們可以利用bindservice來和service綁定,綁定後,我們可以和service交互,發送請求,得到結果甚至執行IPC通信。

那麼,我們應該如何使用bindservice呢?

  1. 首先我們需要重載service的onBinder,返回一個IBinder對象。該對象是
    調用者和serivce交互的接口。
  2. 新建一個ServiceConnection變量,該類是監聽Service是否bound的接口,我們重載其onServiceConnected和onServiceDisconnected方法。onServiceConnected方法中,我們得到了Service中onBinder返回的IBinder接口。
  3. 調用bindservice來綁定服務。

按照上邊的步驟,我們的代碼如下,
1. 重載onBinder並返回一個IBinder對象。在LocalBinder中,提供getSercive方法,返回service實例。

    public class LocalBinder extends Binder {
        MyService getService() {
            return MyService.this;
        }
    }

    private final IBinder mBinder = new LocalBinder();

    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "onBind");
        return mBinder;
    }

2.調用者中新建ServiceConnection接口,在onServiceConnected方法中,將IBinder對象轉爲LocalBinder對象,並調用其getService方法,得到Service。

    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            mBoundService = ((MyService.LocalBinder) service).getService();
        }

        public void onServiceDisconnected(ComponentName className) {
              mBoundService = null;
        }
    };

3.調用者執行bindservice,其中mConnection爲ServiceConnection接口。

bindService(new Intent(MainActivity.this,MyService.class), mConnection, Context.BIND_AUTO_CREATE);

當用戶執行bindservice後,bind的結果會回調mConnection接口,若bind成功,就會回調onServiceConnected方法,然後我們在此方法中,得到了Service實例,得到Service實例後,然後我們就可以和Service交互了

我們繼續完善代碼,在Service的onCreate方法中,我們新建一個線程,每隔1s,計數器加1.其中count爲成員變量,表示當前計數值,threadDisable表示是否service關閉。

        new Thread(new Runnable() {
            // @Override
            public void run() {
                while (!threadDisable) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
                    count++;
                    System.out.println("CountService Count is " + count);
                }
            }
        }).start();

然後,我們在Service中新建一個方法,返回計數值。

    public int getCount() {
        return count;
    }

那麼我們在調用者中,就可以利用上邊得到的mBoundService來調用getCount方法,達到與service交互的目的。
項目地址,https://github.com/KingPaul/ServiceDemo

發佈了31 篇原創文章 · 獲贊 15 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章