405 lines
8.3 KiB
Markdown
405 lines
8.3 KiB
Markdown
# Service详解
|
||
|
||
## 目录
|
||
- [Service生命周期](#service生命周期)
|
||
- [Service类型](#service类型)
|
||
- [IntentService](#intentservice)
|
||
- [Service与Activity通信](#service与activity通信)
|
||
- [Service保活](#service保活)
|
||
- [Service最佳实践](#service最佳实践)
|
||
- [面试常见问题](#面试常见问题)
|
||
|
||
---
|
||
|
||
## Service生命周期
|
||
|
||
### 普通 Service 生命周期
|
||
|
||
```java
|
||
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 生命周期
|
||
|
||
```java
|
||
// 绑定 Service
|
||
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
|
||
|
||
// 解绑 Service
|
||
unbindService(serviceConnection);
|
||
|
||
// 生命周期
|
||
// onCreate() → onBind() → onUnbind() → onDestroy()
|
||
```
|
||
|
||
---
|
||
|
||
## Service类型
|
||
|
||
### 1. 普通 Service
|
||
|
||
```java
|
||
// 普通 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
|
||
|
||
```java
|
||
// 前台 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
|
||
|
||
```java
|
||
// 绑定 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 特点
|
||
|
||
```java
|
||
// 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
|
||
|
||
```java
|
||
// 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
|
||
|
||
```java
|
||
// 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
|
||
|
||
```java
|
||
// 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
|
||
|
||
```java
|
||
// 使用前台 Service
|
||
startForeground(1, notification);
|
||
```
|
||
|
||
#### 2. 双进程守护
|
||
|
||
```java
|
||
// 两个进程互相守护
|
||
// 进程1:主进程
|
||
// 进程2:守护进程
|
||
```
|
||
|
||
#### 3. JobScheduler
|
||
|
||
```java
|
||
// 使用 JobScheduler 定时启动
|
||
JobInfo jobInfo = new JobInfo.Builder(1, componentName)
|
||
.setPeriodic(15 * 60 * 1000)
|
||
.build();
|
||
jobScheduler.schedule(jobInfo);
|
||
```
|
||
|
||
### 注意事项
|
||
|
||
```java
|
||
// ❌ 不推荐:过度保活
|
||
// 1. 影响用户体验
|
||
// 2. 消耗电量
|
||
// 3. 可能被系统杀死
|
||
|
||
// ✅ 推荐:合理使用
|
||
// 1. 使用前台 Service(重要任务)
|
||
// 2. 使用 JobScheduler(定时任务)
|
||
// 3. 使用 WorkManager(后台任务)
|
||
```
|
||
|
||
---
|
||
|
||
## Service最佳实践
|
||
|
||
### 1. 及时停止 Service
|
||
|
||
```java
|
||
// 任务完成后及时停止
|
||
@Override
|
||
protected void onHandleIntent(Intent intent) {
|
||
// 执行任务
|
||
doWork();
|
||
// 任务完成后自动停止
|
||
}
|
||
```
|
||
|
||
### 2. 避免内存泄漏
|
||
|
||
```java
|
||
@Override
|
||
public void onDestroy() {
|
||
super.onDestroy();
|
||
// 释放资源
|
||
if (handler != null) {
|
||
handler.removeCallbacksAndMessages(null);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3. 合理选择 Service 类型
|
||
|
||
```java
|
||
// 长期运行 → 前台 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 的特点?
|
||
|
||
**答案:**
|
||
1. 自动在后台线程执行
|
||
2. 任务执行完毕后自动停止
|
||
3. 多个任务自动排队执行
|
||
|
||
### Q4: Service 保活方式?
|
||
|
||
**答案:**
|
||
1. 前台 Service
|
||
2. 双进程守护
|
||
3. JobScheduler
|
||
4. WorkManager
|
||
|
||
---
|
||
|
||
*最后更新:2024年*
|