Android Framework——AMS、PMS的启动流程

AMS启动过程分析

AMS实际是有SystemServer创建的,不了解的大家可以看这篇文章Android Framework—SystemServer进程启动过程

image.png

    public static void main(String[] args) {
        new SystemServer().run();
    }
   private void run() {
        // Initialize native services.
        System.loadLibrary("android_servers");
     

        // I初始化系统上下文
        createSystemContext();

        // 创建SystemServiceManager
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

        // Start services.
        try {
          //创建ActivityManagerService、PowerManagerService
            startBootstrapServices();
            startCoreServices();
          //启动CameraService等服务
            startOtherServices();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        }

        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
    private void startBootstrapServices() {
      
        Installer installer = mSystemServiceManager.startService(Installer.class);
         //启动AMS
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
          //设置AMS的系统管理
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
         ...
         // 设置 SystemServer 
      mActivityManagerService.setSystemProcess();
    }
    public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;

        public Lifecycle(Context context) {
            super(context);
          //创建ActivityManagerService
            mService = new ActivityManagerService(context);
        }

        @Override
        public void onStart() {
       / /调用start方法
            mService.start();
        }

        public ActivityManagerService getService() {
            return mService;
        }
    }
    public ActivityManagerService(Context systemContext) {
        mContext = systemContext;
       //获取ActivityThread
        mSystemThread = ActivityThread.currentActivityThread();
       // 创建名为"ActivityManager"的前台 HandlerThread
        mHandlerThread = new ServiceThread(TAG,
                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
         //启动HandlerThread
        mHandlerThread.start();
        mHandler = new MainHandler(mHandlerThread.getLooper());
        mUiHandler = new UiHandler();
       //Watchdog监听
        Watchdog.getInstance().addMonitor(this);
        Watchdog.getInstance().addThread(mHandler);
    }

ActivityManagerService.Lifecycle.class实际是创建ActivityManagerServer,并创建UI和CPUTracker

startService源码分析

    public SystemService startService(String className) {
        final Class<SystemService> serviceClass;
        try {
            serviceClass = (Class<SystemService>)Class.forName(className);
        } catch (ClassNotFoundException ex) {
        }
           //classname是ActiviityManagerService.Lifecycle
        return startService(serviceClass);
    }
    public <T extends SystemService> T startService(Class<T> serviceClass) {
 //name 是ActiviityManagerService.Lifecycle
        final String name = serviceClass.getName();
        final T service;
        try {
            Constructor<T> constructor = serviceClass.getConstructor(Context.class);
            service = constructor.newInstance(mContext);
        } catch (InstantiationException ex) {
        }
        mServices.add(service);
       try {
         //实际调用的是ActiviityManagerService.Lifecycle的onStart方法
            service.onStart();
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + name
                    + ": onStart threw an exception", ex);
        }
        return service;
    }

最终实际走到的Lifecycle的onStart方法

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

        public Lifecycle(Context context) {
            super(context);
            mService = new ActivityManagerService(context);
        }

        @Override
        public void onStart() {
            //ActivityManagerService的start方法
            mService.start();
        }

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

        mBatteryStatsService.publish(mContext);
        mAppOpsService.publish(mContext);
        Slog.d("AppOps", "AppOpsService published");
        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
    }

startOtherServices源码

private void startOtherServices() {
 ...
  mActivityManagerService.systemReady(new Runnable() {
            @Override
            public void run() {
                 try {
                    startSystemUi(context);
                } catch (Throwable e) {
                    reportWtf("starting System UI", e);
                }

         ...
    }
   ...
}
    public void systemReady(final Runnable goingCallback) {
        ...
        // 执行 Callback 的 run 方法
        if (goingCallback != null) goingCallback.run();
        // Start up initial activity.
        mBooting = true;
        // 启动桌面 Activity 进程
        startHomeActivityLocked(mCurrentUserId, "systemReady");
    }
   static final void startSystemUi(Context context) {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.android.systemui",
                    "com.android.systemui.SystemUIService"));
        //Slog.d(TAG, "Starting service: " + intent);
        context.startServiceAsUser(intent, UserHandle.OWNER);
    }

最后实际走的桌面的Activity进程

PMS启动过程分析

PMS实际也是SystemServer创建的

    private void startBootstrapServices() {
        Installer installer = mSystemServiceManager.startService(Installer.class);
     
        mSystemServiceManager.startService(LightsService.class);
        mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
       //创建PackManagerService
        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        mFirstBoot = mPackageManagerService.isFirstBoot();
        mPackageManager = mSystemContext.getPackageManager();
        startSensorService();
    }
    public static PackageManagerService main(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        //创建对象并将对象添加到ServiceManager
        PackageManagerService m = new PackageManagerService(context, installer,
                factoryTest, onlyCore);
        ServiceManager.addService("package", m);
        return m;
    }

