Android Service启动流程刨析

强调一下阅读系统源码,起码要对进程间通信要了解,对binder机制非常非常清楚,binder就是指南针,要不然你会晕头转向;强行阅读,就容易睡着。

Service启动先来一张图感受一下

这张图能够说明一个大致的流程,但是服务的启动肯定不是这么简单,但是我们先简单的总结一下,逐渐深入。服务的启动形式有两种,startService()和 binderService(),我们看startService()这一种。startService是ContextWrapper里面的方法。

ContextWrapper.java

  @Override
   public ComponentName startService(Intent service) {
       return mBase.startService(service);//mBase这里指的是ContextImpl类
   }

ContextImpl.java

   @Override
    public ComponentName startService(Intent service) {
        warnIfCallingFromSystemProcess();
        return startServiceCommon(service, mUser);
    }
  private ComponentName startServiceCommon(Intent service, UserHandle user) {
        try {
            //检验Intent
            validateServiceIntent(service);
             ......
            ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), getOpPackageName(), user.getIdentifier());
             ......
            return cn;
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
    }

校验完Intent后,就调用ActivityManagerNative.getDefault(),获取一个IActivityManager对象,将启动Service这件事情交给了IActivityManager。我们看一下ActivityManagerNative的类定义

public abstract class ActivityManagerNative extends Binder implements IActivityManager

这种模式是不是非常熟悉啊? 继承了Binder,实现了一个IActivityManager接口,这个跟我们生成了远程服务通信生成的AIDL的java文件怎么那么像,现在告诉你,这就是为了远程服务通信做准备的,只是一般这种类我们都是自动生成的,ActivityManagerNative 是谷歌的人自己写

一个完整的AID L有两部分,一个是个跟服务端通信的Stub,一个是跟客户端通信的Proxy; ActivityManagerNative就是Stub,阅读源码发现在ActivityManagerNative 文件中还有个ActivityManagerProxy,那么跟客户端通信的Proxy也有了。先看IActivityManager怎么获取的

ActivityManagerNative.java

 static public IActivityManager getDefault() {
        return gDefault.get();
    }
  private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
          //获取名为"activity"的服务,服务都注册到ServiceManager来统一管理
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

就是一个单例设计模式,获取到服务对象IBinder,把这个IBinder转换成IActivityManager返回了。现在由IActivityManager启动服务。

 public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, String callingPackage, int userId) throws RemoteException
    {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        service.writeToParcel(data, 0);
        data.writeString(resolvedType);
        data.writeString(callingPackage);
        data.writeInt(userId);
        mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
        reply.readException();
        ComponentName res = ComponentName.readFromParcel(reply);
        data.recycle();
        reply.recycle();
        return res;
    }

上面说了ActivityManagerProxy作为binder通信的客户端,ActivityManagerNative 作为binder通信的服务端; mRemote.transact()是binder通信的客户端发起方法,经过binder驱动,最后回到binder服务端ActivityManagerNative的onTransact()方法。

   @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
            .......
        switch (code) {
             case START_SERVICE_TRANSACTION: {
                        data.enforceInterface(IActivityManager.descriptor);
                        IBinder b = data.readStrongBinder();
                        IApplicationThread app = ApplicationThreadNative.asInterface(b);
                        Intent service = Intent.CREATOR.createFromParcel(data);
                        String resolvedType = data.readString();
                        String callingPackage = data.readString();
                        int userId = data.readInt();
                        ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);
                        reply.writeNoException();
                        ComponentName.writeToParcel(cn, reply);
                        return true;
                    }
        }
        .......
    }

ActivityManagerNative的真正实现是ActivityManagerService,所以binder通信的服务端的ActivityManagerService,ActivityManagerProxy.startService()最终调用ActivityManagerService.startService()。注意这就跨进程了,ActivityManagerService是一个服务端的进程。看ActivityManagerService中的startService方法。

ActivityManagerService.java

 public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, String callingPackage, int userId)
            throws TransactionTooLargeException {
        ......
        synchronized(this) {
            .......
            ComponentName res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid, callingPackage, userId);
            Binder.restoreCallingIdentity(origId);
            return res;
        }
    }

ActivityManagerService没有直接干这个活,而是把这个任务交给了mService, mService 是一个 ActiveServices 对象。在早期的安卓版本中并没有这个类,后来重构时抽出这个类专门用来管理Service.

