ActivityManagerService启动流程

基于Android 6.0的源码剖析, 分析Android系统服务ActivityManagerService,简称AMS

frameworks/base/core/java/android/app/
  - ActivityThread.java
  - LoadedApk.java
  - ContextImpl.java

frameworks/base/services/java/com/android/server/
  - SystemServer.java

frameworks/base/services/core/java/com/android/server/
  - SystemServiceManager.java
  - ServiceThread.java
  - pm/Installer.java
  - am/ActivityManagerService.java

一、概述

    本文以AMS为主线,讲述system_server进程中AMS服务的启动过程,以startBootstrapServices()方法为起点,紧跟着startCoreServices(), startOtherServices()共3个方法。本文大致流程:

二. AMS启动过程

2.1 startBootstrapServices

[-> SystemServer.java]

private void startBootstrapServices() {
    ...
    //启动AMS服务【见小节2.2】
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();

    //设置AMS的系统服务管理器
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    //设置AMS的APP安装器
    mActivityManagerService.setInstaller(installer);
    //初始化AMS相关的PMS
    mActivityManagerService.initPowerManagement();
    ...

    //设置SystemServer【见小节2.3】
    mActivityManagerService.setSystemProcess();
}

2.2 启动AMS服务

SystemServiceManager.startService(ActivityManagerService.Lifecycle.class) 功能主要:

SystemServiceManager.startService返回Lifecycle对象,并调用Lifecycle.onStart()方法

  1. 创建ActivityManagerService.Lifecycle对象;
  2. 调用Lifecycle.onStart()方法。

2.1.1 AMS.Lifecycle

[-> ActivityManagerService.java]

public static final class Lifecycle extends SystemService {
    private final ActivityManagerService mService;

    public Lifecycle(Context context) {
        super(context);
        //创建ActivityManagerService【见小节2.1.2】
        mService = new ActivityManagerService(context);
    }

    @Override
    public void onStart() {
        mService.start();  //【见小节2.1.3】
    }

    public ActivityManagerService getService() {
        return mService;
    }
}

该过程:创建AMS内部类的Lifecycle,已经创建AMS对象,并调用AMS.start();

2.1.2 AMS创建

public ActivityManagerService(Context systemContext) {
    mContext = systemContext;
    mFactoryTest = FactoryTest.getMode();//默认为FACTORY_TEST_OFF
    mSystemThread = ActivityThread.currentActivityThread();

    //创建名为"ActivityManager"的前台线程,并获取mHandler
    mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND, false);
    mHandlerThread.start();

    mHandler = new MainHandler(mHandlerThread.getLooper());

    //通过UiThread类,创建名为"android.ui"的线程
    mUiHandler = new UiHandler();

    //前台广播接收器,在运行超过10s将放弃执行
    mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
            "foreground", BROADCAST_FG_TIMEOUT, false);
    //后台广播接收器,在运行超过60s将放弃执行
    mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
            "background", BROADCAST_BG_TIMEOUT, true);
    mBroadcastQueues[0] = mFgBroadcastQueue;
    mBroadcastQueues[1] = mBgBroadcastQueue;

    //创建ActiveServices,其中非低内存手机mMaxStartingBackground为8
    mServices = new ActiveServices(this);
    mProviderMap = new ProviderMap(this);

    //创建目录/data/system
    File dataDir = Environment.getDataDirectory();
    File systemDir = new File(dataDir, "system");
    systemDir.mkdirs();

    //创建服务BatteryStatsService
    mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
    mBatteryStatsService.getActiveStatistics().readLocked();
    ...

    //创建进程统计服务,信息保存在目录/data/system/procstats,
    mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));

    mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
    mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));

    // User 0是第一个,也是唯一的一个开机过程中运行的用户
    mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
    mUserLru.add(UserHandle.USER_OWNER);
    updateStartedUserArrayLocked();
    ...

    //CPU使用情况的追踪器执行初始化
    mProcessCpuTracker.init();
    ...
    mRecentTasks = new RecentTasks(this);
    // 创建ActivityStackSupervisor对象
    mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
    mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);

    //创建名为"CpuTracker"的线程
    mProcessCpuThread = new Thread("CpuTracker") {
        public void run() {
          while (true) {
            try {
              try {
                synchronized(this) {
                  final long now = SystemClock.uptimeMillis();
                  long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
                  long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
                  if (nextWriteDelay < nextCpuDelay) {
                      nextCpuDelay = nextWriteDelay;
                  }
                  if (nextCpuDelay > 0) {
                      mProcessCpuMutexFree.set(true);
                      this.wait(nextCpuDelay);
                  }
                }
              } catch (InterruptedException e) {
              }
              updateCpuStatsNow(); //更新CPU状态
            } catch (Exception e) {
            }
          }
        }
    };
    ...
}