PackManagerService的main函数实际就是创建PackageManagerService对象,然后将其对象添加到ServiceManager

 public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
          //打印开始日志
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
                SystemClock.uptimeMillis());
         //屏幕相关信息
        mMetrics = new DisplayMetrics();
      //Settings用于保存所有包的动态设置,这里主要创建Setting对象
        mSettings = new Settings(mPackages);
          // 添加 system, phone, log, nfc, bluetooth, shell 这六种shareUserId到mSettings;
    //shareUserId是用来进程间共享数据,两个不通信的App有了同一个shareUserId,两个App此时就可以实现通信
        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        ....
         //mPackageDexOptimizer 主要用于Dex的优化
        mPackageDexOptimizer = new PackageDexOptimizer(this);
        synchronized (mInstallLock) {
        // writer
        synchronized (mPackages) {
            //创建ServiceThread,ServiceThread实际是个HandleThread
            mHandlerThread = new ServiceThread(TAG,
                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
            mHandlerThread.start();
             //PackageHandler主要用于apk复制和安装工作
            mHandler = new PackageHandler(mHandlerThread.getLooper());
           //检测PackageHandler是否过于繁忙而导致卡住
            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
           //创建各项文件目录
          File dataDir = Environment.getDataDirectory();
            mAppDataDir = new File(dataDir, "data");
            mAppInstallDir = new File(dataDir, "app");
            mAppLib32InstallDir = new File(dataDir, "app-lib");
            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
            mUserAppDataDir = new File(dataDir, "user");
            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
            // 创建用户管理服务
            sUserManager = new UserManagerService(context, this,
                    mInstallLock, mPackages);
             //framework目录
            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
            alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
            String[] frameworkFiles = frameworkDir.list();
           //遍历framework下所有的文件
            if (frameworkFiles != null) {
                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
                    for (int i=0; i<frameworkFiles.length; i++) {
                        File libPath = new File(frameworkDir, frameworkFiles[i]);
                        String path = libPath.getPath();
                           //跳过是apk和jar
                        if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
                            continue;
                        }
                        try {
                            int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false);
                            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                                   //mInstaller也是系统服务,apk的安装和卸载便是通过它
                                mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded, false);
                            }
                        } catch (FileNotFoundException e) {
                            Slog.w(TAG, "Jar not found: " + path);
                        } catch (IOException e) {
                            Slog.w(TAG, "Exception reading jar: " + path, e);
                        }
                    }
                }
            }
              if (!mOnlyCore) {
             //扫描data/app目录
                scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
            //扫描data/app-private 目录
                scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
                   ............
                }
        }}
}

实际就是对我们data/app目录下文件进行扫描

