Android 开发学习笔记(二)—— Service

Service 能在后台长期运行而不提供用户界面。由其他组件启动,且可以做到不依赖当前应用运行。组件能绑定 Service,进行交互、执行进程间通信。

Tips
  1. 一个Service如果被调用startService()启动多次,onCreate()方法也只执行一次
  2. 对于启动服务,除onStartCommand()方法外,其他生命周期方法只会被调用一次
  3. onStartCommand()调用次数 == startService()调用次数
  4. 在服务中启动Activity必须加下面这行代码
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Service
Android 开发学习笔记(二)—— Service_第1张图片
Service.png
Service 生命周期
  • 官方生命周期图 服务生命周期
Android 开发学习笔记(二)—— Service_第2张图片
service_lifecycle.png
Service 的两种形式:
  • 启动:组件通过startService()启动,无限期运行(不受组件生命周期影响)
  • 绑定:组件通过bindService()绑定,提供客户端-服务器接口进行交互、发请求、获取结果甚至进程间通信。仅当与另一个组件绑定时才会运行,组件与服务可以是多对一关系,最后一个绑定组件销毁Service销毁。应用场景:Activity 和其他应用组件中的服务进行交互,或者需要通过进程间通信 (IPC) 向其他应用公开某些应用功能,那么就创建绑定服务。

Service 既可以是启动服务,也可以与其他组件进行绑定。这取决于你是否实现Service的回调方法:onStartCommand()(允许组件启动服务)、onBind()(允许绑定服务)。

创建启动 Service:

应用场景:假设某Activity 需要上传数据到服务器,则可以启动一个协同服务,通过startService()传递一个Intent ,为该服务提供上传的数据。服务通过onStartCommand()接收Intent,进行上传操作。

PS:需要注意的是,默认情况,Service 运行在主线程,因此,如果有耗时操作交给 Service 应该在 Service中启动新的子线程执行该操作。

  1. 首先,与其他 Android 组件一样,需要在 AndroidManifest.xml 文件里面声明你要用的服务;
...

  

...
  1. 使用扩展类创建 Service
  • Service:所有服务的基类,扩展时,必须创建一个用于执行所有服务工作的新线程。

  • IntentService:Service 的子类,一般情况下都用这个。不要求同时处理多个请求就选这个服务。实现onHandleIntent()方法接收每个Intent。

/**
  *  使用 IntentService 只需要提供一个构造函数跟实现onHandleIntent()方法就行了
  */
public class HelloIntentService extends IntentService {

  public HelloIntentService() {
      super("HelloIntentService");
  }

  @Override
  protected void onHandleIntent(Intent intent) {
      // ...
  }
}
  1. 启动 Service
/**
  *  Intent可以指定要启动的服务,通过将Intent传给 startService(),
  *  从Activity或其他组件中启动Service
  */
Intent intent = new Intent(this, HelloService.class);
startService(intent);
  • 这之后Android系统会调用onStartCommand()方法 接收被传递的Intent。千万不要手动去掉onStartCommand();如果服务尚未运行,那系统就会onCreate()->onStartCommand()。
  • 通信:如果服务亦未提供绑定,则使用 startService() 传递的 Intent 是应用组件与 Service 之间唯一的通信模式;Service向组件传递消息可以通过:让启动服务的组件创建一个 PendingIntent (使用 getBroadcast())并通过Intent传递给Service,然后Service可以使用广播传递消息
  • 多个服务启动请求会导致多次对服务的 onStartCommand()进行相应的调用。但是,要停止服务,只需一个服务停止请求(使用 stopSelf() 或 stopService())即可。
  1. 停止 Service
  • 启动服务必须通过 stopSelf()自行结束,或是其他组件调用stopService()来停止它;
  • 通过 stopSelf(startId)来确保停止正确的Service;
  • 任务完成后应停止服务节省电量;
在前台运行服务

应用场景:应该将通过服务播放音乐的音乐播放器设置为在前台运行,这是因为用户明确意识到其操作。 状态栏中的通知可能表示正在播放的歌曲,并允许用户启动 Activity 来与音乐播放器进行交互。

前台服务特点:
  1. 在内存不足时,系统也不会考虑将其终止
  2. 前台服务必须为状态栏提供通知,放在“正在进行”标题下方,这意味着除非服务停止或从前台移除,否则不能清除通知。
  • 让服务运行在前台
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
        System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
        getText(R.string.notification_message), pendingIntent);
// 第一个参数不能为 0 
startForeground(ONGOING_NOTIFICATION_ID, notification);
  • 从前台移除服务
// true 或 false 代表是否也移除状态栏通知
stopForeground(true);

参考自官方文档
https://developer.android.com/guide/components/services.html?hl=zh-cn

你可能感兴趣的:(Android 开发学习笔记(二)—— Service)