该过程共创建了3个线程,分别为”ActivityManager”,”android.ui”,”CpuTracker”。

  • 以上 AMS创建过程 涉及到Android 四大组件管理的初始化:

    Broadcast --》BroadcastQueue
    Provider --》ProviderMap
    Service --》ActiveServices
    Activity --》ActivityStackSupervisor

2.1.3 AMS.start

private void start() {
    Process.removeAllProcessGroups(); //移除所有的进程组
    mProcessCpuThread.start(); //启动CpuTracker线程

    mBatteryStatsService.publish(mContext); //启动电池统计服务
    mAppOpsService.publish(mContext);
    //创建LocalService,并添加到LocalServices
    LocalServices.addService(ActivityManagerInternal.class, new LocalService());
}

2.3 AMS.setSystemProcess

public void setSystemProcess() {
    try {
        ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
        ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
        ServiceManager.addService("meminfo", new MemBinder(this));
        ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
        ServiceManager.addService("dbinfo", new DbBinder(this));
        if (MONITOR_CPU_USAGE) {
            ServiceManager.addService("cpuinfo", new CpuBinder(this));
        }
        ServiceManager.addService("permission", new PermissionController(this));
        ServiceManager.addService("processinfo", new ProcessInfoService(this));
        ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                "android", STOCK_PM_FLAGS);

        //【见小节2.3.1】
        mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
        synchronized (this) {
            //创建ProcessRecord对象
            ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
            app.persistent = true; //设置为persistent进程
            app.pid = MY_PID;
            app.maxAdj = ProcessList.SYSTEM_ADJ;
            app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
            synchronized (mPidsSelfLocked) {
                mPidsSelfLocked.put(app.pid, app);
            }
            updateLruProcessLocked(app, false, null);//维护进程lru
            updateOomAdjLocked(); //更新adj
        }
    } catch (PackageManager.NameNotFoundException e) {
        throw new RuntimeException("", e);
    }
}

 setSystemProcess意义:

               主要工作是注册各种服务。

    这一步就是给SystemServer进程创建ProcessRecord,adj值,就是将SystemServer进程加入到AMS进程管理机制中,跟应用进程一致;
      进程调度更新优先级oomadj值,个人感觉SystemServer进程跟应用进程就不一样,却加入AMS来调度管理,这样做的意义何在?

2.4 startOtherServices

​
​
private void startOtherServices() {
    ...

 //安装系统Provider 【见小节2.4.1】
  mActivityManagerService.installSystemProviders();
//通过WMS 弹出“正在启动应用”框
ActivityManagerNative.getDefault().showBootMessage(context.getResources().getText(
                        com.android.internal.R.string.android_upgrading_starting_apps),false);
  ...
  mActivityManagerService.systemReady(new Runnable() {
    public void run() {
      //phase550
      mSystemServiceManager.startBootPhase(
              SystemService.PHASE_ACTIVITY_MANAGER_READY);

      mActivityManagerService.startObservingNativeCrashes();
      //启动WebView
      WebViewFactory.prepareWebViewInSystemServer();
      //启动系统UI【见小节3.2.1】
      startSystemUi(context);

      // 执行一系列服务的systemReady方法
      networkScoreF.systemReady();
      networkManagementF.systemReady();
      networkStatsF.systemReady();
      networkPolicyF.systemReady();
      connectivityF.systemReady();
      audioServiceF.systemReady();
      Watchdog.getInstance().start(); //Watchdog开始工作

      //phase600
      mSystemServiceManager.startBootPhase(
              SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);

      //执行一系列服务的systemRunning方法
      wallpaper.systemRunning();
      inputMethodManager.systemRunning(statusBarF);
      location.systemRunning();
      countryDetector.systemRunning();
      networkTimeUpdater.systemRunning();
      commonTimeMgmtService.systemRunning();
      textServiceManagerService.systemRunning();
      assetAtlasService.systemRunning();
      inputManager.systemRunning();
      telephonyRegistry.systemRunning();
      mediaRouter.systemRunning();
      mmsService.systemRunning();
    }
  });
}