扫描阶段

    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
        final File[] files = dir.listFiles();
        for (File file : files) {
              //判断是不是apk或者文件夹
            final boolean isPackage = (isApkFile(file) || file.isDirectory())
                    && !PackageInstallerService.isStageName(file.getName());
            try {
                scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
                        scanFlags, currentTime, null);
            } catch (PackageManagerException e) {
                    //出现异常就删除
                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
                        e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
                    logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
                    if (file.isDirectory()) {
                        mInstaller.rmPackageDir(file.getAbsolutePath());
                    } else {
                        file.delete();
                    }
                }
            }
        }
    }
    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
            long currentTime, UserHandle user) throws PackageManagerException {
             //创建PackageParser
        PackageParser pp = new PackageParser();
        pp.setSeparateProcesses(mSeparateProcesses);
        pp.setOnlyCoreApps(mOnlyCore);
        pp.setDisplayMetrics(mMetrics);
        final PackageParser.Package pkg;
        try {
              //解析apk参数
            pkg = pp.parsePackage(scanFile, parseFlags);
        } catch (PackageParserException e) {
            throw PackageManagerException.from(e);
        }
    }
    public Package parsePackage(File packageFile, int flags) throws PackageParserException {
        if (packageFile.isDirectory()) {
            return parseClusterPackage(packageFile, flags);
        } else {
               //apk走这里
            return parseMonolithicPackage(packageFile, flags);
        }
    }
    @Deprecated
    public Package parseMonolithicPackage(File apkFile, int flags) throws PackageParserException {
        //new 一个AssetManager
        final AssetManager assets = new AssetManager();
        try {
            final Package pkg = parseBaseApk(apkFile, assets, flags);
            pkg.codePath = apkFile.getAbsolutePath();
            return pkg;
        } finally {
            IoUtils.closeQuietly(assets);
        }
    }
    private Package parseBaseApk(File apkFile, AssetManager assets, int flags)
            throws PackageParserException {
           //apk的绝对路径
        final String apkPath = apkFile.getAbsolutePath();

        Resources res = null;
        XmlResourceParser parser = null;
        try {
            res = new Resources(assets, mMetrics, null);
        
            final Package pkg = parseBaseApk(res, parser, flags, outError);
            if (pkg == null) {
                throw new PackageParserException(mParseError,
                        apkPath + " (at " + parser.getPositionDescription() + "): " + outError[0]);
            }

            pkg.volumeUuid = volumeUuid;
            pkg.applicationInfo.volumeUuid = volumeUuid;
            pkg.baseCodePath = apkPath;
            pkg.mSignatures = null;

            return pkg;

        } catch (PackageParserException e) {
            throw e;
        } catch (Exception e) {
            throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
                    "Failed to read manifest from " + apkPath, e);
        } finally {
            IoUtils.closeQuietly(parser);
        }
    }
    private Package parseBaseApk(Resources res, XmlResourceParser parser, int flags,
            String[] outError) throws XmlPullParserException, IOException {
         final String pkgName;
        final String splitName;
        //解析包名
        try {
            Pair<String, String> packageSplit = parsePackageSplitNames(parser, attrs, flags);
            pkgName = packageSplit.first;
            splitName = packageSplit.second;
        } catch (PackageParserException e) {
        }
        final Package pkg = new Package(pkgName);
        boolean foundApp = false;
          //解析AndroidManifest
        TypedArray sa = res.obtainAttributes(attrs,
                com.android.internal.R.styleable.AndroidManifest);
       //获取versionCode和versionName
        pkg.mVersionCode = pkg.applicationInfo.versionCode = sa.getInteger(
                com.android.internal.R.styleable.AndroidManifest_versionCode, 0);
        pkg.baseRevisionCode = sa.getInteger(
                com.android.internal.R.styleable.AndroidManifest_revisionCode, 0);
        pkg.mVersionName = sa.getNonConfigurationString(
                com.android.internal.R.styleable.AndroidManifest_versionName, 0);
        if (pkg.mVersionName != null) {
            pkg.mVersionName = pkg.mVersionName.intern();
        }
       //解析其他,比如application,permission等
       int outerDepth = parser.getDepth();
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                continue;
            }

            String tagName = parser.getName();
            if (tagName.equals("application")) {
                foundApp = true;
                if (!parseBaseApplication(pkg, res, parser, attrs, flags, outError)) {
                    return null;
                }
            } else if (tagName.equals("permission-group")) {
                if (parsePermissionGroup(pkg, flags, res, parser, attrs, outError) == null) {
                    return null;
                }
            } else if (tagName.equals("permission")) {
                if (parsePermission(pkg, res, parser, attrs, outError) == null) {
                    return null;
                }
            } else if (tagName.equals("permission-tree")) {
                if (parsePermissionTree(pkg, res, parser, attrs, outError) == null) {
                    return null;
                }
            } else if (tagName.equals("uses-permission")) {
                if (!parseUsesPermission(pkg, res, parser, attrs)) {
                    return null;
                }
            } else if (tagName.equals("uses-permission-sdk-m")
                    || tagName.equals("uses-permission-sdk-23")) {
                if (!parseUsesPermission(pkg, res, parser, attrs)) {
                    return null;
                }
            }
               ..........
         }
 
}

