1、是一个应用程序组件
2、没有图形化界面
3、常用来做一些耗时操作
4、可以使用Service更新ContentProvider,发送Intent以及启动系统的通知等
5、Service于Activity有相同的父类ContentWrapper,Service就是默默运行在后台的组件,可以理解为是没有前台的activity,适合用来运行不需要前台界面的代码
6、服务可以被手动关闭,不会重启,但是如果被自动关闭,内存充足就会重启startService启动服务的生命周期onCreate-onStartCommand-onDestroy
7、重复的调用startService会导致onStartCommand被重复调用
8、Service不是一个单独的进程
9、Service不是一个线程
二、服务的创建和启动、停止
1、 创建一个类继承Service
public class TestService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
System.out.println("服务被开启了");
super.onCreate();
}
@Override
public void onDestroy() {
System.out.println("服务被停止了.");
super.onDestroy();
}
}
2、启动服务有两种方式(1)创建意图,使用startService()方法启动服务
开始服务,会使进程变成为服务进程
启动服务的activity和服务不再有一毛钱关系
缺陷:不能调用服务中的方法
(2)绑定服务
可以调用服务中的方法
绑定服务不会使进程变成服务进程
绑定服务,是activity与服务建立连接,如果activity销毁了,服务也会被解绑并销毁,但是如果服务被销毁,activity不会被销毁
绑定服务和解绑服务的生命周期方法:onCreate->onBind->onUnbind->onDestroy
绑定不会重复执行,只能绑定一次
解绑只能执行一次,执行多次会出现非法状态异常(java.lang.IllegalStateException)
3、停止服务
(1)使用StopService()方法停止
绑定服务
public interface IService {
/**
* 定义的接口 小蜜一定有一个方法是拿钱办事
* @param name 姓名
* @param money 钱
*/
public void callMethodInService(String name,int money);
}
public class TestService extends Service {
/**
* 服务内部的中间人 小蜜
*/
private class MyBinder extends Binder implements IService{
/**
* 中间人帮忙简介的调用服务的方法.
*
* @param name
* 姓名
* @param money
* 钱
*/
public void callMethodInService(String name, int money) {
if (money > 200) {
methodInService(name);
}else{
Toast.makeText(TestService.this, "这点钱不够用,我们要按照制度办事", 0).show();
}
}
public void 洗桑拿(){
Toast.makeText(TestService.this, "走,一起去洗桑拿吧...", 0).show();
}
public void 打麻将(){
Toast.makeText(TestService.this, "走,一起去打麻将吧...", 0).show();
}
}
// 在服务成功绑定的时候 返回服务中的代理人(中间人)
@Override
public IBinder onBind(Intent intent) {
System.out.println("服务被绑定了, 返回IBinder的中间人");
return new MyBinder();
}
@Override
public void onCreate() {
System.out.println("服务被创建了..");
super.onCreate();
}
@Override
public void onDestroy() {
System.out.println("服务被销毁了..");
super.onDestroy();
}
/**
* 服务内部的方法,帮助你办暂住证.
*
* @param name
* 姓名
*/
public void methodInService(String name) {
Toast.makeText(this, name + "你的暂住证办好了...", 0).show();
}
}
本地使用public class MainActivity extends Activity {
IService iService;
MyConn conn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void bind(View view) {
Intent intent = new Intent(this, TestService.class);
conn = new MyConn();
bindService(intent, conn, BIND_AUTO_CREATE);//此方法绑定并启动方法
}
private class MyConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iService = (IService) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}}
特别注意:
1、你应当知道在调用 bindService 绑定到Service的时候,你就应当保证在某处调用 unbindService 解除绑定(尽管 Activity 被 finish 的时候绑定会自动解除,并且Service会自动停止);
2、你应当注意 使用 startService 启动服务之后,一定要使用 stopService停止服务,不管你是否使用bindService;
3、同时使用 startService 与 bindService 要注意到,Service 的终止,需要unbindService与stopService同时调用,才能终止 Service,不管 startService 与 bindService 的调用顺序,如果先调用 unbindService 此时服务不会自动终止,再调用 stopService 之后服务才会停止,如果先调用 stopService 此时服务也不会终止,而再调用 unbindService 或者 之前调用 bindService 的 Context 不存在了(如Activity 被 finish 的时候)之后服务才会自动停止;
4、当在旋转手机屏幕的时候,当手机屏幕在“横”“竖”变换时,此时如果你的 Activity 如果会自动旋转的话,旋转其实是 Activity 的重新创建,因此旋转之前的使用 bindService 建立的连接便会断开(Context 不存在了),对应服务的生命周期与上述相同。
5、在 sdk 2.0 及其以后的版本中,对应的 onStart 已经被否决变为了 onStartCommand,不过之前的 onStart 任然有效。这意味着,如果你开发的应用程序用的 sdk 为 2.0 及其以后的版本,那么你应当使用 onStartCommand 而不是 onStart。
三、两种启动方法混合使用
1、方式一:start-->bind-->stop-->unbind
2、方式二:start-->bind-->unbind-->stop (常用)
四、进程优先级
1. 前台进程(forign process):拥有一个正在与用户交互的activity(onResume方法被调用)的进程
2. 可见进程(visiable process):拥有一个非前台,但是对用户可见的activity(onPause方法被调用)的进程
3. 服务进程(service process):拥有一个通过startService方法启动的服务的进程
4. 后台进程(background process):拥有一个后台activity(onStop方法被调用)的进程
5. 空进程(Empty process):没有拥有任何活动的应用组件的进程,也就是没有任何服务和activity在运行
五、本地服务和远程服务
本地服务:服务和启动它的组件在同一个进程
远程服务:服务和启动它的组件不在同一个进程
远程服务只能隐式启动,类似隐式启动Activity,在清单文件中配置Service标签时,必须配置intent-filter子节点,并指定action子节点
六、AIDL
Android interface definition language
安卓接口定义语言
作用:跨进程通信
应用场景:远程服务中的中间人对象,其他应用是拿不到的,那么在通过绑定服务获取中间人对象时,就无法强制转换,使用aidl,就可以在其他应用中拿到中间人类所实现的接口
使用步骤
(1)绑定服务用到的接口文件后缀名修改为AIDL,去掉文件中的所有访问修饰符
(2)在调用者中添加与aidl文件所在包相同包名的包,将aidl文件拷贝到这个应用程序的这个包下
例:http://www.2cto.com/kf/201406/312244.html
七、Activity与service之间的通信