兩種啟動模式核心區別
| 特性 | startService | bindService |
| 啟動方式 | Context.startService(Intent) | Context.bindService(Intent, ServiceConnection, flags) |
| 生命周期 | onCreate → onStartCommand → running → onDestroy | onCreate → onBind → running → onUnbind → onDestroy |
| 調用者關係 | 無綁定,調用者退出 Service 繼續運行 | 綁定關係,調用者退出 Service 自動停止 |
| 通信方式 | Intent 傳遞數據,單向 | IBinder 接口,雙向通信 |
| 多次調用 | 多次 onStartCommand,單例 onCreate | 多次 bind 只觸發一次 onBind |
| 停止方式 | stopService / stopSelf | unbindService (最後一個解綁時停止) |
模式一:startService (獨立後台任務)
// 啟動
Intent intent = new Intent(this, MyService.class);
startService(intent);
// Service 實現
public class MyService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 處理任務
return START_STICKY; // 被殺後自動重啟
}
@Override
public IBinder onBind(Intent intent) { return null; } // 不支持綁定
public void stopSelf() { stopSelf(); }
}
// 停止
stopService(new Intent(this, MyService.class));
模式二:bindService (客戶端-服務端雙向通信)
// 綁定
Intent intent = new Intent(this, MyService.class);
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyService.LocalBinder binder = (MyService.LocalBinder) service;
myService = binder.getService(); // 獲取服務實例
// 現在可以直接調用 myService.publicMethod()
}
@Override
public void onServiceDisconnected(ComponentName name) {
myService = null;
}
};
bindService(intent, conn, Context.BIND_AUTO_CREATE);
// Service 實現
public class MyService extends Service {
private final IBinder binder = new LocalBinder();
public class LocalBinder extends Binder {
MyService getService() { return MyService.this; }
}
@Override
public IBinder onBind(Intent intent) { return binder; }
// 業務方法可直接被調用端調用
public String getStatus() { return "Running..."; }
}
// 解綁
unbindService(conn);
混合模式:同時支持啟動與綁定
public class HybridService extends Service {
private boolean isStarted = false;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
isStarted = true;
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return binder;
}
@Override
public boolean onUnbind(Intent intent) {
// 所有客戶端解綁後,若非 started 模式則停止
return isStarted; // true 表示保持運行
}
}
選型指南
- 音樂播放/下載/同步 → startService (獨立後台任務)
- 即時通訊/位置共享/傳感器監聽 → bindService (頻繁雙向交互)
- 複雜業務 → 混合模式 (既要後台運行又要交互)
Android 8.0+ 前台服務適配
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("服務運行中")
.setContentText("點擊查看")
.setSmallIcon(R.drawable.ic_service)
.build();
startForeground(1, notification);
}