安卓四大组件之Service

来源:互联网 发布:永久域名 编辑:程序博客网 时间:2024/06/05 22:51

Service作为安卓四大组件之一通常用来完成一些不需要用户操作,但是一直运行着的任务 ,还可以用于ipc(进程间通信)

在介绍Service之前 我们先了解一下安卓中进程的优先级:

安卓中的优先级共有5个

1.Foregrounf process 前台进程 
当前进程中有Activity处于可见可操作(Activity执行onResume之后)
service 以及广播接收者 执行生命周期方法

2.visible process 可视进程
不是前台,但是可以被看见 dialog
一般不会被干掉
Activity处于onPause (有透明应用盖在上面,或者一个对话框盖在上面)
只有当前台进程内存不够时 才会杀死它

3.Service process服务进程
startService 开启一个服务 一般很难杀死

4.backgroung process 后台进程
前面三个如果需要内存 随时都可以把它干掉
Activity处于 onstop状态 但是没有被销毁
LRU:最近最少使用 最近使用的应用最后被杀死 
          最早使用的最先被杀死

5.Empty process 空进程 
没有任何组件运行(是为了下次应用启动的时候 节省了创建进程的时间) 


在进程中加入Service可以提高进程的优先级

Service同其他的组件一样,都是在主线程中工作的 因此如果在Service中做耗时的操作同样也需要开启子线程


开启服务的第一种方式:startService()

定义一个类继承Service 重写里面的oncreate   onstartCommand  onDestroy方法

public class MyService extends Service {@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {super.onDestroy();}}
( 在Service类中还有一个抽象的方法onBind需要我们实现 它是用来绑定启动的 回头我们再说 )

写好MyService类之后 还需要在清单文件中声明 service节点

<service android:name="com.startservice.MyService"></service>
这样一个服务我们就创建好了,下面我们用startService方法来启动它

Intent service = new Intent(this,MyService.class);startService(service);
startService的启动方法同Activity的启动方式类似,使用一个意图,然后开启意图

stractService开启服务的特点:

①调用startservice之后 service走的生命周期方法  onCreate->onstartCommend 
 ②多次调用startservice onCreate只会走一次  onStartCommend会调用多次(调用几次startservice onStartCommend方法就会调用几次)
③ 通过startservice开启service的activity退出之后 service不会销毁
④ 只有手动调用stopservice或stopself方法 才会销毁服务(或者在程序管理器页面停止服务)
⑤ startservice方式开启的服务可以提升应用的进程优先级


绑定Service

大家有没有发现虽然启动方式可以开启一个服务,在服务里面执行一些做操,但是我们没有办法去手动调用Service里面的方法,

四大组件又不能new出来,new出来的系统也不会走他的生命周期方法 。安卓中为我们提供了另一种启动服务的方式,绑定方式

绑定方式的生命周期: oncreate() onBind()  onUnbind()  onDestory()

这与startService还是有很大的不同的  




绑定Service:

 Intent service = new Intent(this, MyService.class);        ServiceConnection conn = new MyConnect();bindService(service , conn , BIND_AUTO_CREATE);    }        private class MyConnect implements ServiceConnection{@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {}@Overridepublic void onServiceDisconnected(ComponentName name) {}        }

语句解释:

bindService(service,conn,flag); 

这一服务建立绑定此方法里面有三个参数 

service意图  

conn 接收一个ServiceConnection对象 由于这是一个接口,我们没法直接创建对象,所以在下面写一个类实现这个接口

并重写里面的两个方法  onServiceConnected 在绑定成功的时候 系统会自动调用这个方法 

onServiceDisconnected在解绑的时候会调用这个方法 


那么为什么说 我们用绑定的方式来启动一个服务就可以调用 服务这个类中的方法了呢?

原因很简单,在服务的生命周期中有一个Onbind方法,以绑定的方式启动服务,才会走这个方法

public IBinder onBind(Intent intent) {return null;}
再看这个方法返回的是一个Ibinder对象,如果返回的不是空的话,那么我们就可以在前面的onServiceConnected方法中接收这个Ibinder 对象,我们就可以得到了它返回

对象的一个实例,这时候我们就可以想到用类部类的方式,去访问外部类的成员。

我们可以在服务中定义一个Ibinder的类,通过onbind返回,由于Ibinder是一个接口,我们可以继承他的实现类Binder

public class MyBinder extends Binder {}

在onbind中返回它

public IBinder onBind(Intent intent) {return new MyBinder();}
在MyConnect的 onServiceConnected方法中接收它。

public void onServiceConnected(ComponentName name, IBinder service) {MyBinder binder = (MyBinder) service;}
这样我们就得到了一个服务的类部类的对象
我们可以在内部类中定义方法去调用外部类方法  这样就可以 通过调用内部类的中的公共方法,去间接的调用外部类中的方法,这里就不一一举例

绑定服务使用完一定要调用unbindservice()方法手动关闭

绑定服务的特点:

1. 通过bindservice开启服务 走生命周期方法: onCreate()->onBind
多次调用bindservice onCreate()->onBind都只会执行一次
2. 如果service是在activity中通过bindservice方法打开的 service的生命周期就跟activity的生命周期关联起来(不求同生,但求同死)
3. 在activity退出的时候 如果不手动调用unbindservice方法会抛异常 提示serviceconnection泄露
4. unbindservice只能调用一次 多次调用会抛异常


startServicr启动服务和绑定启动服务的区别:



实际的开发中,我们既希望能够用到stratService的服务不依赖Activity运行,又希望能够调用服务中的方法,那么就需要StartService与绑定的方法相结合的混合开发

startService bindservice 先后调用 顺序无所谓 但是都要调用
停止与解绑的顺序也是无所谓的,但不一定都有要调用,还要看实际的需求。












0 0
原创粉丝点击