美文网首页
三大组件启动过程

三大组件启动过程

作者: 刘佳阔 | 来源:发表于2020-05-21 08:49 被阅读0次

title: 四大组件启动过程
date: 2020-05-05 13:13:02
tags:[android源码,]
typora-copy-images-to: ./四大组件启动过程
typora-root-url: ./四大组件启动过程


本文主要记录四大组件在framework和APP中如何交互启动.记录大概框架.不追求完备的细节.源码根据8.0

Activity启动过程

主要流程

桌面程序通常是launch.我们点击桌面图标启动app时.是由桌面launch程序通过AMS来启动Activity.这个过程大概如下

image-20200505163411999

简单说就是.launch通知AMS启动新Activity. AMS则会先暂停当前进程.然后在启动新进程.然后在新进程启动完成后在创建Activity并启动.

通过intent定位Activity

APP在安装时.通过PackageManagerService 安装.并解析出来AndroidManifest.xml里声明的所有Activity.然后吧主Activity和应用图标绑定起来.这样点击图标.就能找到对应的Activity信息.

Instrumentation启动Activity

execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target,
   Intent intent, int requestCode, Bundle options){
       int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);   
   }

这个可以说是代理类,他用来监控程序和系统间的交互.里边有针对Activity启动的监控ActivityMonitor.

他会通过AMS在客户端的代理来通知AMS启动Activity.并且传给AMS一个IBinder类的ApplicationThread,这是用来让AMS回调通知客户端进程的binder本地对象.

同时还传入一个IBinder的 token. 代表当前Activity对象在AMS中的标识. 每个启动的Activity都会有这个token.在AMS端是ActivityRecord对象.

ActivityManager 拿到AMS的代理,进行binder通信

ActivityManager.getService通过ServiceManager 拿到AMS对应的用户端binder.然后包装成AMS的客户端代理.

然后通过binder通信.调用AMS服务端.启动Activity.

image-20200505173538751

AMS端处理请求

这里内部会有几个类共同处理.而且每个版本的代码也有所不同.显示AcctivityStack来处理Activity的堆栈管理.

image-20200505173614505

PMS解析intent.找到对应的Activity.

PMS在启动的时候,已经解析了所有apk的androidManifest.xml文件.然后就知道所有intent格式对应的Activity.这里会通过PMS来找到合适的Activity.保存在ActivityInfo中.

检查调用进程的权限,封装信息

通过调用进程的ProsessRecord 来在AMS端对应一个用户进程. AMS检查调用者Launcher的进程.看是否有启动Activity的权限等. 同时封装要启动的Activity的信息为ActivityRecord.也拿到了源Activity(也就是launcher)的组件信息.

处理启动标识Intent.FLAG

这里处理各种启动模式,然后产生Activity对应的taskRecord. TaskRecord表示任务栈. 如果这个任务已经存在,就把待启动的Activity加入进去.如果新Activity对应的是新的任务.就要创建新的TaskRecord.

通过管理当前激活的Activity.上次中止的Activity.正在被中止的Activity.AMS来决定把旧Activity(launcher)执行暂停.然后在启动新的Activity.

暂停旧的activity

通过 用户进程的ApplicationThread 在AMS端的代理. AMS通知 旧Activity(launcher) 进行 pause.并把他保存在即将pause的变量中. launcher的Activity在pause后.又会通知AMS他已经pause完毕.然后AMS就会继续执行新Activity的启动过程.

启动新的Activity

先根据新Activity的进程名称判断对应进程是否启动.如果没有启动就先通过zygote来启动新进程.Activity的进程在AMS中的对应的对象是ProcessRecord. 新进程启动完成后必须在规定时间内通知AMS已经启动完成.新进程会执行ActivityThread的main方法.

新进程ActivityThread.main

通过ams.attach.通知AMS 新进程已启动完毕并传入新的ApplicationThread.创建主线程的looper和Handler.开始消息循环.

AMS继续启动Activity