private boolean parseBaseApplication(Package owner, Resources res,
            XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
        throws XmlPullParserException, IOException {
        final ApplicationInfo ai = owner.applicationInfo;
        final String pkgName = owner.applicationInfo.packageName;

        TypedArray sa = res.obtainAttributes(attrs,
                com.android.internal.R.styleable.AndroidManifestApplication);
           //解析application
        String name = sa.getNonConfigurationString(
                com.android.internal.R.styleable.AndroidManifestApplication_name, 0);
      //VERSION
        String manageSpaceActivity = sa.getNonConfigurationString(
                com.android.internal.R.styleable.AndroidManifestApplication_manageSpaceActivity,
                Configuration.NATIVE_CONFIG_VERSION);

        boolean allowBackup = sa.getBoolean(
                com.android.internal.R.styleable.AndroidManifestApplication_allowBackup, true);    

        //解析label也是就是app的名字
        TypedValue v = sa.peekValue(
                com.android.internal.R.styleable.AndroidManifestApplication_label);
         //icon图标
        ai.icon = sa.getResourceId(
                com.android.internal.R.styleable.AndroidManifestApplication_icon, 0);
       //logo
        ai.logo = sa.getResourceId(
                com.android.internal.R.styleable.AndroidManifestApplication_logo, 0);
        ai.banner = sa.getResourceId(
                com.android.internal.R.styleable.AndroidManifestApplication_banner, 0);
        ai.theme = sa.getResourceId(
                com.android.internal.R.styleable.AndroidManifestApplication_theme, 0);
        ai.descriptionRes = sa.getResourceId(
                com.android.internal.R.styleable.AndroidManifestApplication_description, 0);
           .....
       //解析四大组件
        final int innerDepth = parser.getDepth();
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
   
            String tagName = parser.getName();
           //解析activity
            if (tagName.equals("activity")) {
                Activity a = parseActivity(owner, res, parser, attrs, flags, outError, false,
                        owner.baseHardwareAccelerated);
                if (a == null) {
                    mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                    return false;
                }

                owner.activities.add(a);

            } else if (tagName.equals("receiver")) {//解析receiver
                Activity a = parseActivity(owner, res, parser, attrs, flags, outError, true, false);
                owner.receivers.add(a);
            } else if (tagName.equals("service")) {
             //解析service
                Service s = parseService(owner, res, parser, attrs, flags, outError);
                if (s == null) {
                    mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                    return false;
                }
                owner.services.add(s);

            } else if (tagName.equals("provider")) {
                Provider p = parseProvider(owner, res, parser, attrs, flags, outError);               
                  owner.providers.add(p);
            } else if (tagName.equals("activity-alias")) {
                Activity a = parseActivityAlias(owner, res, parser, attrs, flags, outError);
                owner.activities.add(a);
            } else if (parser.getName().equals("meta-data")) {
                if ((owner.mAppMetaData = parseMetaData(res, parser, attrs, owner.mAppMetaData,
                        outError)) == null) {
                    mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                    return false;
                }
            } else if (tagName.equals("library")) {
                sa = res.obtainAttributes(attrs,
                        com.android.internal.R.styleable.AndroidManifestLibrary);
                String lname = sa.getNonResourceString(
                        com.android.internal.R.styleable.AndroidManifestLibrary_name);

                sa.recycle();
                XmlUtils.skipCurrentTag(parser);

            } else if (tagName.equals("uses-library")) {
                sa = res.obtainAttributes(attrs,
                        com.android.internal.R.styleable.AndroidManifestUsesLibrary);

      
                String lname = sa.getNonResourceString(
                        com.android.internal.R.styleable.AndroidManifestUsesLibrary_name);
                boolean req = sa.getBoolean(
                        com.android.internal.R.styleable.AndroidManifestUsesLibrary_required,
                        true);

                sa.recycle();

                if (lname != null) {
                    lname = lname.intern();
                    if (req) {
                        owner.usesLibraries = ArrayUtils.add(owner.usesLibraries, lname);
                    } else {
                        owner.usesOptionalLibraries = ArrayUtils.add(
                                owner.usesOptionalLibraries, lname);
                    }
                }

                XmlUtils.skipCurrentTag(parser);

            } else if (tagName.equals("uses-package")) {
                // Dependencies for app installers; we don't currently try to
                // enforce this.
                XmlUtils.skipCurrentTag(parser);

            } else {
                if (!RIGID_PARSER) {
                    XmlUtils.skipCurrentTag(parser);
                    continue;
                } else {
                    outError[0] = "Bad element under <application>: " + tagName;
                    mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                    return false;
                }
            }
        }
        return true;
    }

总结

  • 获取一个应用程序的所有信息
  • 获取四大组件的信息
  • 查询权限的相关信息
  • 获取包的信息
  • 安装、卸载apk
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言 对于Android开发,干上几年后,都要进阶,或者直接转行了。如果你还在干Android,想要进阶 对Fra...
    北斗星_And阅读 920评论 0 3
  • com.android.server.am.ActivityManagerService 本文在 API 27 基...
    simplehych阅读 1,594评论 0 2
  • 这篇是自己学习所用,请谨慎观看,具体内容可看下面博客:Android启动流程简析[https://www.jian...
    QGv阅读 1,352评论 0 0
  • AMS作为Android FrameWork中最核心的一个部分,是应用层开发者进阶的里程碑,本文是AMS专栏的第一...
    leap_阅读 997评论 0 3
  • 一、启动电源以及系统启动 当电源按下时引导芯片代码从预定义的地方(固化在ROM)开始执行。加载引导程序BootLo...
    小阿冷爱学习阅读 326评论 0 0