我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android Service怎么实现

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android Service怎么实现

今天小编给大家分享一下Android Service怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

    一.APP侧启动Service

    其实启动service和启动Activity是很相似的,都是APP通知系统侧,由系统侧完成的整个流程。

    1.1 前台和后台启动

    无论是Activity,还是service,还是Application,都继承自Context的抽象类,所以可以使用Context的各种功能,就比如这了要介绍的启动前台/后台service。

    Context在安卓中,使用了一种典型的代理模式,我们调用的startService或者startForegroundService方法,最终都会委托给ContextImpl中的startService和startForegroundService来处理的。我们就来看下ContextImpl中的这两个方法:

    @Override    public ComponentName startService(Intent service) {        warnIfCallingFromSystemProcess();        return startServiceCommon(service, false, mUser);    }    @Override    public ComponentName startForegroundService(Intent service) {        warnIfCallingFromSystemProcess();        return startServiceCommon(service, true, mUser);    }

    果然和我猜测的差不多,无论前台还是后台启动,其实最终都会走到一个方法中,只是配置参数的区别而已。最终都会走执行startServiceCommon方法。

    1.2startServiceCommon

    该方法中,通过binder通知系统的AMS完成对应的service的启动操作:

     ComponentName cn = ActivityManager.getService().startService(                    mMainThread.getApplicationThread(), service,                    service.resolveTypeIfNeeded(getContentResolver()), requireForeground,                    getOpPackageName(), getAttributionTag(), user.getIdentifier());

    接下来,我们就看下系统侧是如何处理Service启动流程的。

    二.系统侧分发处理Service的启动逻辑

    系统侧的处理我主要分为3块来讲:

    系统接受APP侧的通知并转发

    系统侧委托ActiveServices负责完成的处理流程

    收到APP侧执行完成的回调,进行收尾操作

    2.1 AMS接受启动service的通知

    APP侧持有system_server进程的binder,上面讲到,它会通过binder方法startService完成对系统侧的通知。所以AMS的startService会收到这个通知。

    我们看下代码,发现AMS会把整个service的逻辑全部交由ActiveServices来处理,代码如下:

     try {                res = mServices.startServiceLocked(caller, service,                        resolvedType, callingPid, callingUid,                        requireForeground, callingPackage, callingFeatureId, userId);            } finally {                Binder.restoreCallingIdentity(origId);            }

    系统代码startServiceLocked方法中,代码虽然很长,但是却遵循着一个不变的宗旨:位语句,即前面处理各种异常的分支逻辑,把核心流程留到方法的最终来处理。

    所以我们直接看startServiceLocked方法的最后一部分即可:

    final ComponentName realResult =                startServiceInnerLocked(r, service, callingUid, callingPid, fgRequired, callerFg,                allowBackgroundActivityStarts, backgroundActivityStartsToken);

    startServiceInnerLocked方法中,处理逻辑也是比较简单的,最终会交给bringUpServiceLocked方法来进行处理。而bringUpServiceLocked方法中则最终会交给realStartServiceLocked完成整个流程。好像系统代码都喜喜欢用realStart,Activity启动的流程中也有一个方法叫realStartActivity。

    2.2realStartServiceLocked流程

    realStartServiceLocked方法中,我们总结为三个流程:

    bumpServiceExecutingLocked,启动超时检查。

    thread.scheduleCreateService通知APP一侧去创建Service。

    sendServiceArgsLocked通知APP执行Service的生命流程。

    private void realStartServiceLocked(ServiceRecord r, ProcessRecord app,            IApplicationThread thread, int pid, UidRecord uidRecord, boolean execInFg,            boolean enqueueOomAdj) throws RemoteException {        //1.启动超时检查        bumpServiceExecutingLocked(r, execInFg, "create", null );        ...        //2.通知APP创建service            thread.scheduleCreateService(r, r.serviceInfo,                    mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),                    app.mState.getReportedProcState());            r.postNotification();            created = true;        ...        //3.通知执行service生命流程        sendServiceArgsLocked(r, execInFg, true);       ...    }

    三.系统侧通知APP启动Service

    一般情况下,APP侧会收到系统侧发过来两种类型的通知,

    第一种:创建Service的任务通知

    第二种:执行Service生命流程的通知,通知Service执行onStartCommand方法。

    ApplicationThread接受通知并创建Service

    系统侧持有APP侧的binder,会通过scheduleCreateService这个binder方法通知APP一侧进行相应的操作。而APP侧,完成这个工作接收的就是ApplicationThread中的scheduleCreateService方法。该方法收到通知后,通过handler切换到主线程处理:

     public final void scheduleCreateService(IBinder token,                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {            updateProcessState(processState, false);            CreateServiceData s = new CreateServiceData();            s.token = token;            s.info = info;            s.compatInfo = compatInfo;            sendMessage(H.CREATE_SERVICE, s);        }

    handle中,会切换到主线程执行ActivityThread的handleCreateService方法。

    主要执行了如下的几段逻辑:

    如果是首次创建App进程的话,则需要重新创建Application;

    创建Service对象;

    调用service的attach方法进行关联;

    调用service的onCreate生命周期方法;

    创建完成后,通过serviceDoneExecuting通知系统侧创建完成。

    try {            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);            Application app = packageInfo.makeApplication(false, mInstrumentation);            final java.lang.ClassLoader cl;            if (data.info.splitName != null) {                cl = packageInfo.getSplitClassLoader(data.info.splitName);            } else {                cl = packageInfo.getClassLoader();            }            service = packageInfo.getAppFactory()                    .instantiateService(cl, data.info.name, data.intent);            ContextImpl context = ContextImpl.getImpl(service                    .createServiceBaseContext(this, packageInfo));            if (data.info.splitName != null) {                context = (ContextImpl) context.createContextForSplit(data.info.splitName);            }            if (data.info.attributionTags != null && data.info.attributionTags.length > 0) {                final String attributionTag = data.info.attributionTags[0];                context = (ContextImpl) context.createAttributionContext(attributionTag);            }            // Service resources must be initialized with the same loaders as the application            // context.            context.getResources().addLoaders(                    app.getResources().getLoaders().toArray(new ResourcesLoader[0]));            context.setOuterContext(service);            service.attach(context, this, data.info.name, data.token, app,                    ActivityManager.getService());            service.onCreate();            mServicesData.put(data.token, data);            mServices.put(data.token, service);            try {                ActivityManager.getService().serviceDoneExecuting(                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);            } catch (RemoteException e) {                throw e.rethrowFromSystemServer();            }        }

    ApplicationThread接受通知并执行Service的生命流程

    同样的,这里完成接受的是,仍然是ApplicationThread中的方法。这个流程中的接受方法是scheduleServiceArgs方法。

    ApplicationThread中,收到通知后,通过handler把任务转交到主线程。

     public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {            List<ServiceStartArgs> list = args.getList();            for (int i = 0; i < list.size(); i++) {                ServiceStartArgs ssa = list.get(i);                ServiceArgsData s = new ServiceArgsData();                s.token = token;                s.taskRemoved = ssa.taskRemoved;                s.startId = ssa.startId;                s.flags = ssa.flags;                s.args = ssa.args;                sendMessage(H.SERVICE_ARGS, s);            }        }

    接下来handler中切换到主线程会执行ActivityThread的handleServiceArgs方法。

    handleServiceArgs方法主要会完成以下几件事:

    找到对应的service,调用起onStartCommand方法;

    通知系统侧回调完成。

    private void handleServiceArgs(ServiceArgsData data) {        CreateServiceData createData = mServicesData.get(data.token);        Service s = mServices.get(data.token);        if (s != null) {            try {                if (data.args != null) {                    data.args.setExtrasClassLoader(s.getClassLoader());                    data.args.prepareToEnterProcess(isProtectedComponent(createData.info),                            s.getAttributionSource());                }                int res;                if (!data.taskRemoved) {                    res = s.onStartCommand(data.args, data.flags, data.startId);                } else {                    s.onTaskRemoved(data.args);                    res = Service.START_TASK_REMOVED_COMPLETE;                }                QueuedWork.waitToFinish();                try {                    ActivityManager.getService().serviceDoneExecuting(                            data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);                } catch (RemoteException e) {                    throw e.rethrowFromSystemServer();                }            } catch (Exception e) {                if (!mInstrumentation.onException(s, e)) {                    throw new RuntimeException(                            "Unable to start service " + s                            + " with " + data.args + ": " + e.toString(), e);                }            }        }    }

    以上就是“Android Service怎么实现”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    Android Service怎么实现

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    Android Service怎么实现

    今天小编给大家分享一下Android Service怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一.APP侧启动S
    2023-07-04

    怎么在Android中实现Service与Activity的通信

    本篇文章为大家展示了怎么在Android中实现Service与Activity的通信,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。第一种方式:通过MyBinder方式调用Service方法MainA
    2023-05-30

    android中service的实现方法是什么

    在Android中,有两种常见的实现Service的方法:1. 继承Service类:创建一个继承自Service类的子类,然后重写其中的方法。这种方法适用于需要自定义Service逻辑的情况。常见的重写方法包括:- onCreate():
    2023-09-11

    Android实现Service重启的方法

    本文实例讲述了Android实现Service重启的方法。分享给大家供大家参考。具体如下: 做APP的时候,我们可能需要一个后台服务一直在运行着,得用到Service组件。 但服务可能在如下情况被杀死: A.用户手动点击停止。 B.采用第三
    2022-06-06

    Android使用Messenger实现service与activity交互

    service与activity交互的方式有多种,这里说说使用Messenger来实现两者之间的交互。 Service程序:public class MessengerService extends Service {final Messe
    2022-06-06

    Android实现Service在前台运行服务

    前言在做手机音乐播放器的时候,让我非常苦恼的一件事就是手机有清理内存的软件,比如百度,360等等,一点击清理音乐就停止播放了,去后台查看发现Service已经被停止并重新启动了,这显然不是我想要的,我希望音乐能够在后台播放,并且自己能控制什
    2023-05-30

    Service与Activity的相互通信怎么在Android项目中实现

    今天就跟大家聊聊有关Service与Activity的相互通信怎么在Android项目中实现,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。在Android中,Activity主要负责
    2023-05-31

    怎么在Android中使用Service方法实现本地音乐播放

    这篇文章给大家介绍怎么在Android中使用Service方法实现本地音乐播放,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1、主Activity控制音乐 的开始、暂停、停止、退出空能,(具体实现在下面MusicSer
    2023-06-14

    Android实现从activity中停止Service的方法

    本文实例讲述了Android实现从activity中停止Service的方法。分享给大家供大家参考,具体如下: 1、在AndroidManifest.xml注册Service2022-06-06

    Android使用Service及BroadcastReceiver实现音乐播放器

    播放音乐,我们需要在AndroidManifest.xml文件添加权限创建Service,需要在AndroidManifest.xml文件配置现在我们创建了一个叫做MusicService的Service,它是继承Service类的 话不多
    2022-06-06

    Android 两个Service的相互监视实现代码

    两个Service之间相互监视的实现 在实际开发中可能需要用到两个Service相互监视的情况,本示例就是实现此功能以作参考。 服务A:public class ServiceA extends Service {private stati
    2022-06-06

    Android IPC机制绑定Service实现本地通信

    **写作原因:跨进程通信的实现和理解是Android进阶中重要的一环。下面博主分享IPC一些相关知识、操作及自己在学习IPC过程中的一些理解。 这一章是为下面的Messenger和AIDL的使用做准备,主要讲解Android Servic
    2022-06-06

    Android Service服务不被停止详解及实现

    Android Service服务一直运行: 最近有个项目需求是后台一直运行Service,但是一般都是可以手动停止的,这里就提供一个方法让Android Service服务一直运行,大家看下。 1.设置->应
    2022-06-06

    Android中实现开机自动启动服务(service)实例

    最近在将 HevSocks5Client 移植到 Android 上了,在经过增加 signalfd 和 timerfd 相关的系统调用支持后,就可以直接使用 NDK 编译出 executable 了。直接的 native exectuab
    2022-06-06

    Android编程实现开始及停止service的方法

    本文实例讲述了Android编程实现开始及停止service的方法。分享给大家供大家参考,具体如下: 开始一个Service 你可以从一个activity或从其它应用的组件通过传递一个Intent(指定了要启动的服务)给startServi
    2022-06-06

    android使用Messenger绑定Service的多种实现方法

    如果你需要在不同进程间通信,你可以在Service中使用Messenger来实现进程中通信。 如果使用这种方式,Service中需要定义一个Handler对象(负责对客户端发送过来的Message进行响应)。 Messenger可以共享给c
    2022-06-06

    Android开发之Service用法实例

    本文实例讲述了Android开发之Service用法。分享给大家供大家参考。具体分析如下: Service是一个生命周期较长而且没有界面的程序。 下面通过一个播放mp3的例子来学习。 先看MainActivity.javapackage c
    2022-06-06

    Android服务Service怎么配置和使用

    要配置和使用Android服务Service,可以按照以下步骤进行操作:在AndroidManifest.xml文件中注册Service:创建一个继承自Service
    Android服务Service怎么配置和使用
    2024-03-08

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录