8.3 KiB
8.3 KiB
Service详解
目录
Service生命周期
普通 Service 生命周期
public class MyService extends Service {
@Override
public void onCreate() {
super.onCreate();
// Service 创建时调用
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Service 启动时调用(startService)
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// Service 绑定时调用(bindService)
return binder;
}
@Override
public void onDestroy() {
super.onDestroy();
// Service 销毁时调用
}
}
绑定 Service 生命周期
// 绑定 Service
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
// 解绑 Service
unbindService(serviceConnection);
// 生命周期
// onCreate() → onBind() → onUnbind() → onDestroy()
Service类型
1. 普通 Service
// 普通 Service:后台执行任务
public class MyService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 执行任务
new Thread(() -> {
// 耗时操作
}).start();
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
2. 前台 Service
// 前台 Service:显示通知
public class ForegroundService extends Service {
@Override
public void onCreate() {
super.onCreate();
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("服务运行中")
.setContentText("正在执行任务")
.setSmallIcon(R.drawable.ic_notification)
.build();
startForeground(1, notification);
}
}
3. 绑定 Service
// 绑定 Service:与 Activity 通信
public class BoundService extends Service {
private IBinder binder = new LocalBinder();
public class LocalBinder extends Binder {
BoundService getService() {
return BoundService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return binder;
}
public void doSomething() {
// Service 方法
}
}
// Activity 中使用
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
BoundService.LocalBinder binder = (BoundService.LocalBinder) service;
boundService = binder.getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
boundService = null;
}
};
IntentService
IntentService 特点
// IntentService:自动在后台线程执行任务
public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
// 在后台线程执行
// 任务执行完毕后自动停止
String action = intent.getAction();
if ("ACTION_DOWNLOAD".equals(action)) {
downloadFile();
}
}
}
// 启动
Intent intent = new Intent(this, MyIntentService.class);
intent.setAction("ACTION_DOWNLOAD");
startService(intent);
IntentService vs Service
| 特性 | Service | IntentService |
|---|---|---|
| 线程 | 主线程 | 后台线程 |
| 自动停止 | 否 | 是 |
| 多任务 | 需要手动处理 | 自动排队 |
| 适用场景 | 需要长期运行 | 一次性任务 |
Service与Activity通信
方式1:Binder
// Service
public class MyService extends Service {
private IBinder binder = new LocalBinder();
public class LocalBinder extends Binder {
MyService getService() {
return MyService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return binder;
}
public void doWork() {
// Service 方法
}
}
// Activity
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyService.LocalBinder binder = (MyService.LocalBinder) service;
myService = binder.getService();
myService.doWork();
}
@Override
public void onServiceDisconnected(ComponentName name) {
myService = null;
}
};
bindService(intent, connection, Context.BIND_AUTO_CREATE);
方式2:BroadcastReceiver
// Service 发送广播
Intent broadcast = new Intent("ACTION_UPDATE");
broadcast.putExtra("data", "value");
sendBroadcast(broadcast);
// Activity 接收广播
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String data = intent.getStringExtra("data");
}
};
registerReceiver(receiver, new IntentFilter("ACTION_UPDATE"));
方式3:Messenger
// Service
public class MessengerService extends Service {
private Messenger messenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
// 处理消息
}
});
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
}
// Activity
private Messenger serviceMessenger;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
serviceMessenger = new Messenger(service);
Message msg = Message.obtain();
msg.what = 1;
msg.obj = "Data";
try {
serviceMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
serviceMessenger = null;
}
};
Service保活
保活方式
1. 前台 Service
// 使用前台 Service
startForeground(1, notification);
2. 双进程守护
// 两个进程互相守护
// 进程1:主进程
// 进程2:守护进程
3. JobScheduler
// 使用 JobScheduler 定时启动
JobInfo jobInfo = new JobInfo.Builder(1, componentName)
.setPeriodic(15 * 60 * 1000)
.build();
jobScheduler.schedule(jobInfo);
注意事项
// ❌ 不推荐:过度保活
// 1. 影响用户体验
// 2. 消耗电量
// 3. 可能被系统杀死
// ✅ 推荐:合理使用
// 1. 使用前台 Service(重要任务)
// 2. 使用 JobScheduler(定时任务)
// 3. 使用 WorkManager(后台任务)
Service最佳实践
1. 及时停止 Service
// 任务完成后及时停止
@Override
protected void onHandleIntent(Intent intent) {
// 执行任务
doWork();
// 任务完成后自动停止
}
2. 避免内存泄漏
@Override
public void onDestroy() {
super.onDestroy();
// 释放资源
if (handler != null) {
handler.removeCallbacksAndMessages(null);
}
}
3. 合理选择 Service 类型
// 长期运行 → 前台 Service
// 一次性任务 → IntentService
// 需要通信 → 绑定 Service
面试常见问题
Q1: Service 生命周期?
答案:
- 启动 Service:onCreate() → onStartCommand() → onDestroy()
- 绑定 Service:onCreate() → onBind() → onUnbind() → onDestroy()
Q2: Service 和 Thread 的区别?
答案:
- Service:运行在主线程,是 Android 组件
- Thread:后台线程,不是 Android 组件
- 使用:Service 中创建 Thread 执行耗时操作
Q3: IntentService 的特点?
答案:
- 自动在后台线程执行
- 任务执行完毕后自动停止
- 多个任务自动排队执行
Q4: Service 保活方式?
答案:
- 前台 Service
- 双进程守护
- JobScheduler
- WorkManager
最后更新:2024年