Android Service详解

    xiaoxiao2023-11-07  166

    全面解析Service

    1 Service的两种启动方式

    startService():其他组件通过startService()方法启动一个Service。一旦启动,Service将一直运行在后台即便启动Service的组件已被destroy。通常,一个被start的Service会在后台执行单独的操作,并不给启动它的组件返回结果,Service中的任务执行完成后应停止Service

    bindService():其他组件调用bindService()方法绑定一个Service。通过绑定方式启动的Service是一个client-server结构,该Service可以与绑定它的组件进行交互。一个bound service仅在有组件与其绑定时才会运行,多个组件可以与一个service绑定,service不再与其他组件绑定时会被destroy

    一个Service可以同时被 startService() 和 bindService()

    注意:Service是运行在主线程的,不能在Service中执行耗时任务,否则会出现ANR。

    2 startService()和bindService()的区别

    startService() 不与启动它的组件交互,bindService() 可以与启动它的组件交互

    onCreate() 和 onDestroy() 只会执行一次,若使用 startService() 启动服务,每一次 startService() 会调用一次onStartCommand();若使用 bindService() 启动服务,每一次 bindService() 只会调用一次 onBind()

    问题:如果同时startService()和bindService(),再调用stopService()时会不会停止Service?

    不会,只有在 startService() 和 bindService() 的任务都执行完成后,stopService() 才会调用 onDestroy()。

    3 Service运行在后台可能会出现的情况

    当系统内存低时,系统将强制停止在后台运行的Service

    若Service绑定了正在与用于交互的Activity,那么该Service将不大可能被系统kill

    如果是创建的前台Service,那么该Service几乎不会被kill

    一个后台Service长时间运行在后台,系统会降低该Service在后台任务栈中的级别,这意味着它容易被kill

    4 一般创建Service的两种方式

    继承Service:该Service运行在主线程,如果需要Service进行耗时任务,需要在Service中开启线程

    继承IntentService:IntentService内部会开启HandlerThread创建了子线程和Handler,在 onHandleIntent() 中可以执行耗时操作,在任务执行完成后会自动 stopSelf() 停止服务

    5 onStartCommand()返回的常量

    START_NO_STICKY:若执行完 onStartCommand() 后,系统就kill Service,不再重新创建Service,除非系统回传了一个PendingIntent。这避免了在不必要的时候运行Service,应用也可以restart任何未完成的操作

    START_STICKY:若系统在 onStartCommand() 执行并返回后kill Service,那么Service会被重新创建并回调onStartCommand()。 此时不要重新传递最后一个Intent,因为系统回调 onStartCommand() 时回传了一个空的Intent,除非有 PendingIntent 传递,否则Intent 为null。该模式适合一些类似播放音乐的操作

    START_REDELIVER_INTENT:若系统在 onStartCommand() 执行并返回后kill Service,那么Service会被重新创建并回调onStartCommand(),并将最后一个Intent回传至该方法。任何 PendingIntent 都会被轮流传递。该模式适合类似下载文件的操作

    最新回复(0)