AMS收到ActivityThread的att通知后.继续启动新Activity.此时新进程已经和ProcessRecord对应上.然后通过上边的ApplicationThread在AMS的代理.通知ActivityThread启动Activity.而客户端ApplicationThread收到AMS的消息后.通过向主线程looper 发送消息.启动Activity. ActivityThread收到消息后.取出要启动的Activity信息

ActivityThread 启动Activity

通过执行handleLauncherActivity,反射 创建activity所属的Application.ContextImpl.和activity.

然后执行activity.attach .使activity和WMS建立联系.获得应用窗口.

在执行activity.onCreate. 创建view树.

Activity 的启动.因为之前已经写过了.这里就简单的过一下

Service启动过程

Service的启动分为显示启动和隐式启动.并且可以运行在不同的进程.并且可以通过startService启动.和bindService启动.

activity启动服务

最开始其余 startService. 他会调用到ContextWrapper.startService.有会调用到mBase.startService(service). mBase实际是一个ComtextImpl对象.每个Activity创建时都有一个ContextImpl对象. 他又会调用AMS.startService.通过binder来启动.

AMS接收调用.启动服务

AMS内部又通过 mServices.startServiceLocked 来启动 mService 是ActiveServices类.

ActiveServices.java
startServiceLocked(){
            继续启动Service,找到 intent对应的Service.
         ServiceLookupResult res =retrieveServiceLocked(service, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true, callerFg, false);
      启动完的Service在AMS里抽象为ServiceRecord
      ServiceRecord r = res.record;
      然后是一些权限的验证处理
      
      生成了一个 ComponentName.这里一会看.
     ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);              
}

通过intent找到Service

ActivityService.java
根据intent.找到对应的Service,在AMS里.每个ServiceRecord是和ComponentName绑定的
private ServiceLookupResult retrieveServiceLocked(Intent service...){
     ServiceRecord r = null;
     找到进程对应的 ServiceMap.然后根据componentName找Service.
     ServiceMap smap = getServiceMapLocked(userId);
     final ComponentName comp = service.getComponent();
        if (comp != null) {
            r = smap.mServicesByName.get(comp);
        }
   接下来是对ServiceRecord 权限的检查,看用户进程是否可以启动这个Service
   最后封装后返回出去
  return new ServiceLookupResult(r, null); 
}

启动服务 startServiceInnerLocked

这里又调用的同名函数 bringUpServiceLocked 这是真正启懂Service的地方.然后又调度队列.启动所以等待的Service

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r...){
    //启动Service
  String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
  
  //通过队列.把等待启动的Service 再次通过startServiceInnerLocked方法启动.
    if (r.startRequested && addToStarting) {
            if (first) {
                smap.rescheduleDelayedStartsLocked();
            }
  } else if (callerFg || r.fgRequired) {
      smap.ensureNotStartingBackgroundLocked(r);
  }
}

AMS启动service对应进程

这里会看Service对应的进程是否启动.如果启动.就直接启动Service就行了.如果没有.就先启动对应的进程.进程在AMS端的代表对象是ProsessRecord

private String bringUpServiceLocked(ServiceRecord r){
        进程存在,直接启动Service
             if (r.app != null && r.app.thread != null) {
            sendServiceArgsLocked(r, execInFg, false);
            return null;
        }
        
        进程不存在.启动进程,然后在把Service放入队列,等待启动
      if (app == null && !permissionsReviewRequired) {
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    hostingType, r.name, false, isolated, false)) == null) {
            }
        } 
        
          if (!mPendingServices.contains(r)) {
            mPendingServices.add(r);
        }
}

AMS启动Service的进程,这里还是通过Process.start来启动新进程.这里和之前的Activity比较类似.也是通过zygote进程来fork出新进程.然后执行ActivityThread的main函数. 进程初始化完成后.会调用AMS.attachApplication.

这里和Activity的启动是一个方法.这次他会在这里看上边加入队列的

