onCreate()方法只會在Service第一次被創(chuàng)建的時候調用凤价,如果當前Service已經被創(chuàng)建過了歹叮,不管怎樣調用startService()方法译秦,onCreate()方法都不會再執(zhí)行。
Service和Activity通信
Activity通過binder來啟動或停止service中的任務砾省,并監(jiān)聽service中任務的進度蠕啄。代碼如下:
OnProgressListener
public interface OnProgressListener {
void onProgress(int progress);
}
MyService
public class MyService extends Service {
private final String TAG = "MyService";
private int progress = 0;
private MyBinder mBinder = new MyBinder();
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate() executed");
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.d(TAG, "onStart() executed");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand() executed");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy() executed");
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
Log.d(TAG, "onUnbind() executed");
return super.onUnbind(intent);
}
class MyBinder extends Binder {
/**
* 更新進度的回調接口
*/
private OnProgressListener onProgressListener;
public void startDownload() {
Log.d(TAG, "startDownload() executed");
// 執(zhí)行具體的下載任務
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
progress++;
//進度發(fā)生變化通知調用方
if (onProgressListener != null) {
onProgressListener.onProgress(progress);
}
}
}
public void stopDownload() {
Log.d(TAG, "stopDownload() executed");
// 執(zhí)行具體的下載任務
}
/**
* 注冊回調接口的方法场勤,供外部調用
*
* @param onProgressListener
*/
public void setOnProgressListener(OnProgressListener onProgressListener) {
this.onProgressListener = onProgressListener;
}
}
}
MainActivity中
public class MainActivity extends AppCompatActivity {
MyService.MyBinder myBinder = null;
Button btn_start,btn_stop;
private String Tag = "MyService";
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder = (MyService.MyBinder) service;
myBinder.setOnProgressListener(new OnProgressListener() {
@Override
public void onProgress(int progress) {
Log.i(Tag,"progress: "+progress);
}
});
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_start = (Button)findViewById(R.id.btn_start);
btn_stop = (Button)findViewById(R.id.btn_stop);
Intent bindIntent = new Intent(this, MyService.class);
bindService(bindIntent, connection, BIND_AUTO_CREATE);
btn_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myBinder.startDownload();
}
});
btn_stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myBinder.stopDownload();
}
});
}
}
bindService和startService的區(qū)別
- 生命周期的區(qū)別:
startService,【onCreate()- >onStartCommand()->startService()->onDestroy()】
補充說明:其中沒有onStart()歼跟,主要是被onStartCommand()方法給取代了和媳,onStart方法不推薦使用了;
bindService()哈街,【onCreate()->onBind()->onUnbind()->onDestroy()】
補充說明:傳遞給bindService()的Intent對象會傳遞給onBind()留瞳,傳遞給unbindService()的Intent對象會傳遞給onUnbind()方法。調用順序為:onCreate --> onBind(只一次骚秦,不可多次綁定) --> onUnbind --> onDestory她倘。 - 調用者和服務者之間的關系:
startService()的調用,調用者和服務之間沒有聯(lián)系作箍,即使調用者退出了硬梁,服務依然在進行。
bindService()調用者和綁定者綁在一起蒙揣,調用者一旦退出服務也就終止了靶溜。
注意:BroadcastReceiver只能通過startService啟動Service,因為廣播本身生命周期很短懒震,bind的話沒有意義。 - 關于多次調用:
多次調用startService嗤详,該Service只能被創(chuàng)建一次个扰,即該Service的onCreate方法只會被調用一次。但是每次調用startService葱色,onStartCommand方法都會被調用递宅。Service的onStart方法在API 5時被廢棄,替代它的是onStartCommand方法苍狰。
第一次執(zhí)行bindService時办龄,onCreate和onBind方法會被調用,但是多次執(zhí)行bindService時淋昭,onCreate和onBind方法并不會被多次調用俐填,即并不會多次創(chuàng)建服務和綁定服務。 - 既使用startService又使用bindService的情況
如果一個Service又被啟動又被綁定翔忽,則該Service會一直在后臺運行英融。首先不管如何調用盏檐,onCreate始終只會調用一次。對應startService調用多少次驶悟,Service的onStartCommand方法便會調用多少次胡野。Service的終止,需要unbindService和stopService同時調用才行痕鳍。不管startService與bindService的調用順序硫豆,如果先調用unbindService,此時服務不會自動終止笼呆,再調用stopService之后熊响,服務才會終止;如果先調用stopService抄邀,此時服務也不會終止耘眨,而再調用unbindService或者之前調用bindService的Context不存在了(如Activity被finish的時候)之后,服務才會自動停止境肾。
那么剔难,什么情況下既使用startService,又使用bindService呢奥喻?
如果你只是==想要啟動一個后臺服務長期進行某項任務同時還想要與正在運行的Service取得聯(lián)系偶宫,那么有兩種方法:一種是使用broadcast,另一種是使用bindService环鲤。前者的缺點是如果交流較為頻繁纯趋,容易造成性能上的問題,而后者則沒有這些問題冷离。因此吵冒,這種情況就需要startService和bindService一起使用了。
另外西剥,如果你的服務只是公開一個遠程接口痹栖,供連接上的客戶端(Android的Service是C/S架構)遠程調用執(zhí)行方法,這個時候你可以不讓服務一開始就運行瞭空,而只是bindService揪阿,這樣在第一次bindService的時候才會創(chuàng)建服務的實例運行它,這會節(jié)約很多系統(tǒng)資源咆畏,特別是如果你的服務是遠程服務南捂,那么效果會越明顯(當然在Servcie創(chuàng)建的是偶會花去一定時間,這點需要注意) - 銷毀 service
Bind Service -> Unbind Service
Start Service -> Stop Service
Bind Service + Start Service -> Unbind Service + Stop Service(無順序區(qū)別)
==注意點==
onServiceDisconnected 會在程序意外退出時才會調用