​

​

该过程启动各种进程:

  • 启动阶段550,回调相应onBootPhase()方法;
  • 启动WebView,并且会创建进程,这是zygote正式创建的第一个进程;
  • 启动systemui服务;
  • installSystemProviderss,加载SettingsProvider;
  • 通过WMS 弹出“正在启动应用”框

2.4.1 startSystemUi

static final void startSystemUi(Context context) {
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("com.android.systemui",
                "com.android.systemui.SystemUIService"));
    context.startServiceAsUser(intent, UserHandle.OWNER);
}

启动服务”com.android.systemui/.SystemUIService”

三. AMS.systemReady

​
v​
public void systemReady(final Runnable goingCallback) {
        synchronized(this) {
            if (mSystemReady) {
                goingCallback.run();
            }
            ……
            
            // 1.升级相关处理:发送PRE_BOOT_COMPLETED广播 等待升级处理完成才能继续
            // Check to see if there are any update receivers to run.
            if (!mDidUpdate) {
                // 等待升级完成,否则直接返回
                if (mWaitingUpdate) {
                    return;
                }
                // 发送PRE_BOOT_COMPLETED广播
                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();//分析见3.2
                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
                    // 等待所有接收PRE_BOOT_COMPLETED广播者处理完毕
                    public void run() {
                        synchronized (ActivityManagerService.this) {
                            mDidUpdate = true;
                        }
                        showBootMessage(mContext.getText(
                                R.string.android_upgrading_complete),
                                false);
                                
                        // 将系统版本号和处理过的广播写入文件:/data/system/called_pre_boots.dat文件
                        writeLastDonePreBootReceivers(doneReceivers);
                        
                        // 继续systemReady流程
                        systemReady(goingCallback);
                    }
                }, doneReceivers, UserHandle.USER_OWNER);

                if (mWaitingUpdate) {
                    return;
                }
                mDidUpdate = true;
            }

            mSystemReady = true;
        }
        
        // 2. 收集已经启动的进程并杀死,除过persistent常驻进程
        ArrayList<ProcessRecord> procsToKill = null;
        synchronized(mPidsSelfLocked) {
            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
                if (!isAllowedWhileBooting(proc.info)){
                    if (procsToKill == null) {
                        procsToKill = new ArrayList<ProcessRecord>();
                    }
                    procsToKill.add(proc);
                }
            }
        }

        synchronized(this) {
            if (procsToKill != null) {
                for (int i=procsToKill.size()-1; i>=0; i--) {
                    ProcessRecord proc = procsToKill.get(i);
                    Slog.i(TAG, "Removing system update proc: " + proc);
                    removeProcessLocked(proc, true, false, "system update done");
                }
            }

            // Now that we have cleaned up any update processes, we
            // are ready to start launching real processes and know that
            // we won't trample on them any more.
            mProcessesReady = true;
        }
        
        // 3.系统准备好后回调传入的Runnable:
        if (goingCallback != null) goingCallback.run();
        
    
      // 4. 发送账户启动的广播,涉及多用户
		      long ident = Binder.clearCallingIdentity();

		      Intent intent = new Intent(Intent.ACTION_USER_STARTED);
		      broadcastIntentLocked(intent);
		      intent = new Intent(Intent.ACTION_USER_STARTING);
		      broadcastIntentLocked(intent);

		      Binder.restoreCallingIdentity(ident);
        // 5. 启动桌面Home Activity分析见3.1
        mBooting = true;
        startHomeActivityLocked(mCurrentUserId, "systemReady");
        mStackSupervisor.resumeTopActivitiesLocked();
  }

​

​

