安卓四大组件——Service服务(内含Binder的简单解释)

这篇具有很好参考价值的文章主要介绍了安卓四大组件——Service服务(内含Binder的简单解释)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

对于Service这个组件很多同学都会把它跟线程搞混,所以我们有必要先缕清一下基础知识。

线程:比进程更小的执行单元,每个进程可能有多条线程,线程需要放在一个 进程中才能执行,线程由程序负责管理,而进程则由系统进行调度!


多线程的理解:并行执行多个条指令,将CPU时间片按照调度算法分配给各个 线程,实际上是分时执行的,只是这个切换的时间很短,用户感觉到"同时"而已!

进程和程序的区别:程序只是一个静态的指令集合,而进程是一个正在系统中活动的指令集合。

那Service跟线程有什么区别或者联系呢。其实一点联系都没有,Service只是一个支持长时间挂在后台运行的组件而已,在Service中可以开设多线程,其实从层次来说,Service跟线程就不是一个层面上的东西。

在安卓中一般Service都采用一个轮询的方式进行运行。轮询(Polling)是一种CPU决策如何提供周边设备服务的方式,又称“程控输入输出”(Programmed I/O)。轮询法的概念是:由CPU定时发出询问,依序询问每一个周边设备是否需要其服务,有即给予服务,服务结束后再问下一个周边,接着不断周而复始。 

Service的启动方式

Android中使用Service的方式有主要有三种,第三种主要是第一第二种的结合使用:

BindService()启动Service

StartService()启动Service

还有一种不常使用的便是在service启动之后再去绑定service

创建Service

创建Service的方式非常简单,Android已经将Service封装成了一个很成熟的类,我们自定义Service只需要继承Service类即可。下面将给出一段示例代码,但是值得注意的是,我这里继承的类并不是Service类,而是IntentService。

这个IntentService看上去可能会有点懵逼,其实该类跟Service类在用法上区别不大,但是该类在很大程度上优化了Service类的使用。使用Service一般都不进行耗时操作,如若超过一秒没有响应就会发生报错,而IntentService则很好的解决了这个问题,该类让Service进行一些耗时操作成了可能,该类在启动服务之后会回调onHandleIntent方法,该方法相当于开多了一个子线程,所有耗时操作都在子线程中完成。该类其实本质上就是对Handle的封装。对于IntentService的具体介绍后面的文章会进一步描述,现在只需要知道创建Service的方法即可。

首先大概得介绍一下这个类里面的每个方法的用途。

onCreate:该方法只会在整个生命周期中调用一次,在第一次被创建后会立即回调该方法,后续无论绑定多少次Service或者启动多次Service,都不会在调用这个方法,而是会一直复用一开始创建的Service方法。

onDestory:当Service被关闭时会调用这个方法,该方法一样只会调用一次。

onStartCommand:这个方法只会在startService方式启动的情况下才会被回调,如若客户端多次调用startService,一样不会创建新的service对象,只会接着服用一开始已经创建好的对象。

onBind:这个方法会在通过bindService启动Service,绑定的时候进行调用,值得注意的是该方法是可以返回一个Binder对象的,这个Binder对象主要是进行进程之间的通信。

public class ThirdService extends IntentService {
    private final static String TAG="ThirdService";
    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public ThirdService(String name) {
        super(name);
    }

    public ThirdService() {
        super(TAG);
    }

    public class MyBinder extends Binder{
        public String getTag(){
            return TAG;
        }
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Log.d(TAG,"onHandleIntent");
    }

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        Log.d(TAG,"onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG,"onBind");
        return new MyBinder();
    }

    @Override
    public void onCreate() {
        Log.d(TAG,"onCreate");
        super.onCreate();
    }
}

 

BindService

第一种直接使用BindService启动Service:bindService模式下的Service是与调用者相互关联的,可以理解为 "一条绳子上的蚂蚱",要死一起死,在bindService后,一旦调用者销毁,那么Service也立即终止!
简单来说就是,当只有一个客户端绑定了一个service的情况下,当客户端关闭该service也会被关闭。

如果我们解除与服务的绑定,只需调用unbindService(),此时onUnbind和onDestory方法将会被调用!

核心代码:

bindService(Intent Service,ServiceConnection conn,int flags)

