简介:
1. 基础知识
- 定义:服务,属于Android中的四大之一组件
- 作用:提供需要在后台长期运行的服务(如复杂计算、下载等等)(运行在主线程需要耗时操作得启用子线程)
- 特点:长生命周期的、没有用户界面、在后台运行
2. 生命周期方法详解
目录
![](https://i-blog.csdnimg.cn/blog_migrate/f0d538fdd2ef56450c72d025acf0a50d.webp?x-image-process=image/format,png)
生命周期表:
![](https://img-blog.csdn.net/20170718102825431)
1. 生命周期常用方法
在Service的生命周期里,常用的有:
- 4个手动调用的方法
手动调用方法 作用 startService() 启动服务 stopService() 关闭服务 bindService() 绑定服务 unbindService() 解绑服务
- 5个内部自动调用的方法
内部自动调用的方法 作用 onCreat() 创建服务 onStartCommand() 开始服务 onDestroy() 销毁服务 onBind() 绑定服务 onUnbind() 解绑服务
2. 生命周期方法具体介绍
主要介绍内部调用方法和外部调用方法的关系。
2.1 startService()
- 作用:启动Service服务
- 手动调用startService()后,自动调用内部方法:onCreate()、onStartCommand()
- 调用逻辑如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6666fd3c91721b5b5af50d8c4db68754.webp?x-image-process=image/format,png)
调用逻辑
2.2 stopService()
- 作用:关闭Service服务
- 手动调用stopService()后,自动调用内部方法:onDestory()
- 调用的逻辑:
调用逻辑
2.3 bindService()
- 作用:绑定Service服务
- 手动调用bindService()后,自动调用内部方法:onCreate()、onBind()
- 调用的逻辑:
![](https://i-blog.csdnimg.cn/blog_migrate/a74c2b82fdc11e27782f8003dcb03a3b.webp?x-image-process=image/format,png)
调用的逻辑
2.4 unbindService()
- 作用:解绑Service服务
- 手动调用unbindService()后,自动调用内部方法:onCreate()、onBind()、onDestory()
- 调用的逻辑:
![](https://i-blog.csdnimg.cn/blog_migrate/f536638f00be0b482c21c7bc36dfed7a.webp?x-image-process=image/format,png)
调用的逻辑
3. 常见的生命周期使用
3.1 只使用startService启动服务的生命周期
![](https://i-blog.csdnimg.cn/blog_migrate/a2ff0fb2d1718118ab8d3aee4222deaf.webp?x-image-process=image/format,png)
startService启动服务的生命周期
3.2 只使用BindService绑定服务的生命周期
![](https://i-blog.csdnimg.cn/blog_migrate/0c1dd9e0017aff73f7813bb4b2dded8c.webp?x-image-process=image/format,png)
BindService绑定服务的生命周期
3.3 同时使用startService()启动服务、BindService()绑定服务的生命周期
![](https://i-blog.csdnimg.cn/blog_migrate/1fbf91de137af67081b63ace183bfd2e.webp?x-image-process=image/format,png)
Paste_Image.png
3.4 特别注意
- startService()和stopService()只能开启和关闭Service,无法操作Service;
bindService()和unbindService()可以操作Service
- startService开启的Service,调用者退出后Service仍然存在;(跟Acitivity的关系不密切,即时界面销毁服务还在)
- BindService开启的Service,调用者退出后,Service随着调用者销毁。(跟Activity关系密切,界面销毁,服务也会销毁。)
- StartService 和BindService 结合使用时:先StartService 启动服务,再BindService (不会调用oncreat只调用onBind())绑定服务。关闭界面,Service不会关闭,只后会解绑。不会调用ondestory()方法,只会调用onUnbind(),再次进入界面,先StartService ,BindService。不会创建新的服务。(不会调用onCreate()),只会调用onstartcommand()及onBind()。想真正解除服务只能先stopService()再unbindService()一个Service必须要在既没有和任何Activity关联又处理停止状态的时候才会被销毁。
eg:
如下所示:
这里我们新增了一个MyBinder类继承自Binder类,然后在MyBinder中添加了一个startDownload()方法用于在后台执行下载任务,当然这里并不是真正地去下载某个东西,只是做个测试,所以startDownload()方法只是打印了一行日志。
项目中的每一个Service都必须在AndroidManifest.xml中注册才行
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.servicetest"
- android:versionCode="1"
- android:versionName="1.0" >
-
- <uses-sdk
- android:minSdkVersion="14"
- android:targetSdkVersion="17" />
-
- <application
- android:allowBackup="true"
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:theme="@style/AppTheme" >
-
- ……
-
- <service android:name="com.example.servicetest.MyService" >
- </service>
- </application>
-
- </manifest>
然后修改activity_main.xml中的代码,在布局文件中添加用于绑定Service和取消绑定Service的按钮:
接下来再修改MainActivity中的代码,让MainActivity和MyService之间建立关联,代码如下所示:
可以看到,这里我们首先创建了一个ServiceConnection的匿名类,在里面重写了onServiceConnected()方法和onServiceDisconnected()方法,这两个方法分别会在Activity与Service建立关联和解除关联的时候调用。在onServiceConnected()方法中,我们又通过向下转型得到了MyBinder的实例,有了这个实例,Activity和Service之间的关系就变得非常紧密了。现在我们可以在Activity中根据具体的场景来调用MyBinder中的任何public方法,即实现了Activity指挥Service干什么Service就去干什么的功能。
当然,现在Activity和Service其实还没关联起来了呢,这个功能是在Bind Service按钮的点击事件里完成的。可以看到,这里我们仍然是构建出了一个Intent对象,然后调用bindService()方法将Activity和Service进行绑定。bindService()方法接收三个参数,第一个参数就是刚刚构建出的Intent对象,第二个参数是前面创建出的ServiceConnection的实例,第三个参数是一个标志位,这里传入BIND_AUTO_CREATE表示在Activity和Service建立关联后自动创建Service。
3. Service分类
生命周期表:
1. 生命周期常用方法
在Service的生命周期里,常用的有:
- 4个手动调用的方法
手动调用方法 | 作用 |
---|---|
startService() | 启动服务 |
stopService() | 关闭服务 |
bindService() | 绑定服务 |
unbindService() | 解绑服务 |
- 5个内部自动调用的方法
内部自动调用的方法 | 作用 |
---|---|
onCreat() | 创建服务 |
onStartCommand() | 开始服务 |
onDestroy() | 销毁服务 |
onBind() | 绑定服务 |
onUnbind() | 解绑服务 |
2. 生命周期方法具体介绍
主要介绍内部调用方法和外部调用方法的关系。
2.1 startService()
- 作用:启动Service服务
- 手动调用startService()后,自动调用内部方法:onCreate()、onStartCommand()
- 调用逻辑如下:
调用逻辑
2.2 stopService()
- 作用:关闭Service服务
- 手动调用stopService()后,自动调用内部方法:onDestory()
- 调用的逻辑:
![](https://i-blog.csdnimg.cn/blog_migrate/230519643c6e3c52b1b53078daa8d77e.webp?x-image-process=image/format,png)
2.3 bindService()
- 作用:绑定Service服务
- 手动调用bindService()后,自动调用内部方法:onCreate()、onBind()
- 调用的逻辑:
![](https://i-blog.csdnimg.cn/blog_migrate/a74c2b82fdc11e27782f8003dcb03a3b.webp?x-image-process=image/format,png)
2.4 unbindService()
- 作用:解绑Service服务
- 手动调用unbindService()后,自动调用内部方法:onCreate()、onBind()、onDestory()
- 调用的逻辑:
调用的逻辑
3. 常见的生命周期使用
3.1 只使用startService启动服务的生命周期
![](https://i-blog.csdnimg.cn/blog_migrate/a2ff0fb2d1718118ab8d3aee4222deaf.webp?x-image-process=image/format,png)
3.2 只使用BindService绑定服务的生命周期
![](https://i-blog.csdnimg.cn/blog_migrate/0c1dd9e0017aff73f7813bb4b2dded8c.webp?x-image-process=image/format,png)
3.3 同时使用startService()启动服务、BindService()绑定服务的生命周期
![](https://i-blog.csdnimg.cn/blog_migrate/1fbf91de137af67081b63ace183bfd2e.webp?x-image-process=image/format,png)
3.4 特别注意
- startService()和stopService()只能开启和关闭Service,无法操作Service;
bindService()和unbindService()可以操作Service
- startService开启的Service,调用者退出后Service仍然存在;(跟Acitivity的关系不密切,即时界面销毁服务还在)
- BindService开启的Service,调用者退出后,Service随着调用者销毁。(跟Activity关系密切,界面销毁,服务也会销毁。)
- StartService 和BindService 结合使用时:先StartService 启动服务,再BindService (不会调用oncreat只调用onBind())绑定服务。关闭界面,Service不会关闭,只后会解绑。不会调用ondestory()方法,只会调用onUnbind(),再次进入界面,先StartService ,BindService。不会创建新的服务。(不会调用onCreate()),只会调用onstartcommand()及onBind()。想真正解除服务只能先stopService()再unbindService()一个Service必须要在既没有和任何Activity关联又处理停止状态的时候才会被销毁。
如下所示:
这里我们新增了一个MyBinder类继承自Binder类,然后在MyBinder中添加了一个startDownload()方法用于在后台执行下载任务,当然这里并不是真正地去下载某个东西,只是做个测试,所以startDownload()方法只是打印了一行日志。
项目中的每一个Service都必须在AndroidManifest.xml中注册才行
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.servicetest"
- android:versionCode="1"
- android:versionName="1.0" >
- <uses-sdk
- android:minSdkVersion="14"
- android:targetSdkVersion="17" />
- <application
- android:allowBackup="true"
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:theme="@style/AppTheme" >
- ……
- <service android:name="com.example.servicetest.MyService" >
- </service>
- </application>
- </manifest>
然后修改activity_main.xml中的代码,在布局文件中添加用于绑定Service和取消绑定Service的按钮:
接下来再修改MainActivity中的代码,让MainActivity和MyService之间建立关联,代码如下所示:可以看到,这里我们首先创建了一个ServiceConnection的匿名类,在里面重写了onServiceConnected()方法和onServiceDisconnected()方法,这两个方法分别会在Activity与Service建立关联和解除关联的时候调用。在onServiceConnected()方法中,我们又通过向下转型得到了MyBinder的实例,有了这个实例,Activity和Service之间的关系就变得非常紧密了。现在我们可以在Activity中根据具体的场景来调用MyBinder中的任何public方法,即实现了Activity指挥Service干什么Service就去干什么的功能。
当然,现在Activity和Service其实还没关联起来了呢,这个功能是在Bind Service按钮的点击事件里完成的。可以看到,这里我们仍然是构建出了一个Intent对象,然后调用bindService()方法将Activity和Service进行绑定。bindService()方法接收三个参数,第一个参数就是刚刚构建出的Intent对象,第二个参数是前面创建出的ServiceConnection的实例,第三个参数是一个标志位,这里传入BIND_AUTO_CREATE表示在Activity和Service建立关联后自动创建Service。
3. Service分类
3.1 Service的类型
![](https://i-blog.csdnimg.cn/blog_migrate/9969eed4e1a3757d1eb132a66530532f.webp?x-image-process=image/format,png)
3.2 详细介绍
![](https://i-blog.csdnimg.cn/blog_migrate/8f8dcc22eeb540f0f8fac84c13375192.webp?x-image-process=image/format,png)
具体demo参考:
http://www.jianshu.com/p/e04c4239b07e
5. 使用场景
- 通过上述描述,你应该对Service类型及其使用非常了解;
- 那么,我们该什么时候用哪种类型的Service呢?
- 各种Service的使用场景请看下图:
使用场景
6. 其他思考
6.1 Service和Thread的区别
- 结论:Service和Thread之间没有任何关系
-
之所以有不少人会把它们联系起来,主要因为Service的后台概念
后台的定义:后台任务运行完全不依赖UI,即使Activity被销毁,或者程序被关闭,只要进程还在,后台任务就可以继续运行
-
其实二者存在较大的区别,如下图:
Paste_Image.png
一般来说,会将Service和Thread联合着用,即在Service中再创建一个子线程(工作线程)去处理耗时操作逻辑,如下代码:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//新建工作线程
new Thread(new Runnable() {
@Override
public void run() {
// 开始执行后台任务
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
class MyBinder extends Binder {
public void service_connect_Activity() {
//新建工作线程
new Thread(new Runnable() {
@Override
public void run() {
// 执行具体的下载任务
}
}).start();
}
}
6.2 Service和IntentService的区别
具体别人写的文章:Android多线程全面解析:IntentService用法&源码
转载:http://blog.csdn.net/guolin_blog/article/details/11952435
http://www.jianshu.com/p/d963c55c3ab9