该阶段的主要功能:

  • 向PRE_BOOT_COMPLETED的接收者发送广播;
  • 杀掉procsToKill中的进程, 杀掉进程且不允许重启;
  • 此时,系统和进程都处于ready状态;
  • 回调所有SystemService的onStartUser()方法;
  • 启动persistent进程;
  • 启动home Activity;
  • 发送广播USER_STARTED和USER_STARTING;
  • 恢复栈顶Activity;

Q1:   系统都有哪些地方接收PRE_BOOT_COMPLETED,以及什么情况下应该接收该广播?
  从目前看到的主要应用在数据库应用升级方面,数据库升级涉及到数据字段变化,数据的增加等会比较耗时,
  为了加快应用启动和提供数据,需要在开机过程中做升级操作,避免使用时耗时。

Q2: 这里其实存在一个隐患:从上面的流程看到,系统发送广播给接收者处理,只有等所有接收者处理完毕,才会继续系统的启          动流程。
  试想:如果某个接收者的操作处理耗时较长,甚至被阻塞 或其他异常导致广播处理无法完成,不能回调回来怎么办?
  结果:开机时间需要的更长了,或无法开机,一直就卡在这里无法开机。

       这其实是系统不合理的地方,没有相应的超时控制的安全机制,所幸这里只允许系统应用接收该广播,如果允许第三方接收,后果可想而知。

3.1AMS.startHomeActivityLocked

boolean startHomeActivityLocked(int userId, String reason) {
    //home intent有CATEGORY_HOME
    Intent intent = getHomeIntent();
    ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
    if (aInfo != null) {
        intent.setComponent(new ComponentName(
                aInfo.applicationInfo.packageName, aInfo.name));
        aInfo = new ActivityInfo(aInfo);
        aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
        ProcessRecord app = getProcessRecordLocked(aInfo.processName,
                aInfo.applicationInfo.uid, true);
        if (app == null || app.instrumentationClass == null) {
            intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
            //启动桌面Activity
            mStackSupervisor.startHomeActivity(intent, aInfo, reason);
        }
    }
    return true;
}

3.2 deliverPreBootCompleted

deliverPreBootCompleted(new Runnable() {
        // 向PMS查询,所有接收ACTION_PRE_BOOT_COMPLETED广播的Receiver
        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
        List<ResolveInfo> ris = null;
        ris = AppGlobals.getPackageManager().queryIntentReceivers(
                    intent, null, 0, userId);
        
        // 只有系统广播才能接收该广播,去掉非系统应用
        for (int i=ris.size()-1; i>=0; i--) {
            if ((ris.get(i).activityInfo.applicationInfo.flags
                &ApplicationInfo.FLAG_SYSTEM) == 0) {
            ris.remove(i);
            }
        }
        
        // 给Intent设置flag:FLAG_RECEIVER_BOOT_UPGRADE,很关键这个看看flag的作用:
        // 只有设置这个标志,才能让应用在系统没有ready的情况下启动,见下文原始注释
        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
        
        // 将已经处理过ACTION_PRE_BOOT_COMPLETED广播的Receiver去掉
        // 已经处理该广播的Receiver记录 和 对应的系统版本号 都记录在:/data/system/called_pre_boots.dat文件中,
        // 通过与系统当前版本号比对,确认是否已处理过。考虑处理过程异常中断的情况:比如断电
        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
        
        // 将已经处理过的广播去除,同时记录已处理过保存在 doneReceivers数组中
        for (int i=0; i<ris.size(); i++) {
            ActivityInfo ai = ris.get(i).activityInfo;
            ComponentName comp = new ComponentName(ai.packageName, ai.name);
            if (lastDoneReceivers.contains(comp)) {
                // We already did the pre boot receiver for this app with the current
                // platform version, so don't do it again...
                ris.remove(i);
                i--;
                // ...however, do keep it as one that has been done, so we don't
                // forget about it when rewriting the file of last done receivers.
                doneReceivers.add(comp);
            }
        }
        
        // 内部类专门用来ACTION_PRE_BOOT_COMPLETED广播的发送,要看看这个PreBootContinuation类
        // 这块逻辑一直在变,Android5.0, 6.0 , 以及看到在7.0上又变了,基本思路不变,本文代码基于Android6.0
        //详细见3.1.2.1
        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
                ris, users);
        cont.go();
        return true;
    }

       只有系统做OTA升级 和 手机初次开机的时候,应当才会走此广播,下面看看这个函数具体的处理。

        public static final int FLAG_RECEIVER_BOOT_UPGRADE = 0x02000000;