ActiveServices.java

    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, String callingPackage, int userId)
            throws TransactionTooLargeException {
              ........
              return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
    }

tartServiceInnerLocked调用了 bringUpServiceLocked(),bringUpServiceLocked()内部调用了realStartServiceLocked(),我们看realStartServiceLocked()方法。

private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
       .......
        try {
            .......
            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);
            r.postNotification();
            created = true;
        } catch (DeadObjectException e) {
            ....
        } finally {
           ....
        }
        requestServiceBindingsLocked(r, execInFg);
        updateServiceClientActivitiesLocked(app, null, true);
        // If the service is in the started state, and there are no
        // pending arguments, then fake up one so its onStartCommand() will
        // be called.
        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                    null, null));
        }
       // 进入onStartCommand()
        sendServiceArgsLocked(r, execInFg, true);
       ....
    }

这里的关键是

 app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),

app 是要运行 Service 的进程对应的 ProcessRecord 对象,代表一个应用进程; 要区分一下,一般我们都是单方向通信,客户端将处理请求发送给服务端,服务端处理后返回,如果要服务端向客户端发送一个“请求”呢?这里的thread 是一个 ApplicationThreadProxy 对象,它是应用进程的 ApplicatonThread 对象在 AMS 端的代理,AMS 靠它来和应用进程进行通信。所以AMS和应用进程可以双向通信了。

ApplicationThreadProxy.java

public final void scheduleCreateService(IBinder token, ServiceInfo info,
        CompatibilityInfo compatInfo, int processState) throws RemoteException {
    Parcel data = Parcel.obtain();
    data.writeInterfaceToken(IApplicationThread.descriptor);
    data.writeStrongBinder(token);
    info.writeToParcel(data, 0);
    compatInfo.writeToParcel(data, 0);
    data.writeInt(processState);
    try {
        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
    } catch (TransactionTooLargeException e) {
        throw e;
    }
    data.recycle();
}

执行mRemote.transact后,就会回调ApplicationThreadNative的onTransact,这是Binder的套路。

ApplicationThreadNative.java

public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    switch (code) {
    case SCHEDULE_CREATE_SERVICE_TRANSACTION: {
        data.enforceInterface(IApplicationThread.descriptor);
        IBinder token = data.readStrongBinder();
        ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data);
        CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
        int processState = data.readInt();
        scheduleCreateService(token, info, compatInfo, processState);
        return true;
    }
    ...
}

内部调用scheduleCreateService,看上面的图,可以知道,scheduleCreateService是属于ApplicatonThread的。

ApplicatonThread.java

 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);
        }

发送一个消息,这个消息都是由H类处理的,H类就是系统Hander,专门处理系统请求的; 比如一些Activity的生命周期等全在这里面。这个 H对象是在应用进程的主线程中创建的,所以最终的结果是把创建 Service 的消息传到了主线程,因此Service是运行在主线程中的。

H.java

private class H extends Handler {
          .........
            public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
             case CREATE_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
                    handleCreateService((CreateServiceData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
        }

ActivityThread.java

private void handleCreateService(CreateServiceData data) {
        .......
        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            // 反射加载Service
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {
            .......
        }
        try {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
             //创建ContextImpl对象
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);
             //创建Application对象
            Application app = packageInfo.makeApplication(false, mInstrumentation);
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManagerNative.getDefault());
            //回调onCreate方法
            service.onCreate();
            mServices.put(data.token, service);
            try {
              //调用服务创建完成
                ActivityManagerNative.getDefault().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                // nothing to do.
            }
        } catch (Exception e) {
           .......
        }
    }

到此Service的onCreate就回调了,那么onStartCommand()何时回调呢?在realStartServiceLocked中调用了sendServiceArgsLocked(r, execInFg, true),sendServiceArgsLocked与上面类似,最终也是发送了一个(SERVICE_ARGS)消息。

ApplicationThread.java

public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
            int flags ,Intent args) {
            ServiceArgsData s = new ServiceArgsData();
            s.token = token;
            s.taskRemoved = taskRemoved;
            s.startId = startId;
            s.flags = flags;
            s.args = args;
            sendMessage(H.SERVICE_ARGS, s);
        }

ActivityThread.java

