Android Service详解

 

各位肯定知道 Service 作为 Android 的四大组件之一是非常重要的。不过说实话,我实际开发项目中服务用的并不多,(可能和需求有关吧)但是笔试的时候,几乎是必出的题目了,所以我们今天就来仔细的回顾一下 Service 。

1. 什么是服务?

Service 是表示应用程序需求的应用程序组件,在不与用户交互的情况下执行长时间运行的操作,或者给其他应用程序提供使用的功能。Service 是和应用程序在同一个进程中运行的,Service 并不是一个线程,所以它并不是用来处理耗时操作的。

2. 启动服务的方式有几种?(启动服务需要在 AndroidManifest.xml 文件配置)

  • Context.startService()
  • Context.bindService()
  • 先 Context.startService() 在 Context.bindService()

3. Service 的方法和常量有哪些?

Return Methode
final Application

getApplication()

返回拥有此服务的Application。

adstract IBinder

onBind(Intent intent)

将通信通道返回给服务。

void

onConfigurationChanged(Configuration newConfig)

当组件运行时,设备配置发生变化时由系统调用。

void

onCreate()

首次创建服务时由系统调用。

void

onDestroy()

由系统调用以通知服务它已不再使用且正在被删除。

void

onLowMemory()

当整个系统内存不足时调用此方法,并且主动运行的进程应调整其内存使用量。

void

onRebind()

当新客户端连接到服务时调用,在此之前,它已经被通知所有客户端在其onUnbind(Intent)中断开连接。

void

onStart(Intent intent,int startId)

此方法在API级别5中已弃用。请实现onStartCommand(Intent,int,int)。

int

onStartCommand(Intent intent,int flags,int startId)

每次客户端通过调用Context.startService(Intent)显式启动服务时,由系统调用,提供它提供的参数和表示启动请求的唯一整数标记。

void

onTaskRemoved(Intent rootIntent)

如果服务当前正在运行,且用户删除了来自服务应用程序的任务,则调用此函数。

void

onTrimMemory(int level)

当操作系统确定是进程从进程中删除不需要的内存的好时机时调用。

boolean

onUnbind(Intent intent)

当所有客户端与服务发布的特定接口断开连接时调用。

final void

startForeground(int flags)

将此服务从前台状态删除,允许在需要更多内存时终止该服务。

final void

startForeground(boolean removeNotification)

同 startForeground(int flags)

final void

startForeground(int id,Notification notification)

如果您的服务已启动(通过Context.startService(Intent)运行),则还要使此服务在前台运行,从而提供在此状态下向用户显示的持续通知。

final void

stopSelf()

停止服务,如果服务之前已经启动。

final void

stopSelf(int startId)

不再返回结果的旧版本的stopSelfResult(int)。

final boolean

stopSelfResult(int startId)

如果最近一次启动的是startId,则停止服务。

Constants
int

START_CONTINUATION_MASK

onStartCommand返回的位(Intent, int, int)描述了如果服务被终止,如何继续服务。

int

START_FLAG_REDELIVERY

如果Intent是先前传递的intent的重新传递,则此标志在onStartCommand(Intent,int,int)中设置,因为该服务先前已返回START_REDELIVER_INTENT但在为该Intent调用stopSelf(int)之前已被杀死。

int

START_FLAG_RETRY

如果意图是重试,则在onStartCommand(Intent, int, int)中设置此标志,因为初始尝试从未到达或从onStartCommand(Intent, int, int)返回。

int

START_NOT_STICKY

从onStartCommand(Intent,int,int)返回的常量:如果此服务的进程在启动时被终止(从onStartCommand(Intent,int,int)返回后),并且没有新的启动意图要传递给它,那么 将服务从启动状态中取出,并且在将来显式调用Context.startService(Intent)之前不要重新创建。

int

START_REDELIVER_INTENT

从onStartCommand(Intent,int,int)返回的常量:如果此服务的进程在启动时被终止(从onStartCommand(Intent,int,int)返回后),则它将被安排重新启动并且最后一次传递的Intent 通过onStartCommand(Intent,int,int)再次传递给它。

int

START_STICKY

从onStartCommand(Intent,int,int)返回的常量:如果此服务的进程在启动时被终止(从onStartCommand(Intent,int,int)返回后),则将其保留在启动状态但不保留此状态 交付 intent。

int

START_STICKY_COMPATIBILITY

从onStartCommand(Intent,int,int)返回的常量:START_STICKY的兼容版本,不保证在被杀死后再次调用onStartCommand(Intent,int,int)。

int

STOP_FOREGROUND_DETACH