ActivityManagerService.java
boolean attachApplicationLocked(IApplicationThread thread,int pid) {
    又回调到了Service的方法区去处理启动Service
       // Find any services that should be running in this process...
        if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);
            } catch (Exception e) {
                badApp = true;
            }
        }          
}

Service继续启动服务

遍历pending队列,启动Service

ActivityServices.java
boolean attachApplicationLocked(ProcessRecord proc, String processName) {
        if (mPendingServices.size() > 0) {
            ServiceRecord sr = null;
                for (int i=0; i<mPendingServices.size(); i++) {
                    sr = mPendingServices.get(i);
                    realStartServiceLocked(sr, proc, sr.createdFromFg);
                }
          }
}
realStartServiceLocked里最主要的是,下边的.也就是通过binder调用用户进程启动service,通过ApplicationThread继而通知ActivityThread启动服务
app.thread.scheduleCreateService(r, r.serviceInfo,
    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),app.repProcState);

用户进程启动service

ActivityThread.java
void handleCreateService(CreateServiceData data) {
每个app都有一个loadedApk来描述应用程序的资源.
        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
        反射加载servi的类.
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {
        }

        try {
    为service创建ContextImpl上下文环境. activity也有这个.
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);
        service 绑定Application. 执行onCreate
            Application app = packageInfo.makeApplication(false, mInstrumentation);
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManager.getService());
            service.onCreate();
      ActivityThread 保存所有的service
            mServices.put(data.token, service);
            try {
       通知AMS.service启动成功     
                ActivityManager.getService().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } catch (Exception e) {
        }
    }

最后AMS里会做一些收尾工作.

附一个流程图.

Sample sequence diagram

service绑定过程

绑定的Service也是需要先启动起来的. 过程和启动服务类似. 都是从ContextImpl通知AMS开始.这里会封装一个IServiceConnection.这个IServiceConnection 是一个adil类.这是夸进程传递给AMS 的对象. 这里.APP的进程是IServiceConnection的binder服务端. AMS则持有 IServiceConnection的binder的代理端.

封装ServiceConnect.通知AMS

bindServiceCommon(Intent service, ServiceConnection conn,){
     IServiceConnection sd;
     //封装成一个IBinder.
   sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
 //  调用ams的方法.
int res = ActivityManager.getService().bindService(
                mMainThread.getApplicationThread(), getActivityToken(), service,
                service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, getOpPackageName(), user.getIdentifier());
}

AMS转给ActiveServices处理.

这里的流程比较复杂.简单说就是找到service的记录.然后和对应的Activity. 及Activity对应的process创建绑定关系ConnectionRecord并保存起来.保存在service 的ServiceRecord中.然后开始启动service

ActivityServices.java
bindServiceLocked (IApplicationThread caller, IBinder token, Intent service,  final IServiceConnection connection..){
        请求绑定服务的Activity的进程.
      final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
      请求的Activity的记录
 ActivityRecord activity = null;
    if (token != null) {
        activity = ActivityRecord.isInStackLocked(token);
    }
    //同启动服务一样.找到对应的service记录.
ServiceLookupResult res =
      retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(),
              Binder.getCallingUid(), userId, true, callerFg, isBindExternal);            
      ServiceRecord s = res.record;

        找到service对应的app绑定描述对象.表示service绑定在callerApp进程中.表示绑定在这个service上的进程.
        这是一种对应关系. 一个service可以被多个进程绑定.
      AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
      这里是描述Activity.service.process 的对应关系的一个记录.
      ConnectionRecord c = new ConnectionRecord(b, activity,
              connection, flags, clientLabel, clientIntent);
            得到connection的远程代理类.,保存上边的映射关系.
      IBinder binder = connection.asBinder();
      ArrayList<ConnectionRecord> clist = s.connections.get(binder);
            接着启动这个service
      if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
                  permissionsReviewRequired) != null) {
              return 0;
          }
       clist.add(c);
      c.conn.connected(s.name, b.intent.binder, false);

         
}

