android学习笔记之五:四大组件之Service

本文介绍了Android中的服务与进程概念,包括服务的启动方式、进程的优先级与生命周期,并详细讲解了通过bindService方式调用服务的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.服务和进程优先级

  • 什么是服务?

    • windows下的服务:没有界面、长期运行在后台的应用程序;
    • android下的服务:应用程序的一个组件,没有界面activity,长期运行在后台;
  • 进程
    • 进程是应用程序运行的载体。
    • 进程与应用程序之间的关系: linux操作系统创建一个进程,这个进程负责运行dalvik虚拟机,Android的应用程序都是运行在dalvik虚拟机上的。
  • 进程的生命周期:

    • 应用程序一启动的时候就创建了进程;
    • 当应用程序退出的时候进程并没有退出;
    • 只有手工停止这个进程,进程才会结束;

操作系统尽量长时间的运行应用程序的进程,为了保证内从空间不被大量占用,它会按照进程的优先级,从低到高一级一级的杀死进程,直到内存空间被清理的差不多。

  • 进程的等级:

    1. Foreground process(前台进程)
      应用程序,用户当前操作所必须的进程。

      满足以下任一条件时,进程被视作处于前台进程:

      其中运行着正与用户交互的Activity(Activity对象的 onResume() 方法已被调用)。

      其中运行着被正与用户交互的activity绑定的服务Service。

      其中运行着“前台”服务Service——服务以startForeground()方式被调用。

      其中运行着正在执行生命周期回调方法(onCreate()、onStart()或onDestroy())的服务Service。

      其中运行着正在执行onReceive()方法的BroadcastReceiver。

    2. Visible process (可视进程)
      应用程序的ui界面,用户还可以看到,但是不能操作了。

      满足以下任一条件时,进程被认为是可见的:

      其中运行着不在前台的Activity,但用户仍然可见到此activity(onPause()方法被调用了)。

      其中运行着被可见(或前台)activity绑定的服务Service。

      可见进程被认为是非常重要的进程,除非无法维持所有前台进程同时运行了,它们是不会被终止的

    3. Service process (服务进程)
      应用程序没有界面,但是有一个后台的服务还处于运行状态。

      此进程运行着由startService()方法启动的服务,它不会升级为上述两级别。

      尽管服务进程不直接和用户所见内容关联,但他们通常在执行一些用户关心的操作(比如在后台播放音乐或从网络下载数据)。

      除非内存不足以维持所有前台、可见进程同时运行,系统会保持服务进程的运行。

    4. Background process(后台进程)

      应用程序没有服务处于运行状态,应用程序被最小化了,activity执行了onstop方法。

      包含目前用户不可见activity(Activity对象的onStop()方法已被调用)的进程。

      这些进程对用户体验没有直接的影响,系统可能在任意时间终止它们,以回收内存供前台进程、可见进程及服务进程使用。

    5. Empty process (空进程)
      没有任何组件运行,所有的activity都关闭了,任务栈清空了。

      不含任何活动应用程序组件的进程。

      保留这种进程的唯一目的就是用作缓存,以改善下次在此进程中运行组件的启动时间。

      为了在进程缓存和内核缓存间平衡系统整体资源,系统经常会终止这种进程。

2.服务两种启动方式

  • startService
    • 开始服务,会使进程变成为服务进程
    • 启动服务的activity和服务不再有关系
  • bindService
    • 绑定服务不会使进程变成服务进程
    • 绑定服务,是activity与服务建立连接,如果activity销毁了,服务也会被解绑并销毁,但是如果服务被销毁,activity不会被销毁

