2019-04-29

2019-04-29  本文已影响0人  漆黑迷夜

Service 概述

关于 Service 的介绍,官方文档里面有给详细的说明,它是一个可以再用户看不到的情况下长时间执行某项任务的应用组件。它可以由 Activity 通过调用 startService() 方法来启动,也可以跟 Activity 进行绑定,Activity 也可以通过绑定到 Service 来与其进行交互。

一般情况下,Service 会有两种状态:

上面的两种状态在 Service 中是可以共存的,即一个服务启动的同时也可以被绑定。区别是启动服务会回调 Service 中的 onStartCommand 方法,而绑定则会回调 onBind() 方法。在 Android 中的任何组件都可以通过 Intent 来使用服务,即使在不同的应用中,当然这需要你定义的 Service 是对其他应用开放的。

Android 中的四大组件都是需要在 AndroidManifest.xml 中进行声明了才可以可使用,因此当你创建一个服务时,在清单文件也需要使用<service>标签来声明。

默认情况下,Service是在启动它的应用程序进程中运行的,它不会创建自己的线程,因此如果要执行耗时的任务时,为了不阻塞应用程序的主进程,我们应该在 Service 中开启一个子线程。

Service 的使用

继承 Service 类

要创建一个自己的服务很简单,只需继承 Service 类并重写里面的方法即可。示例如下:

public class MyService extends Service{
    public MyService(){
    
    }
    
    //若没有重写该方法,服务将无法绑定到其他组件
    @Override
    public IBinder onBind(Intent intent){
        throw new UnsupportedOperationException("Not yet implemented");
    }
    
    @Override
    public void onCreate(){
        super.onCreate();
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId){
        return super.onStartCommand(intent, flags, startId);
    }
    
    @Override
    public void onDestory(){
        super.onDestory();
    }
}

上面各个方法的含义如下:

在AndroidManifest.xml中声明

创建了 Service 的子类以后还要将该服务在清单文件(AndroidManifest.xml)中声明,代码如下:

<manifest>
    ......
    <service
        android:name=".MyService"
        android:enabled="true"
        android:exported="true">
    </service>
    ........
</manifest>

几个属性的含义如下:

启动服务

一般通过将要启动的服务的类名传递到 Intent 中,在将该 Intent 作为 startService() 的参数来启动服务的。示例如下:

    Intent intent = new Intent(MainActivity.this, MyService.class);
    startService(intent);

startService() 方法调用了之后会执行 Service 里面的 onStartCommand() 方法。如果多次发起启动服务的请求,则会调用多次该方法。启动服务之后会无限制的运行,即使启动服务的组件已经被销毁

停止服务

前面也说过一旦服务启动了之后便会一直运行,因此要么会在组件销毁时调用 stopService() 停止服务,要么在Service的任务执行完毕之后,调动stopSelf() 自行停止,依次来保证系统的资源能够被释放。如果服务同时处理多个 onStartCommand() ,则应该调用 stopSelf(int) 来停止最近的服务请求。

绑定服务

Android 提供了 bindService() 来进行服务的绑定,以便于长期连接。服务必须实现 onBind() 方法才能进行服务的绑定,该方法返回一个 IBinder 接口实例,用于与服务进行通信。当没有组件绑定到服务时,该服务则会被系统销毁。多个客户端可以同时绑定到一个服务,并且可以通过 unbindService() 来解绑。

前台服务

前台服务时用户主动意识到的服务,因此在内存不足时,系统也不会销毁它。当然前台服务必须以在状态栏上提供通知。 Android 提供了 startForeground(int id, Notification notification) 方法来将一个服务变成前台服务,该方法有两个参数:

移除前台服务调用 stopForeground()

服务的生命周期

官方给出的服务生命周期图如下:

alt

不管是以何种方式启动服务的,均有可能与客户端进行绑定,因此即使已经使用 onStartCommand() (即客户端调用 startService )启动的服务仍可以接收对 onBind() 的调用(客户端调用 bindService() )

IntentService

IntentService 也是Service的子类,对 Service 做了一定的封装,前面说了如果不手动给 Service 开启一个线程的话,默认会运行在主线程中,这会降低正在运行的Activity的性能。因此 Android 提供了 IntentService ,它会创建独立的 Worker 线程来处理请求。

IntentService 的使用方法也很简单,只需继承 IntentService 类并重写 onHandleIntent() 方法即可

IntnetService 的主要执行了以下操作:

public class HelloIntentService extends IntentService {
    public HelloIntentService(){
        super("HelloIntentService");
    }
    
    @Override
    protected void onHandleIntent(Intent intent){
        try{
            Thread.sleep(5000);
        }catch(InterruptedException e){
            Thread.currentThread().interrupt();
        }
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId){
        Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
        return super.onStartCommand(Intent intent, int flags);
    }
}

参考文档

上一篇下一篇

猜你喜欢

热点阅读