ActivityServices 继续启动

bringUpServiceLocked方法.在启动service里已经出现过了.流程就是启动service对应的进程. 进程启动完后通知AMS.AMS在通知创建Service. 直到执行service的onStart.onCreate

但是这里不太一样的是realStartServiceLocked里又会执行requestServiceBindingsLocked.进而遍历调用r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, r.app.repProcState); 也就是变量得到该service所有对应的要绑定的activity的相关记录.

private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
            throws TransactionTooLargeException {
        for (int i=r.bindings.size()-1; i>=0; i--) {
            IntentBindRecord ibr = r.bindings.valueAt(i);
            if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
                break;
            }
        }
    }

private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
            boolean execInFg, boolean rebind) throws TransactionTooLargeException {
        if ((!i.requested || rebind) && i.apps.size() > 0) {
                r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.repProcState);
            }
        return true;
}

ActivityThread处理绑定服务

这时.又通过Binder通知到了ActivityThread,他调用servic的onBind. 获取服务的binder对象.然后回传给AMS

ActivityThread.java
private void handleBindService(BindServiceData data) {
      Service s = mServices.get(data.token);
          try {
               if (!data.rebind) {
               调用了service的onBind 获取service的 binder. ActivityThread保存所有的service.
                      IBinder binder = s.onBind(data.intent);
                再把service服务的binder传递个AMS.用来发送回所有绑定到该service的进程.当然发送过去的是本地binder的代理类.
                      ActivityManager.getService().publishService(
                              data.token, data.intent, binder);
                  } else {
                      s.onRebind(data.intent);
                      ActivityManager.getService().serviceDoneExecuting(
                              data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                  }
              } catch (RemoteException ex) {
                  throw ex.rethrowFromSystemServer();
              }
          } 
      }
  }

AMS获取service的binder代理对象

ams还是把请求交个ActivityServices来处理.

