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

8.3 KiB
Raw Permalink Blame History

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通信

方式1Binder

// 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

// 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

// 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 生命周期?

答案:

  • 启动 ServiceonCreate() → onStartCommand() → onDestroy()
  • 绑定 ServiceonCreate() → 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年