Service
什麼是Service
Service是一個可以在後臺執行長時間操作而不使用用戶界面的應用組件。
如何使用Service
我們首先需要實現一個Service的子類。主要實現Service的onCreat(),onStartCommand(),onBind(),onDesroy(),其中onBind()只有在需要與activity有交互的時候纔會調用。由於很多時候我們需要在service中進行許多比較耗時的操作,所以我們常常需要在其中開啓子線程,因爲每次都需要在線程任務執行之後去調用stopSelf()。
Service與Activity通信
從上面的生命週期,可以看出,當用startService()來啓動一個Service的時候,這個服務的執行就不再受到控制,爲了與某個服務通信,我們可以使用bindService()來啓動一個Service。Google的例子如下:
public class MyService extends Service {
private static final String TAG = "MyService";
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
//當其他組件調用bindService()方法時,此方法將會被調用
//然後返回一個Binder對象
//如果不想讓這個service被綁定,在此返回null即可
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind");
LocalBinder binder = new LocalBinder();
return binder;
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy");
//service調用的最後一個方法
//在此進行資源的回收
super.onDestroy();
}
/** method for clients */
public int getRandomNumber() {
return mGenerator.nextInt(100);
}
/**
* 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 {
MyService getService() {
// Return this instance of LocalService so clients can call public methods
return MyService.this;
}
}
}
使用bindService()和startService()的最大區別就是對於Service中的onBind()實現,當執行到這一步的時候會返回一個Binder對象,這個就是開始與Service通信的節點。
public class MyActivity extends Activity {
LocalService mService;
boolean mBound = false;
/** 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;
}
};
@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();
}
}
}
通過上面的代碼我們可以看出,執行bindService()需要是三個參數,一個是intent,一個是ServiceConnection,第三個是一個flag,一般使用BIND_AUTO_CREATE。而Activity與Service的通信主要就是通過這個對象來實現的,我們可以很容易的看出其中兩個函數的作用,在Activity與Service執行bind的時候,會將Service中onBind()返回的Binder對象,我們可以通過onServiceConnected()持有它的一個引用,這樣我們就可以通過它與Service內部進行通信了。