ActivityServices.java
publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
        final long origId = Binder.clearCallingIdentity();
        try {
            Intent.FilterComparison filter= new Intent.FilterComparison(intent);
            IntentBindRecord b = r.bindings.get(filter);
            if (b != null && !b.received) {
            ConnectionRecord是上问我们介绍的 service和Activity和acitivity的process建立的绑定关系.
            这里拿到这个服务的所有ConnectionRecord.然后取出里边的binder代理类 IServiceConnection.
            在调用connected方法.并传入service发过来的binder. 就实现了 service和Activity的绑定.
                for (int conni=r.connections.size()-1; conni>=0; conni--) {
                    ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
                    for (int i=0; i<clist.size(); i++) {
                        ConnectionRecord c = clist.get(i);
                            c.conn.connected(r.name, service, false);
                    }
                }
            }
            serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

看到这里就明白了. activity提供的ServiceConnection 被包装成Binder后.发送到AMS中.与要绑定的Service建立关系.产生ConnectionRecord对象. 而service在对应的进程启动完成.service也启动完成后. 由AMS调用service 的onBind. service 则会提供代表他的功能的binder给AMS. 在publishServiceLocked方法中.遍历所有的ConnectionRecord, 调用conn.connected 把service 传来的binder发送给 activity里的ServiceConnection .这就实现了 activity和service的绑定.

ServiceDispatcher 处理connection

上边的 c.conn.connected(r.name, service, false); 其实是调用的的InnerConnection的方法.他是LoadApk 里ServiceDispatcher的内部类.是aidl实现的类.这里又涉及到AMS和最初 的Activity 通过aidl 方式来进程ipc.

loadApk.java
public void connected(ComponentName name, IBinder service, boolean dead) {
            if (mActivityThread != null) {
            可以看到.通过handler.把connec推到住线程来处理了.
                mActivityThread.post(new RunConnection(name, service, 0, dead));
            } else {
                doConnected(name, service, dead);
            }
        }

Runnconection 在主线程处理

简单说就是找到旧的服务.将他断开,然后执行新的connection 的onServiceConnected方法.也就是回调activity里设置的connection.

public void doConnected(ComponentName name, IBinder service, boolean dead) {
            ServiceDispatcher.ConnectionInfo old;
            ServiceDispatcher.ConnectionInfo info;

            synchronized (this) {
                }
                old = mActiveConnections.get(name);
                if (service != null) {
                    info = new ConnectionInfo();
                    info.binder = service;
                    info.deathMonitor = new DeathMonitor(name, service);
                    try {
                        service.linkToDeath(info.deathMonitor, 0);
                        mActiveConnections.put(name, info);
                    } catch (RemoteException e) {
                }
                if (old != null) {
                    old.binder.unlinkToDeath(old.deathMonitor, 0);
                }
            }
断开旧服务
            if (old != null) {
                mConnection.onServiceDisconnected(name);
            }
 开启新服务           
            if (service != null) {
                mConnection.onServiceConnected(name, service);
            }
        }
Service_Start

广播机制

广播机制是在binder的基础上实现的.广播机制存在注册中心.就是AMS.广播订阅者要先向AMS注册,并指明接受广播的类型.然后广播发送者把广播发送给AMS.再由AMS分发给对应的接收者.

广播分为有序广播和无序广播. 注册时有静态注册和动态注册.

注册广播

同样是从ContextImpl开始.先拿到主线程的handler.然后封装一个 receiverDispatcher.然后通知AMS来注册,

这个ReceiverDispatcher也是对receiver的封装.并且内部有实现aidl 的类.也就是利用binder 把代理类发给AMS.用于回调.

ContextImpl.java
 private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
            IntentFilter filter, String broadcastPermission,
            Handler scheduler, Context context, int flags) {
        IIntentReceiver rd = null;
        if (receiver != null) {
        封装一个receiverDispatcher .这个和service原理有点类似.都是发给AMS用来回调app进程的binder类
            if (mPackageInfo != null && context != null) {
                if (scheduler == null) {
                还拿到了ui线程的handler,用来向主线程发消息.
                    scheduler = mMainThread.getHandler();
                }
                rd = mPackageInfo.getReceiverDispatcher(
                    receiver, context, scheduler,
                    mMainThread.getInstrumentation(), true);
            }  
        }
        通过ams注册
            final Intent intent = ActivityManager.getService().registerReceiver(
                    mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
                    broadcastPermission, userId, flags);
            
    }

AMS中注册广播

这里有对粘性广播和普通广播的处理. 如果存在粘性广播.就把他们保存在 allSticky中.粘性广播就是广播发送在广播注册之前.但是也能收到.粘性广播会一直留在AMS中.直到下一个同类型粘性广播的到来.

public Intent registerReceiver(IApplicationThread caller, String callerPackage,
            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
            int flags) {
        ArrayList<Intent> stickyIntents = null;
        ProcessRecord callerApp = null;
                callerApp = getRecordForAppLocked(caller);

            instantApp = isInstantApp(callerApp, callerPackage, callingUid);

                找到匹配的粘性广播,保存intent
        ArrayList<Intent> allSticky = null;
        if (stickyIntents != null) {
            final ContentResolver resolver = mContext.getContentResolver();
            // Look for any matching sticky broadcasts...
            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
                Intent intent = stickyIntents.get(i);
                if (filter.match(resolver, intent, true, TAG) >= 0) {
                    allSticky.add(intent);
                }
            }
        }
                
        每个广播接收者是用BroadcastFilter 来描述.BroadcastFilter和APP传过来的InnerReceiver.而可能多个activity会使用同一个InnerReceiver.因此用集合来保存相同InneReceiver的广播接收者.
        也就是如果多个activity注册同一个广播.就会有一个InnerReceiver.对应多个BroadcastFilter.
        synchronized (this) {
            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
            if (rl == null) {
                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
                        userId, receiver);
                mRegisteredReceivers.put(receiver.asBinder(), rl);
            }
            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
                    permission, callingUid, userId, instantApp, visibleToInstantApps);
            rl.add(bf);
            if (!bf.debugCheck()) {
                Slog.w(TAG, "==> For Dynamic broadcast");
            }
            加到这里后.以后来了广播.就能找到对应的接收者.
            mReceiverResolver.addFilter(bf);

            把粘性广播返回给activity组件.也就实现了粘性广播的发送.
            if (allSticky != null) {
                ArrayList receivers = new ArrayList();
                receivers.add(bf);

                final int stickyCount = allSticky.size();
                for (int i = 0; i < stickyCount; i++) {
                    Intent intent = allSticky.get(i);
                    BroadcastQueue queue = broadcastQueueForIntent(intent);
                    每个广播对应的就是 BroadCastRecord 记录.这里是入栈.然后发送粘性广播.
                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
                            null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
                            null, 0, null, null, false, true, true, -1);
                    queue.enqueueParallelBroadcastLocked(r);
                    queue.scheduleBroadcastsLocked();
                }
            }

            return sticky;
        }
    }