service:通过该intent指定要启动的Service
conn:ServiceConnection对象,用户监听访问者与Service间的连接情况, 连接成功回调该对象中的onServiceConnected(ComponentName,IBinder)方法; 如果Service所在的宿主由于异常终止或者其他原因终止,导致Service与访问者间断开 连接时调用
flags:指定绑定时是否自动创建Service(如果Service还未创建), 参数可以是0(不自动创建),BIND_AUTO_CREATE(自动创建)

//目前安卓版本已经不允许通过隐式调用Service,只能进行显式调用
Intent intent1=new Intent(FunctionsActivity.this, ThirdService.class);
bindService(intent1,serviceConnection, Service.BIND_AUTO_CREATE);

-------------------------------------------------------------------------------------------

serviceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                String tag = ((ThirdService.MyBinder) service).getTag();
                Log.d(TAG,tag);
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        };

这时候回调函数的调用顺序是 ThirdService#onCreate -> ThirdService#onCreate -> serviceConnection #onServiceConnected。

值得注意的是,onServiceDisconnected这个回调方法,当你主动调用unBindService这个方法解绑服务的时候,并不会回调这个方法。

还有一个Binder的问题,这是一种安卓特有的进程间通信机制,具体的后文会有一个总结。坚持一下,再看一会就到了。

startService

第二种直接使用startService启动Service:首次启动会创建一个Service实例,依次调用onCreate()和onStartCommand()方法,此时Service 进入运行状态,如果再次调用StartService启动Service,将不会再创建新的Service对象, 系统会直接复用前面创建的Service对象,调用它的onStartCommand()方法!
但这样的Service与它的调用者无必然的联系,就是说当调用者结束了自己的生命周期, 但是只要不调用stopService,那么Service还是会继续运行的!所以一般在使用这种方式启动服务的时候,一定要在活动生命周期摧毁的时候进行stopService操作。

//一样需要显式调用
Intent intent2=new Intent(FunctionsActivity.this, ThirdService.class);
startService(intent2);

StartService启动Service后bindService绑定

其实看这个标题描述就大概知道这个方式在代码上怎么表现。如果一个Service已经通过startService启动,接着再通过bindService进行绑定,这时候再调用unbindService解绑,最后再通过bindService绑定,这时候我们就得清晰的知道他的一个回调函数的走向了,搞懂这点基本上在流程上就彻底通了。

onCreate( )->onStartCommand( )->onBind( )->onUnbind( )->onRebind( )

这里值得注意的是,在我们学习BindService的时候,了解到当调用onUnbind的时候,Service会立刻进行onDestory的调用,但是这里并不会,在这里我们本来一开始进行了startService启动服务,所以Service就算解绑也不会立刻结束。

这里另外补充一点,可能大家会觉得第三种启动方式很鸡肋,感觉没有什么实用的价值。但是转念一想,这些东西如果没有实用价值怎么可能会被封装起来呢,对吧。有没有发现通过startService方式启动的service无法直接获取Binder,无法做到进程间的通信,而通过这种方式,startService也能进行Binder的通信!

Binder

上面一直在说的通信方式Binder到底是什么呢?Binder其实在日常的使用中还是很常见的,所以有必要好好学习一下。

首先我们要知道一个前提条件,进程与进程之间是无法直接通信的。故此Linux系统提供了一种RPC通信模型。RPC模型主要是以一种迁移线程的方式推进。迁移线程允许线程从一个任务“移动”到另外一个任务。在RPC期间,内核不会在其IPC(进程间通信)内核调用时阻塞客户机线程,而是安排他在服务器代码中继续执行。

其实上面还是有点生硬解释,如果你们有学习过Java的后端知识,学习到springcloud的时候,会发现不同微服务之间明明不同服务器却能互相调用服务的方法。这个RPC大概就是这个作用,在两个本来无法通信独立的进程之间搭起了一个桥梁,达到通信的作用。

RPC与IPC之间的区别

相同点:二者之间都可用于进程之间

不同点:RPC强调的是调用,一个进程直接调用另一个进程的方法,而IPC仅仅完成进程之间的互通信,没有函数调用功能。

总结来说,RPC其实就是添加了进程之间的函数调用功能的IPC

Android系统RPC与Binder的关系

Android的RPC并不需要实现不同主机或者不同操作系统间的远程调用。跟上面一样,Andorid的RPC=Binder进程间通信+在Binder基础上简历起来的进程间函数调用机制。

对于Binder的使用,上面的代码事例中还是比较完整,可以划步到上面仔细看看哦,这边就不具体说了。文章来源地址https://www.toymoban.com/news/detail-471650.html

