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服务

服务名类名功能
activityActivityManagerServiceAMS
procstatsProcessStatsService进程统计
meminfoMemBinder内存
gfxinfoGraphicsBinder图像信息
dbinfoDbBinder数据库
cpuinfoCpuBinderCPU
permissionPermissionController权限
processinfoProcessInfoService进程服务
usagestatsUsageStatsService应用的使用情况

想要查看这些服务的信息,可通过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

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kevin@1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值