发送广播

首先广播发送者把广播发送给AMS.

然后AMS找到这个广播对应的接收者,再把这个广播和接收者添加到广播队列中.并向AMS中发送一个BROADCAST_INTENT_MSG的消息.等待AMS处理.

当AMS处理到这个消息时,取出广播及接收者,分别将广播发给接收者的进程

接受者进程的ActivityThread会再次把消息发送到主线程的消息队列.等消息被处理时在交给广播接收者.

发送广播给AMS

由ContextImpl 通过binder通信把广播发给AMS.

AMS接收处理广播

broadcastIntent()

验证广播intent参数的合法性.

broadcastIntentLocked()

先是对intent里的action的不同类型的处理.如检查权限.同时对系统广播进行处理.

接着是对粘性广播的处理.所有的粘性广播都保存在一个hashmap中,并已action作为key

然后如果广播指定了接收者的Component.就从pms中找到对应的接收者,保存起来

然后在判断intent的flag 是发给动态接收者还是动态接收者以及静态接收者.静态和动态的广播接收者分别保存在不同的集合中.

针对无序广播.并且有动态接收者.在发给静态接收者.封装成BroadcastRecord,加入队列.

接着把剩下的广播都加入到BroadcastQueue,并且接收者会按照优先级排序.合并静态动态接受者.

BroadcastQueue.scheduleBroadcastsLocked

将广播加入队列后.通过handler发送给AMS的线程.可以看到广播的发送和接收是异步的

BroadcastQueue.processNextBroadcast

取出广播对象BroadcastRecord,处理无序广播队列,找到所有的无序接收者.遍历执行deliverToRegisteredReceiverLocked

然后执行有序广播的处理. 如果对应的广播接收者还没启动.则先启动对应的进程,然后继续处理下一个有序广播接收者.

入股有序广播不能再一个限定时间内处理完成.就会结束这个有序广播.

BroadcastQueue.deliverToRegisteredReceiverLocked

这里AMS把广播转发给APP所在进程.其实是通过回调ApplicationThread的scheduleRegisteredReceiver把消息发给ActivityThread的.这时发送给APP进程的是之前包装过的InntentReceiver的代理类. 他内部封装了一个广播接收者.

ActivityThread.scheduleRegisteredReceiver

这里就到了APP进程.然后由之前传入的InnerReceiver 来继续执行.

他内部会发消息给ActivityThread的主线程. 发一个runnable过去.等主线程处理这个消息. runnable是Args

的内部类.

Args.getRunnable

最后调用receiver.onReceive .也就是接收者接收到了消息.然后在回调AMS.finishReceive表示消息接收完成

contentprovider 以后再补充.他是用共享内存作为夸进程传输数据的.

相关文章

网友评论

      本文标题:三大组件启动过程

      本文链接:https://www.haomeiwen.com/subject/spbaohtx.html