3.startService开启服务

  • startService:开启并创建一个服务,服务长期运行在后台;
    • 服务被创建时调用onCreate、onStartCommand;
    • 服务只能被创建一次,但是可以开启多次onStartCommand;
    • 服务被开启后,会在设置页面里面的running里面找得到这个服务;
    • 服务会在后台长期运行,直到用户手工停止或者调用StopService方法,服务才会被销毁。
  • stopService:停止服务,销毁服务对象;
    • 服务只能被停止一次;
    • 没有onPause、onStop、onResume、onRestart方法,因为service没有界面,长期运行在后台。
  • 生命周期:
    • onCreate:服务被创建的时候调用这个方法
    • onStartCommand:开启服务
    • onDestroy:销毁服务
      onCreate->onStartCommand ->onDestroy

3.bindService方式开启服务

  • bindService:绑定服务,可以调用服务里面的方法;
    • 服务是在被绑定的时候被创建,调用oncreate、onbind方法;
    • 服务不能再设置页面里面找到 ,相当于是一个隐形的服务
    • 当绑定服务的activity销毁的时候,服务也销毁。
  • unBindService:解除服务,停止服务里面的方法;
    • 服务只能被解除一次,解除绑定的时候调用onUnbind、onDestrory方法,如果多次解除绑定会抛出异常;
  • 生命周期:

    • onBind:服务被绑定调用这个方法
    • onUnbind:服务解除绑定调用这个方法

    onCreate->onBind->onUnbind->onDestroy

  • 为什么要引入bindService

    目的为了调用服务里面的方法

  • 4.通过bindservice方式调用服务方法里面的过程

    步骤:
    1、在服务类中创建一个代理人MyBinder,继承了Binder,Binder实现了IBinder接口:

    public class MyBinder extends Binder{
    }

    2、在服务类里面创建了一个MyBinder的成员变量:

    private MyBinder myBinder;

    3、在MyBinder类中写一个方法用于调用服务的业务逻辑方法:

    public class MyBinder extends Binder{
        //使用代理人调用服务里的方法
        public void callMethodInService(){
            methodInService();
        }       
    } 

    4、在activity中bindService时,定义了ServiceConnection,在这个连接中实现了两个方法:

    private class MyConn implements ServiceConnection {
        /**
         * 服务连接成功时调用这个方法
         */
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //得到服务绑定成功后返回的代理人MyBinder对象
            myBinder = (MyBinder) service;
        }
    
        /**
         * 服务断开成功时调用这个方法
         */
        @Override
        public void onServiceDisconnected(ComponentName name) {
    
        }
    }

    5、绑定服务

    Intent intent = new Intent(this, TestService.class);
    //绑定服务时要求传入一个ServiceConnection实现类的对象
    bindService(intent, new Myconn(), BIND_AUTO_CREATE);

    6、通过在activity中通过代理人调用服务的业务逻辑方法:

    myBinder.callMethodInService();

    5.绑定服务抽取接口

    接口(interface): 对外开放暴露的功能,但是不会暴露功能实现的细节;
    让代理人实现服务接口的目的:只对外暴露接口里面业务逻辑方法,隐藏代理人里面的其他方法;

    步骤:

    1、创建一个服务的接口类,里面包含需要对外暴露的业务逻辑方法:

    public interface IService {
        public void callMethodInService();
    }

    2、让服务中的代理人实现服务的接口类:

    private class MyBinder extends Binder implements IService{
    
        //(实现服务接口中的方法)使用代理人调用服务里的方法
        public void callMethodInService(){
            methodInService();
        }
    }

    3、在activity中声明接口的成员变量:

    private IService myBinder;

    4、强制转换成服务的接口类型

    private class MyConn implements ServiceConnection {
    
        /**
         * 服务连接成功时调用这个方法
         */
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //强制转换成服务的接口类型
            myBinder = (IService) service;
        }
    }

    5、绑定服务

    Intent intent = new Intent(this, TestService.class);
    //绑定服务时要求传入一个ServiceConnection实现类的对象
    bindService(intent, new Myconn(), BIND_AUTO_CREATE);

    6、在activity中通过接口的成员变量调用服务的业务逻辑方法:

    public void call(View view){
        myBinder.callMethodInService();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值