1. 程式人生 > >繫結本地service並與之通訊

繫結本地service並與之通訊

如果Service和訪問者之間需要進行呼叫或者資料交換,則應該則應該使用bindService()和unbindService()方法,啟動.關閉service.
Context 的 boolean bindService (Intent service, ServiceConnection conn, int flags) :該方法的3個引數解釋如下: 

  1. service: 該引數通過Intent 指定要啟動的service.
  2. conn : 該引數是一個 ServiceConnection 物件,該物件用於監聽訪問者與service之間的連線情況.當訪問者與service 之間連線成功時將呼叫該 ServiceConnection物件的 onServiceConnected(ComponentName name,IBinder service) 方法,當service所在的宿主程序由於異常終止或由於其他原因終止,導致該Service與訪問者之間斷開連線時回撥該 ServiceConnection 物件的 onServiceDisconnected(ComponentName name)方法.
  3. flags : 指定繫結時是否自動建立Service(如果 service還未建立),該引數可指定為0(不自動建立),或 BIND_AUTO_CREATE (自動建立).

注意到 ServiceConnection物件的onServiceConnected方法中有一個 IBinder 物件,該物件即可實現被繫結service之間的通訊.
當開發service類時,該 service類必須提供一個IBinder onBind(Intent intent),方法.在繫結本地service的情況下, onBind(Intent intent)方法所返回的 IBinder 物件將會傳給ServiceConnection物件的 onServiceConnected(ComponentName name,IBinder service) 方法的service引數,這樣訪問者就可通過該 IBinder 物件與service進行通訊.

實際上開發時通常採用繼承Binder(IBinder 的實現類)的方式實現自己的IBinder 物件.

BindService繫結服務

package com.test.service.bindservice;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

/**
 * 示範 如何在Activity中繫結本地Service,並獲取Service執行狀態.
 */
public class BindService extends Service { private int count; private boolean quit; //定義 onBinder 方法所返回的物件 private MyBinder binder = new MyBinder(); public class MyBinder extends Binder { public int getCount(){ //獲取 service的執行狀態 return count; } } public BindService() { } @Override //必須實現的方法,繫結 該service時回撥該方法 public IBinder onBind(Intent intent) { Log.d("BindService", "onBind 繫結"); return binder; } @Override //建立 service時回撥該方法 public void onCreate() { super.onCreate(); Log.d("BindService", "onCreate"); //開啟新執行緒 動態的修改 count狀態值 new Thread(){ @Override public void run() { while (!quit){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } count++; } } }.start(); } @Override //Service 被斷開連線時回撥該方法 public boolean onUnbind(Intent intent) { Log.d("BindService", "onUnbind 解綁"); return true; } @Override //service 被關閉之前呼叫 public void onDestroy() { super.onDestroy(); this.quit = true; Log.d("BindService", "onDestroy 銷燬"); } }
package com.test.service.bindservice;

import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.test.service.R;

public class BindServiceActivity extends AppCompatActivity {
    Button btnBind, btnUnBind, btnStatus;

    //保持所啟動的service 的 IBinder物件
    BindService.MyBinder mBinder;

    //定義一個 ServiceConnection 物件
    private ServiceConnection conn = new ServiceConnection() {

        //當activity與 service連線成功時回撥
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("BindServiceActivity", "onServiceConnected 連線成功");

            //獲取 service中的  onBind方法返回的 MyBinder 物件
            mBinder = (BindService.MyBinder) service;
        }

        //當activity與 service斷開連線時回撥
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d("BindServiceActivity", "onServiceDisconnected 斷開連線");
        }
    };

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

        btnBind = (Button) findViewById(R.id.button4);
        btnUnBind = (Button) findViewById(R.id.button5);
        btnUnBind.setEnabled(false);
        btnStatus = (Button) findViewById(R.id.button6);

        //建立啟動 vice的 Intent
        final Intent intent = new Intent();
        intent.setAction("com.test.service.BIND_SERVICE");
        intent.setPackage(this.getPackageName());    //相容Android 5.0

        btnBind.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //繫結service
                bindService(intent, conn, Service.BIND_AUTO_CREATE);
                btnUnBind.setEnabled(true);
            }
        });

        btnUnBind.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //解除繫結 service
                unbindService(conn);
            }
        });
        btnStatus.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //獲取並顯示 service 的count
                Toast.makeText(BindServiceActivity.this, "service的count值: " + mBinder.getCount(), Toast.LENGTH_SHORT).show();
            }
        });
    }
}