private void handleServiceArgs(ServiceArgsData data) {
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                if (data.args != null) {
                    data.args.setExtrasClassLoader(s.getClassLoader());
                    data.args.prepareToEnterProcess();
                }
                int res;
                if (!data.taskRemoved) {
                //onStartCommand回调
                    res = s.onStartCommand(data.args, data.flags, data.startId);
                } else {
                    s.onTaskRemoved(data.args);
                    res = Service.START_TASK_REMOVED_COMPLETE;
                }
                QueuedWork.waitToFinish();
                try {
                    ActivityManagerNative.getDefault().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
                } catch (RemoteException e) {
                    // nothing to do.
                }
                ensureJitEnabled();
            } catch (Exception e) {
               ......
            }
        }
    }

Service的onCreate的回调和onStartCommand的回调套路是完全一样的,朋友们可以自己体会,onCreate的回调先执行scheduleCreateService()方法,最终回调Service.onCreate(); onStartCommand的回调先执行scheduleServiceArgs()方法,最终回调Service.onStartCommand()

总结一下:

IActivityManager接口中定义了AMS向应用程序(本例中即Service)提供的多种API,Activity通过ActivityManagerProxy就可以使用这些API,向AMS发出请求

所以是通过ActivityManagerProxy,调用ActivityManagerProxy的startService方法; 在内部调用transact,然后会调用ActivityManagerNative中的onTransact()方法,在该方法中,将会r完成AMS与Activity的连接并调用AMS的startService()方法,那么AMS是如何Service所在的应用程序呢?比如scheduleCreateService

原来ApplicationThreadProxy 是应用进程的 ApplicatonThread 对象在 AMS 端的代理,AMS 靠它来和应用进程进行通信。这就是Activity与AMS之间的双向Binder连接;Activity用IActivityManager提供的APIActivityManagerService提出执行某个动作的请求(本例中是启动RemoteService),ActivityManagerService通过IApplicationThread提供的API来控制Activity所在的应用程序

上面的分析省去了很多的内容,如果从进程角度看服务启动过程。

  • Process A进程: 是指调用startService命令所在的进程,也就是启动服务的发起端进程
  • system_server进程: 系统进程,是java framework框架的核心载体,里面运行了大量的系统服务,比如这里提供ApplicationThreadProxy,ActivityManagerService,这个两个服务都运行在system_server进程的不同线程中
  • Zygote进程: 是由init进程孵化而来的,用于创建Java层进程的母体,所有的Java层进程都是由Zygote进程孵化而来
  • Remote Service进程: 远程服务所在进程,是由Zygote进程孵化而来的用于运行Remote服务的进程。主线程主要负责Activity/Service等组件的生命周期以及UI相关操作都运行在这个线程; 另外,每个App进程中至少会有两个binder线程 ApplicationThread和ActivityManagerProxy

启动流程:

  • Process A进程采用Binder IPC向system_server进程发起startService请求;
  • system_server进程接收到请求后,向zygote进程发送创建进程的请求;
  • zygote进程fork出新的子进程Remote Service进程;
  • Remote Service进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
  • system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向remote Service进程发送scheduleCreateService请求;
  • Remote Service进程的binder线程在收到请求后,通过handler向主线程发送CREATE_SERVICE消息;
  • 主线程在收到Message后,通过发射机制创建目标Service,并回调Service.onCreate()方法。 到此,服务便正式启动完成。当创建的是本地服务或者服务所属进程已创建时,则无需经过上述步骤2、3,直接创建服务即可

