Bound Service 之 Binder

Service 是一個可以長久運行在後臺不能提供用戶界面的一個組件。程序的其他組件可以啓動service,service可以在後臺運行即便用戶切換了應用程序。一個組件可以綁定一個service並且可以和它交互甚至在進程間交互。例如:請求網絡,播放音樂、I/O、或者和contentprovider交互,所有這一切都是在後臺進行的。

  service大致可以有兩種方式存在。

  •   started:startService

   一旦啓它,理論上它就可以在後臺無限期運行了,即便是啓動它的組件退出了它仍然存在。通常,啓動一個service都是一個單獨的操作過程,不會返回調用者結果。當操作完成,service應當自己退出:stopSelf()。

  • bound:bindsService
應用組件可以通過調用bindService()方法綁定一個service。一個被綁定的service會提供一個client-service的接口供綁定者調用,發生請求,獲取結果,甚至做一些跨進程的交互。bound的service的運行週期和綁定它的組件一樣長。多個組件可以同時綁定一個service,當所有的組件都解除綁定之後service才退出。
  

無論使用哪種方式的service,started,bound或兩個一起,其他應用組件都可以使用它,甚至是另一個應用的組件也可以使用它。你也可以聲明你的service爲私有的。

注意:一個service運行在它所附屬的進程的主線程中,service不會創建線程也不會運行在一個獨立的進程中(除非你特別制定)。這意味着如果你的service要做一些影響cpu的操作,你應該創建一個新的線程去工作。

一個 boundService 是一個client-server的接口。一個boundService只有在它鄉另一個應用組件提供服務的時候才活着,它並不是永久運行在後臺的。

  • 基本架構:
 客戶端client使用bindService()方法綁定service,client必須實現ServiceConnection接口,bindService()方法並不會返回值,但是Android系統會在client和service之間建立一個鏈接,當連連成功會調用onServiceConnected()方法,並傳遞一個IBinder對象,通過IBinder對象和service通信。
 多個client可以同時綁定service,但是系統並不會再次調用service的onBind()方法了,只有第一個調用的時候纔會回調。系統會傳遞同一個IBinder到後來的client。當最後一個client解綁service後系統會銷燬這個service,除非service已經被started了。

start 方式比較簡單,所以這裏重點介紹Bound Service 。Bound Service 第一部分:本地Binder方式。

  • 擴展Binder

如果你的service僅僅服務於本地應用不需要跨進程服務,你可以選擇這種方式。

實現步驟:
1.創建一個Binder對象
2. Binder提供一個公用方法獲取當前service
3.當前service提供公用方法供client使用

    public class LocalService extends Service {
    // Binder given to clients
    private final IBinder mBinder = new LocalBinder();
    // Random number generator
    private final Random mGenerator = new Random();

    /**
     * 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 LocalBinder extends Binder {
        LocalService getService() {
            // Return this instance of LocalService so clients can call public methods
            return LocalService.this;
        }
    }

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

    /** method for clients */
    public int getRandomNumber() {
      return mGenerator.nextInt(100);
    }
}

然後你的Activity綁定這個服務:


public class BindingActivity extends Activity {
    LocalService mService;
    boolean mBound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Bind to LocalService
        Intent intent = new Intent(this, LocalService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

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

    /** Called when a button is clicked (the button in the layout file attaches to
      * this method with the android:onClick attribute) */
    public void onButtonClick(View v) {
        if (mBound) {
            // Call a method from the LocalService.
            // However, if this call were something that might hang, then this request should
            // occur in a separate thread to avoid slowing down the activity performance.
            int num = mService.getRandomNumber();
            Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
        }
    }

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

        @Override
        public void onServiceConnected(ComponentName className,
                IBinder service) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            mBound = true;
        }

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

Bound Service 之本地Binder簡單介紹道這裏了,下篇文章介紹Bound Service的第二種方式:《Bound Service 之 Messenger》

文章參考:http://developer.android.com/guide/components/bound-services.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章