到了这里,关于安卓四大组件——Service服务(内含Binder的简单解释)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android四大组件之服务

    为什么要使用服务呢? 从上面的文字说,我们知道这个服务是用于执行长期后台运行的操作。有些时候,我们没有界面,但是程序仍然需要工作。比如说,我们播放音乐,在后台播放音乐。比如说,我们下载任务,在后台下载文件。这些都是没有界面 的后台运行程序,这些

    2024年02月14日
    浏览(62)
  • Android Binder通信原理(三):service注册

    源码基于: Android R 上一文中详细分析了 servicemanger 的启动流程 ,我们知道 servicemanager 作为 binder 机制中的一个特殊service,利用service map管理所有service,也是所有binder 通信的入口。 本文着重分析 service 的注册流程,下一文着重分析service 的获取流程。 Binder 中每个进程都会有

    2024年02月11日
    浏览(28)
  • 【安卓源码】Binder机制3 -- Binder线程池

    Binder本身是C/S架构,就可能存在多个Client会同时访问Server的情况。 在这种情况下,如果Server只有一个线程处理响应,就会导致客户端的请求可能需要排队而导致响应过慢的现象发生。解决这个问题的方法就是引入多线程。【多个客户端不同线程去请求,服务端需要使用多线程

    2023年04月27日
    浏览(47)
  • Android Binder通信原理(五):Java 端的service 注册和获取

    源码基于: Android R 在阐述相关的知识点,先整理个框架图,后面带着框架图来分析过程: Java 端对于binder 使用大致分为: Java client Java service Java client native service Java 端service 的注册使用 ServiceManager.addService() Java 端service 的获取使用 ServiceManager.getService() 入口都是通过 Servic

    2024年02月11日
    浏览(30)
  • 【Python入门】Python搭建编程环境-安装Python3解释器(内含Windows版本、MacOS版本、Linux版本)

    前言 📕作者简介: 热爱跑步的恒川 ,致力于C/C++、Java、Python等多编程语言,热爱跑步,喜爱音乐的一位博主。 📗本文收录于Python零基础入门系列,本专栏主要内容为Python基础语法、判断、循环语句、函数、函数进阶、数据容器、文件操作、异常模块与包、数据可视化等,

    2024年02月03日
    浏览(40)
  • 创建并美化Github主页(内含组件)

    目录 1、创建仓库 2、美化 1、包含多种  2、活动统计图  3、资料奖杯  4、文字的打字特效  5、中文网站卡片  6、贪吃蛇贡献图  7、可参考的页面 最近有想要写开源的打算了,计划了好久好久好久,不知道写啥(目前仍然不知道)…… 俗话说人活一张脸,写开源项目,首页是

    2024年02月02日
    浏览(37)
  • Android 四大组件之广播

    在Android应用开发中,广播组件是一项关键技术,被广泛用于各种任务和场景。无论是发送系统级广播,还是在应用内部实现组件间的通信,了解和掌握广播组件的工作原理和使用方法对于每个Android开发者来说都是至关重要的。本文旨在帮助你深入了解Android广播组件,并给出

    2024年02月06日
    浏览(32)
  • [Android 四大组件] --- BroadcastReceiver

    BroadcastReceiver(广播接收器)即广播,是一个全局的监听器。 Android 广播分为两个角色:广播发送者、广播接受者。 广播按照类型分为两种,一种是全局广播,另一种是本地广播 全局广播:就是发出的广播被其他任意应用程序接收,或者可以接收来自其他任意应用程序的广播

    2024年02月10日
    浏览(31)
  • [Android 四大组件] --- Activity

    ​​Activity​​是一个Android的应用组件,它提供屏幕进行交互。每个Activity都会获得一个用于绘制其用户界面的窗口,窗口可以充满哦屏幕也可以小于屏幕并浮动在其他窗口之上。 一个应用通常是由多个彼此松散联系的Activity组成,一般会指定应用中的某个Activity为主活动,也

    2024年02月10日
    浏览(32)
  • Mybatis四大组件

    SqlSessionFactoryBuild、SqlSessionFactory、SqlSession、Mapper。 Executor、StatementHandler、ParameterHandler、ResultSetHandler。 这里阐述一下上图的流程 执行器Executor,执行器负责整个SQL执行过程的总体控制。 语句处理器StatementHandler,语句处理器负责和JDBC层具体交互,包括prepare语句,执行语句,

    2024年01月25日
    浏览(19)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包