3.2.1 PreBootContinuation

[-> ActivityManagerService.java ::PreBootContinuation]

final class PreBootContinuation extends IIntentReceiver.Stub {
        void go() {
            //判断是不是最后一个接收者
            if (lastRi != curRi) {
                
                // 疑问:如果不是最后一个接收者,则发给一个指定接收者ComponentName
                // 为什么要在这里指定接收者,一个个发送,而不是交给广播自己去处理?
                ActivityInfo ai = ris.get(curRi).activityInfo;
                ComponentName comp = new ComponentName(ai.packageName, ai.name);
                intent.setComponent(comp);
                doneReceivers.add(comp);
                lastRi = curRi;
                
                // 界面显示正在处理的广播,上面的指定接收者,就是为了这里能显示正在处理的广播名称?
                CharSequence label = ai.loadLabel(mContext.getPackageManager());
                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
            }
            
            // 发送广播,指定接收者处理完毕,会resultTo回来--》this
            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
                    + " for user " + users[curUser]);
            broadcastIntentLocked(null, null, intent, null, this,
                    0, null, null, null, AppOpsManager.OP_NONE,
                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
        }
        
        
        public void performReceive(Intent intent, int resultCode,
                String data, Bundle extras, boolean ordered,
                boolean sticky, int sendingUser) {
                
            // 指定接收者广播处理完毕回调resultTo回来,继续处理下一个,如果所有处理完,则post消息执行onFinishCallback
            curUser++;
            if (curUser >= users.length) {
                curUser = 0;
                curRi++;
                if (curRi >= ris.size()) {
                    // All done sending broadcasts!
                    if (onFinishCallback != null) {
                        // The raw IIntentReceiver interface is called
                        // with the AM lock held, so redispatch to
                        // execute our code without the lock.
                        mHandler.post(onFinishCallback);
                    }
                    return;
                }
            }
            go();
        }
    }

四. 总结

  1. 创建AMS实例对象,创建Andoid Runtime,ActivityThread和Context对象;
  2. setSystemProcess:注册AMS、meminfo、cpuinfo等服务到ServiceManager;
  3. installSystemProviderss,加载SettingsProvider;
  4. 启动SystemUIService,再调用一系列服务的systemReady()方法;

4.1 发布Binder服务

[小节2.3]的AMS.setSystemProcess()过程向servicemanager注册了如下这个binder服务

服务名 类名 功能
activity ActivityManagerService AMS
procstats ProcessStatsService 进程统计
meminfo MemBinder 内存
gfxinfo GraphicsBinder 图像信息
dbinfo DbBinder 数据库
cpuinfo CpuBinder CPU
permission PermissionController 权限
processinfo ProcessInfoService 进程服务
usagestats UsageStatsService 应用的使用情况

想要查看这些服务的信息,可通过dumpsys <服务名>命令。比如查看CPU信息命令dumpsys cpuinfo

4.2 AMS.systemReady

另外,AMS.systemReady()的大致过程如下:

public final class ActivityManagerService{

    public void systemReady(final Runnable goingCallback) {
        ...//更新操作
        mSystemReady = true; //系统处于ready状态
        removeProcessLocked(proc, true, false, "system update done");//杀掉所有非persistent进程
        mProcessesReady = true;  //进程处于ready状态

        goingCallback.run(); //这里有可能启动进程

        addAppLocked(info, false, null); //启动所有的persistent进程
        mBooting = true;  //正在启动中
        startHomeActivityLocked(mCurrentUserId, "systemReady"); //启动桌面
        mStackSupervisor.resumeTopActivitiesLocked(); //恢复栈顶的Activity
    }
}

相关文章:https://www.cnblogs.com/bastard/p/5770573.html

猜你喜欢

转载自blog.csdn.net/kai_zone/article/details/81562617