到此这篇关于Android Service启动流程刨析的文章就介绍到这了,更多相关Android Service内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • android开发教程之开机启动服务service示例

    个例子实现的功能是:1,安装程序后看的一个Activity程序界面,里面有个按钮,点击按钮就会启动一个Service服务,此时在设置程序管理里面会看的有个Activity和一个Service服务运行2,如果手机关机重启,会触发你的程序里面的Service服务,当然,手机启动后是看不到你的程序界面.好比手机里面自带的闹钟功能,手机重启看不到闹钟设置界面只是启动服务,时间到了,闹钟就好响铃提醒. 程序代码是: 首先要有一个用于开机启动的Activity,给你们的按钮设置OnClickListener

  • Android Service启动过程完整分析

    刚开始学习Service的时候以为它是一个线程的封装,也可以执行耗时操作.其实不然,Service是运行在主线程的.直接执行耗时操作是会阻塞主线程的.长时间就直接ANR了. 我们知道Service可以执行一些后台任务,是后台任务不是耗时的任务,后台和耗时是有区别的喔. 这样就很容易想到音乐播放器,天气预报这些应用是要用到Service的.当然如果要在Service中执行耗时操作的话,开个线程就可以了. 关于Service的运行状态有两种,启动状态和绑定状态,两种状态可以一起. 启动一个Servi

  • Android 系统服务TelecomService启动过程原理分析

    由于一直负责的是Android Telephony部分的开发工作,对于通信过程的上层部分Telecom服务以及UI都没有认真研究过.最近恰好碰到一个通话方面的问题,涉及到了Telecom部分,因而就花时间仔细研究了下相关的代码.这里做一个简单的总结.这篇文章,主要以下两个部分的内容: 什么是Telecom服务?其作用是什么? Telecom模块的启动与初始化过程: 接下来一篇文章,主要以实际通话过程为例,分析下telephony收到来电后如何将电话信息发送到Telecom模块以及Telecom是

  • android Service基础(启动服务与绑定服务)

         Service是Android中一个类,它是Android 四大组件之一,使用Service可以在后台执行耗时的操作(注意需另启子线程),其中Service并不与用户产生UI交互.其他的应用组件可以启动Service,即便用户切换了其他应用,启动的Service仍可在后台运行.一个组件可以与Service绑定并与之交互,甚至是跨进程通信.通常情况下Service可以在后台执行网络请求.播放音乐.执行文件读写操作或者与contentprovider交互等.   本文主要讲述service

  • Android Service的启动过程分析

    Android Service的启动过程分析 刚开始学习Service的时候以为它是一个线程的封装,也可以执行耗时操作.其实不然,Service是运行在主线程的.直接执行耗时操作是会阻塞主线程的.长时间就直接ANR了. 我们知道Service可以执行一些后台任务,是后台任务不是耗时的任务,后台和耗时是有区别的喔. 这样就很容易想到音乐播放器,天气预报这些应用是要用到Service的.当然如果要在Service中执行耗时操作的话,开个线程就可以了. 关于Service的运行状态有两种,启动状态和绑

  • Android Service自启动注意事项分析

    本文实例分析了Android Service自启动注意事项.分享给大家供大家参考,具体如下: @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); if(intent == null) return; } @Override public void onDestroy() { super.onDestroy(); Intent intent = new Intent(

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

    最近在将 HevSocks5Client 移植到 Android 上了,在经过增加 signalfd 和 timerfd 相关的系统调用支持后,就可以直接使用 NDK 编译出 executable 了.直接的 native exectuable 在 Android 系统总还是不太方便用哦.还是做成一个 apk 吧,暂定只写一个 service 并开机自动启用,无 activity 的. Java 中调用 native 程序我选择使用 JNI 方式,直接在 JNI_OnLoad 方法中调用 pth

  • Android实现开机自动启动Service或app的方法

    本文实例讲述了Android实现开机自动启动Service或app的方法.分享给大家供大家参考,具体如下: 第一步:首先创建一个广播接收者,重构其抽象方法 onReceive(Context context, Intent intent),在其中启动你想要启动的Service或app. import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; i

  • Android ServiceManager的启动和工作原理

    ServiceManager启动 所有的系统服务都是需要在ServiceManager中进行注册的,而ServiceManager作为一个起始的服务,是通过init.rc来启动的. //system\core\rootdir\init.rc //启动的服务,这里是用的服务名称.服务名称是在对应的rc文件中注册并启动的 start servicemanager 具体的服务信息是在servicemanger.rc命名并定义的 //\frameworks\native\cmds\servicemana

  • Android Service启动流程刨析

    强调一下阅读系统源码,起码要对进程间通信要了解,对binder机制非常非常清楚,binder就是指南针,要不然你会晕头转向:强行阅读,就容易睡着. Service启动先来一张图感受一下 这张图能够说明一个大致的流程,但是服务的启动肯定不是这么简单,但是我们先简单的总结一下,逐渐深入.服务的启动形式有两种,startService()和 binderService(),我们看startService()这一种.startService是ContextWrapper里面的方法. ContextWra

  • Android Activity启动流程刨析

    目录 前言 一.Binder的基本理解 二.Activity启动的双向IPC过程 三.AMS服务注册 前言 上篇文章写到 Service 的启动过程: 相对来说Activity的启动过程比Service的启动过程更为复杂,其一Activity的生命周期方法比Service多,其二Activity具有启动模式和返回栈: 写本文的目的在于更清晰的梳理Activity的启动过程,加强自己的内功修炼,力在以最简单的方式让大家理解,跟大家一起学习 一.Binder的基本理解 Activity的启动有多次I

  • Android zygote启动流程详解

    对zygote的理解 在Android系统中,zygote是一个native进程,是所有应用进程的父进程.而zygote则是Linux系统用户空间的第一个进程--init进程,通过fork的方式创建并启动的. 作用 zygote进程在启动时,会创建一个Dalvik虚拟机实例,每次孵化新的应用进程时,都会将这个Dalvik虚拟机实例复制到新的应用程序进程里面,从而使得每个应用程序进程都有一个独立的Dalvik虚拟机实例. zygote进程的主要作用有两个: 启动SystemServer. 孵化应用

  • 一文带你看懂Android Application启动流程是怎样的

    基于Android11-API30 总览 获取applicationThread,AMS这两个Binder2.attach时,将获取applicationThread对象也传递到AMS进程,请求远程调用通知AMS应用进程想要创建Application,此时AMS为服务端 AMS收到消息,请求调用applicationThread的远程接口,此时AMS为客户端 applicationThread收到AMS的请求,通过Handler发起创建Application的处理任务,后面就没有远程接口调用了

  • Android ActivityManagerService启动流程详解

    目录 概述 AMS的启动流程 启动流程图 概述 AMS是系统的引导服务,应用进程的启动.切换和调度.四大组件的启动和管理都需要AMS的支持.从这里可以看出AMS的功能会十分的繁多,当然它并不是一个类承担这个重责,它有一些关联类. AMS的启动流程 1:SystemServer#main -> 2:SystemServer#run -> 3:SystemServiceManager#startBootstrapServices 1:首先SystemServer进程运行main函数, main函数

  • Android Service启动绑定流程详解

    目录 前言 一.Service 的启动流程 二.Service的绑定 三.Service的Context 总结 前言 本文基于Android 11,参考<Android进阶解密>一书资料.了解Service的启动和绑定流程,以及Service的Context创建过程. 由于基于分析流程,忽略很多细节分支.各位在看源码的时候,要尽可能忽略细节,分析整体流程之后,还有精力的话再去看细节.例如有些属性是在后面赋值的,如果在前面追究,难哦. 另:阅读这种流程需要很大的耐心和毅力.建议在心情愉悦想要学习

  • 全面解析Android系统指纹启动流程

    本章主要整理Android 指纹启动流程,侧重于hal和framework部分. 一.从Android系统启动流程看指纹启动流程 下图图片出处  → 第一阶段 Boot ROM,Android设备上电后,首先会从处理器片上ROM的启动引导代码开始执行,片上ROM会寻找Bootloader代码,并加载到内存.主要就是上电让系统启动. 第二阶段 Bootloader开始执行,首先负责完成硬件的初始化,然后找到Linux内核代码,并加载到内存. 启动过程中,bootloader(默认是bootable

  • Android Service完整实现流程分析

    目录 前言 一.APP侧启动Service 1.1 前台和后台启动 1.2startServiceCommon 二.系统侧分发处理Service的启动逻辑 2.1 AMS接受启动service的通知 2.2realStartServiceLocked流程 三.系统侧通知APP启动Service 四.总结 前言 一开始的目标是解决各种各样的ANR问题的,我们知道,ANR总体上分有四种类型,这四种类型有三种是和四大组件相对应的,所以,如果想了解ANR发生的根因,对安卓四大组件的实现流程是必须要了解的

  • 详解Android广播Broadcast的启动流程

    目录 正文 广播的注册 广播的解注册 广播的发送 总结 正文 本文整体阅读下来相对Activity和Service的启动流程较容易,比较贴近我们日常代码开发习惯.我们曾经有个整机项目,多个APP跨进程交互,本来想采用AIDL进行的,但最终考虑到项目工期和其他同事的能力,最终在采用广播方式进行IPC. 那时,自己也在想,这么多个APP相互发信息,数据量也大,对整机性能有影响么?会不会存在丢失和内存问题.一脸茫然,网上也不会有类似信息告诉总结这种情况,本文也不会总结这个答案,因为看完之后心中自然有数

随机推荐