安卓基础之Service

一.Service简介与进程

Service是没有前台界面的,运行与后台的组件,是用于运行需要在后台运行的代码,例如音乐播放器的后台播放和下载。相当于一个没有界面的Activity,他们的启动方式也很相似。

配置方式

Service有两种,一种是常规的开启,另一种是绑定服务,前面我们直说常规的方式,容易理解

  1. 构建类继承Service
  2. 清单文件中配置
< service android:name ="com.haha.service.MyService">
  1. 开启Service
1.直接开启服务
Intent intent = new Intent(this,MyService.class);
startService(intent);
2.通过包名开启
Intent intent = new Intent("要启动的服务的完整类名");
startService(intent);
  1. 停止服务
1.intent关闭服务:
Intent intent = new Intent(this,MyService.class);
stopService(intent);

2.在服务中调用onStopself()方法

进程

按照进程的优先级从高到低可划分为5类:

  • 前台进程 有五种状态

    • 运行着与用户交互着的Activity(onResume方法执行)
    • 拥有一个与前台Activity绑定的服务,这种情况在多线程之间通信之间有
    • 拥有一个运行“在前台”的服务——服务以startForeground方式被调用
    • 拥有一个正在执行生命周期方法之一(onCreate、onStartCommand、onDestroy)的服务
    • 运行着正在执行onRecive()方法的BroadcastReciver
  • 可见进程,有两种状态

    没有前台组件,但是仍然会影响用户在屏幕上所见内容的进程

    • 运行着不在前台运行的Activity(onPause方法被调用),例如Activity上面弹出了一个对话框,但是Activity还可见
    • 运行着被可见或者前台Activity绑定的服务
  • 服务进程
    拥有一个通过startService方法启动的服务,内存不足时可能被杀死,但当内存充足时会重启

  • 后台进程
    home键之后的进程,拥有一个对用户不可见的Activity(onStop方法已经被调用),这些进程对用户体验没有直接影响,系统可以在任意时间终止,通常有很多后台进程,他们都被放置在LRU链表里面,以确保最后一个使用的APP最后一个被关闭

  • 空进程
    不包含任何活动应用程序的进程,保留这种进程的唯一目的是用作缓存,以便下次恢复使用,这种进程在内存不足时最优先被回收

Sevice的两种模式

service的生命周期从它被创建开始,到它被销毁为止,可以有两条不同的路径。服务有两种开启方式,一个是直接 onstart,另一个是绑定服务。

1. 标准开启模式

被开启的service通过其他组件调用startService()被创建。这种 service可以无限地运行下去,必须调用 stopSelf()方法或者其他组件调用 stopService()方法来停止它。当 service被停止时,系统会销毁它。
* 生命周期:onCreate–onStartCommand–onDestroy
* 服务和启动它的Activity没有一毛钱关系

2. 绑定模式

bound service被绑定的service 是当其他组件(一个客户,此处可以理解成MainActivity)调用 bindService()方法来进行连接的。Activity可以通过一个 IBinder接口和 service进行通信。客户可以通过 unbindService()方法来关闭这种连接。一个 service可以同时和多个客户绑定,当多个客户都解除绑定之后,系统会销毁 service。

特性
* 不会把进程变成服务进程
* 生命周期:onCreate–onBind–onUnbind–onDestroy
* 不能重复绑定
* 不能重复解绑
* 服务和启动它的Activity是同生共死的

Service的这两种生命周期并不是完全分开的。 也就是说,你可以和一个已经调用了 startService() 而被开启的service 进行绑定。比如,一个后台音乐 service可能因调用 startService() 方法而被开启了,稍后,可能用户想要控制播放器或者得到一些当前歌曲的信息,可以通过 bindService() 将一个activity 和service 绑定。这种情况下, stopService()或 stopSelf() 实际上并不能停止这个 service,除非所有的客户都解除绑定。

  • 绑定服务
    bindSercvice(intent,serviceConnection,int flag)
    在其他组件中调用此方法,调用后服务内部的生命周期方法 onBind方法执行,一旦绑定成功, onBind只执行一次,再次绑定,onBind不会执行。
    serviceConnection 参数:连接对象,连接上服务之后可以调用服务的方法传入一个自定义的 ServiceConnection用来接收 Ibinder。实例化 ServiceConnection对象,重写内部方法onServiceConnected(ComponentName name,Ibinder binder),用于接收服务内部的onBind方法返回的对象。
    flag参数:一般为Bind_auto_create,如果绑定的这个服务没有创建,那么自动创建这个服务,调用生命周期方法onCreate()方法。
  • 解绑服务
    内部调用服务的生命周期方法 onUnbind(),然后调用 onDestory()销毁服务。服务只能被解除绑定一次,如果 unBindService方法被调用多次,就报错。

3.start与bind的区别

  • 通过start()直接启动服务: 服务一旦开启,就与调用者没有任何关系,调用者的activity即使退出,也不会影响后台服务的运行。
    通过bindService()绑定启动的服务,服务跟调用者不求同生但求同死。如果调用者的activity退出了,那她绑定的服务也会跟着退出。

    注意:如果一个程序的activity绑定了服务,那么这个activity退出时,会报异常,说是服务没有被释放。那么我们可以重写activity的onDestory方法,方法内调用unbindService(),去显示的解除与服务的绑定。

  • start直接启动服务的方法,调用者不能调用服务内部的方法。
    绑定服务启动服务的方法,调用者可以间接调用服务内部的方法

4.混合启动示例

  1. 构建MusicService继承Service
  2. 在客户端,此处是MainActivity中,首先开启服务 一般我们会使用start的方式,是混合开启,首先是标准开启服务(为了防止Activity退出后该服务被关闭),然后绑定开启服务(为了获取服务内的方法)
private MusicInterface mi;   
//混合启动生命周期:开启-->绑定-->解绑-->结束
Intent intent = new Intent(this,MusicService.class);
   //开启服务,把服务变为后台
  startService(intent);
   //绑定服务
  bindService(intent, new ServiceConnection() {
       @Override
       public void onServiceDisconnected(ComponentName name) {
          
      }
// 利用serviceConnection接口获取服务onbind返回的ibinder对象,
这个对象同时实现了自定义的接口,这个接口内定义了服务中的方法
      @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // TODO Auto-generated method stub
            mi = (MusicInterface) service;
           
       }
   }, BIND_AUTO_CREATE);
}
  1. 在自定义服务类中写一个中间人作用的对象,因为我们不能直接拿到服务内部的方法,服务类的onBind方法会返回一个IBind对象,我们自定义的中间人类继承该IBind借口的实现类Binder,我们可以使用一个接口来定义该中间人的方法。
public interface MusicInterface {
    void start();
    void end();
}

实现类:在自定义的Service类中复写onBind(Intent intent)方法,该方法中返回中间人对象。

public class MusicService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
          return new MusicController();
    }
    //定义中间人
    class MusicController extends Binder implements MusicInterface{
          @Override
          public void start(){
             MusicService. this.play();
         }
          @Override
          public void end(){
             MusicService. this.pose();
         }
    }
    
    
    public void play(){
         
         System. out.println("嗨起来" );
    }
    public void pose(){
         System. out.println("睡觉!" );
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值