stopForeground(int)的标志:如果设置,则先前提供给startForeground(int,Notification)的通知将与服务分离。

int

STOP_FOREGROUND_REMOVE

stopForeground(int)的标志:如果设置,将删除先前提供给startForeground(int,Notification)的通知。

4. 服务的生命周期

(1)Context.startService() 的生命周期。(和开启者的生命周期无关,如果不显示的停止 Service,Service 会一直运行。)

首次启动 Service 会先调用 onCreate() ,然后调用 onStartCommand(),至此 Service 任务就启动了。我们再次启动相同 Service,你会发现只调用了 onStartCommand(),也就是说 onCreate() 只会被调用一次,onStartCommand()会调用多次。当我们停止 Service 会调用 onDestroy(),至此 Service 就停止了。生命周期结束!

  • 测试代码:
public class MyService extends Service {

    public static final String TAG = "My_Service";

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "MyService --> onCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "MyService --> onStartCommand");
        return START_STICKY;
    }

    
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "MyService --> onDestroy");
    }
}
 Intent intent = new Intent(ServiceActivity.this, MyService.class);
 startService(intent);
stopService(intent);
  • 第一次启动 Service 
 D/My_Service: MyService --> onCreate
 D/My_Service: MyService --> onStartCommand
  • 再次启动相同 Service
 D/My_Service: MyService --> onStartCommand
  • 当我们停止服务 Service
 D/My_Service: MyService --> onDestroy

 

(2)Context.bindService() 的生命周期。(和开启者的生命周期绑定,随着开启者的销毁而销毁)

首次启动 Service 会调用 onCreate() ,同样的也是只会调用一次。随后会调用 onBind() 。销毁 Service 会调用先调用onUnbind(),随后会调用 onDestroy()。至此生命周期结束!

  • 测试代码
public class MyService extends Service {

    public static final String TAG = "My_Service";

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG,"MyService --> onBind");
        return new MyBinder();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(TAG,"MyService --> onUnbind");
        return super.onUnbind(intent);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "MyService --> onCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "MyService --> onStartCommand");
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "MyService --> onDestroy");
    }

    public class MyBinder extends Binder implements IPersonalInif{

        @Override
        public String getName() {
            return "Test Name";
        }
    }

    public interface IPersonalInif {
        String getName();
    }
}
public class MyServiceConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mInfoService = (MyService.IPersonalInif) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }

        @Override
        public void onBindingDied(ComponentName name) {

        }
}
Intent intent = new Intent(ServiceActivity.this, MyService.class);
mMyServiceConnection = new MyServiceConnection();
bindService(intent, mMyServiceConnection, Service.BIND_AUTO_CREATE);
Log.d(TAG,"IPersonalInif --> name --> " + mInfoService.getName());
unbindService(mMyServiceConnection);
  • 第一次启动 Service
 D/My_Service: MyService --> onCreate
 D/My_Service: MyService --> onBind
  • 再次启动相同服务 Service

logcat 没有任何输出,也就是再次启动没有任何回调!

  • 我们尝试获取 Service 传递的值
 D/Service_Activity: IPersonalInif --> name --> Test Name
  • 解除 Service 的绑定
 D/My_Service: MyService --> onUnbind
 D/My_Service: MyService --> onDestroy

 

(3)先 Context.startService() 在 Context.bindService() 的生命周期。(这种方式的代码就不贴了,说说场景,和流程吧)

如果 Service 由某个客户端通过 Context.startService() 启动,接下来由其他客户端通过 Context.bindService() 绑定到该 Service,然后在调用 unbindService() 解除该 Service,然后在通过 Context.bindService() 绑定到该 Service,那么生命周期的步骤如下:

onCreate() --> onStartCommand --> onBind() --> onUnbind() --> onRebind()

注意:前提是 onUnbind() 返回 true,读到这里可能会有点疑惑,那就是我明明调用了 unbindService() 方法,系统为什么不调用 Service 的 onDestroy() 呢?这是因为 Service 是我们先 Context.startService() 启动的,所以系统只会调用 onUnbind(),不会调用 onDestroy()。(我们使用 Context.bindService() 绑定一个已经启动的 Service ,系统只是会将 Service 内部的 IBinder 对象传递给 Activity,并不会将 Service 的生命周期和 Activity 的生命周期绑定,所以我们即使调用 unbindService(),也是不会销毁 Service的)

 

至此,Service 的使用以及生命周期已经讲解完了,希望对你有帮助!

欢迎加入Q群一起探讨Android问题。

Android Service详解_第1张图片

 

你可能感兴趣的:(Android,Fragmentation)