Files
mkdocs/docs/android面试/核心组件/Service详解.md
2026-01-15 11:53:37 +08:00

405 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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通信
### 方式1Binder
```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);
```
### 方式2BroadcastReceiver
```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"));
```
### 方式3Messenger
```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年*