AMS启动流程——APP启动过程

news2025/2/2 22:35:04

AMS流程图

基本慨念

1.zygote

zygote意为“受精卵“。Android是基于Linux系统的,而在Linux中,所有的进程都是由init进程直接或者是间接fork出来的,zygote进程也不例外。

在Android系统里面,zygote是一个进程的名字。Android是基于Linux System的,当你的手机开机的时候,Linux的内核加载完成之后就会启动一个叫“init“的进程。在Linux System里面,所有的进程都是由init进程fork出来的,我们的zygote进程也不例外。

我们都知道,每一个App其实都是

● 一个单独的art虚拟机

● 一个单独的进程

所以当系统里面的第一个zygote进程运行之后,在这之后再开启App,就相当于开启一个新的进程。而为了实现资源共用和更快的启动速度,Android系统开启新进程的方式,是通过fork第一个zygote进程实现的。所以说,除了第一个zygote进程,其他应用所在的进程都是zygote的子进程,这下你明白为什么这个进程叫“受精卵”了吧?因为就像是一个受精卵一样,它能快速的分裂,并且产生遗传物质一样的细胞!

2.system_server

SystemServer也是一个进程,而且是由zygote进程fork出来的。

知道了SystemServer的本质,我们对它就不算太陌生了,这个进程是Android Framework里面两大非常重要的进程之一——另外一个进程就是上面的zygote进程。

为什么说SystemServer非常重要呢?因为系统里面重要的服务都是在这个进程里面开启的,比如

ActivityManagerService、PackageManagerService、WindowManagerService等等。

3.ActivityManagerService

  • ActivityManagerService,简称AMS,服务端对象,负责系统中所有Activity的生命周期。
  • ActivityManagerService进行初始化的时机很明确,就是在SystemServer进程开启的时候,就会初始ActivityManagerService。

4.Launcher

当我们点击手机桌面上的图标的时候,App就由Launcher开始启动了。但是,你有没有思考过Launcher到底是一个什么东西?

Launcher本质上也是一个应用程序,和我们的App一样,也是继承自Activity

packages/apps/Launcher2/src/com/android/launcher2/Launcher.java
​
public final class Launcher extends Activity
​
implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,
​
View.OnTouchListener {
​
}

Launcher实现了点击、长按等回调接口,来接收用户的输入。既然是普通的App,那么我们的开发经验在这里就仍然适用,比如,我们点击图标的时候,是怎么开启的应用呢?捕捉图标点击事件,然后startActivity()发送对应的Intent请求呗!是的,Launcher也是这么做的,就是这么easy!

5.Instrumentation和ActivityThread

每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象。

Instrumentation这个类里面的方法大多数和Application和Activity有关,这个类就是完成对Application和Activity初始化和生命周期的工具类。Instrumentation这个类很重要,对Activity生命周期方法的调用根本就离不开他,他可以说是一个大管家。

ActivityThread,就是UI线程。App和AMS是通过Binder传递信息的,那么ActivityThread就是专门与AMS的外交工作的。

AMS服务的启动流程详解

1、startBootstrapServices

private void startBootstrapServices() { 
        // Activity manager runs the show. 
     mActivityManagerService = mSystemServiceManager.startService( 
                ActivityManagerService.Lifecycle.class).getService(); 
     mActivityManagerService.setSystemProcess(); 
…… 
     mActivityManagerService.installSystemProviders(); 
…… 
     mActivityManagerService.systemReady(new Runnable() { 
            @Override 
            public void run() { 
                Slog.i(TAG, "Making services ready"); 
                mSystemServiceManager.startBootPhase( 
                        SystemService.PHASE_ACTIVITY_MANAGER_READY); 
                try { 
                    mActivityManagerService.startObservingNativeCrashes(); 
                } catch (Throwable e) { 
                    reportWtf("observing native crashes", e); 
                } 
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.

SystemServer中关于AMS启动时的几个关键方法,主要分为4个步骤

  • 创建AMS对象,并启动服务
  • 将AMS所在的系统进程,添加到进程管理中去
  • 为系统进程安装ContentProvider对象
  • 在systemReady方法中做善后操作
  • 一个一个的来看先这些方法的作用,这些方法就是AMS的启动和初始化过程;

2、ActivityManagerService

启动ActivityManagerService的方法

mActivityManagerService = mSystemServiceManager.startService(

ActivityManagerService.Lifecycle.class).getService();

AMS服务同样是通过SystemServiceManager来启动的,那我们首先来看ActivityManagerService.Lifecycle的构造方法,然后在来看它的Start函数;

Lifecycle的构造方法中很简单就是构造一个AMS的对象

mService = new ActivityManagerService(context);

创建AMS对象的时候需要传递一个Context作为参数,那这个mSystemContext是就是上面创建的系统Context;

接着看AMS的构造方法;

public ActivityManagerService(Context systemContext) { 
//系统的context         
mContext = systemContext; 
    //获得系统的ActivityThread 
        mSystemThread = ActivityThread.currentActivityThread(); 
    //创建一个HandlerThread用来处理AMS接收的命令 
        mHandlerThread = new ServiceThread(TAG, 
                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 
        mHandlerThread.start(); 
        mHandler = new MainHandler(mHandlerThread.getLooper()); 
        mUiHandler = new UiHandler(); 
    //初始化广播的队列 
        mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 
                "foreground", BROADCAST_FG_TIMEOUT, false); 
        mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 
                "background", BROADCAST_BG_TIMEOUT, true); 
        mBroadcastQueues[0] = mFgBroadcastQueue; 
        mBroadcastQueues[1] = mBgBroadcastQueue; 
    //初始化Service相关的容器 
        mServices = new ActiveServices(this); 
    //初始化Provider相关的Map,里面保存了注册的ContentProvider 
        mProviderMap = new ProviderMap(this); 
        //初始化并创建data/system/目录 
        File dataDir = Environment.getDataDirectory(); 
        File systemDir = new File(dataDir, "system"); 
        systemDir.mkdirs(); 
    //初始化电量统计服务相关的信息 
        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 
        mBatteryStatsService.getActiveStatistics().readLocked(); 
        mBatteryStatsService.scheduleWriteToDisk(); 
        mOnBattery = DEBUG_POWER ? true 
                : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 
        mBatteryStatsService.getActiveStatistics().setCallback(this); 
    //初始化系统统计服务,用于统计系统的运行信息 
        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,userID为0,该用户具有管理员权限 
        mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true)); 
        mUserLru.add(UserHandle.USER_OWNER); 
        updateStartedUserArrayLocked(); 
    //获取opengle的版本 
        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 
            ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 
        //初始化字体语言等配置信息 
        mConfiguration.setToDefaults(); 
        mConfiguration.setLocale(Locale.getDefault()); 
     ……; 
        mRecentTasks = new RecentTasks(this); 
    //初始化StackSupervisor,该类是Activity启动和调度的核心类 
        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks); 
        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks); 
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.
  • AMS的构造方法主要是在做一些初始化的先关操作;
  • 保存了自己的运行环境的Context和ActivityThread;
  • AMS负责调度四大组件,所以会初始化broadcast,service和contentProvider相关的变量,接着初始化了电量统计服务,创建了系统的第一个用户,初始化了基本的配置信息,还创建了Activity调度的核心类,因为Activity调度比较复杂,Activity相关的信息初始化会在ActivityStackSupervisor中;

3、start

AMS的start方法。

private void start() { 
     mProcessCpuThread.start(); 
     mBatteryStatsService.publish(mContext); 
     LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 
 } 
1.2.3.4.5.
  • AMS的start方法很简单,只是启动了几个服务,并把AMS服务自己保存到localService中供程序内部调用;
  • AMS的构造方法和start方法中做了AMS服务一些变量的初始化和相关服务的初始化。接着看下一个重要的方法setSystemProcess;

4、setSystemProcess

ActivityManagerService的setSystemProcess方法

public void setSystemProcess() { 
        try { 
    //将AMS注册到ServiceManager中 
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 
    //注册其他服务到ServiceMananger中 
            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)); 
            } 
    //注册权限服务到ServiceMananger中 
            ServiceManager.addService("permission", new PermissionController(this)); 
            ServiceManager.addService("processinfo", new ProcessInfoService(this)); 
    //从PMS中查询包名为android的application,即framework-res的Application信息 
            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 
                    "android", STOCK_PM_FLAGS); 
        //将application信息配置到开始创建的activityThread中 
            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 
            synchronized (this) { 
        //创建了一个ProcessRecord对象,该对象中保存着系统ongoing服务的进程信息 
                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 
                app.persistent = true; 
                app.pid = MY_PID; 
                app.maxAdj = ProcessList.SYSTEM_ADJ; 
                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 
                synchronized (mPidsSelfLocked) { 
        然后将系统进程的processRecord对象也添加到mPidsSelfLocked集合中,和普通应用的进程一样,接收AMS的管理调度 
                    mPidsSelfLocked.put(app.pid, app); 
                } 
        //更细进程管理的调度信息 
                updateLruProcessLocked(app, false, null); 
                updateOomAdjLocked(); 
            } 
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.
  • setSystemProcess方法中,首先将自己AMS服务注册到了ServiceManager中,然后又注册了权限服务等其他的系统服务;
  • 通过先前创建的Context,得到PMS服务,检索framework-res的Application信息,然后将它配置到系统的ActivityThread中;
  • 为了能让AMS同样可以管理调度系统进程,也创建了一个关于系统进程的ProcessRecord对象,ProcessRecord对象保存一个进程的相关信息;
  • 然后将它保存到mPidsSelfLocked集合中方便管理;
  • AMS具体是如何将检索到的framework-res的application信息,配置到ActivityThread中的,需要继续分析ActivityThread的installSystemApplicationInfo方法;

接着看installSystemApplicationInfo方法

public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { 
        synchronized (this) { 
            getSystemContext().installSystemApplicationInfo(info, classLoader); 
        } 
    } 
1.2.3.4.5.

这个方法中最终调用上面创建的SystemContext的installSystemApplication方法,那就接着看ConxtextImpl的installSystemApplication方法。

void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { 
        mPackageInfo.installSystemApplicationInfo(info, classLoader); 
    } 
1.2.3.
  • 它有最终调用了mPackageInfo的installSystemApplication方法,mPackageInfo就是在创建Context对象的时候传进来的LoadedApk,里面保存了一个应用程序的基本信息;
  • setSystemProcess主要就是设置系统集成的一些信息,在这里设置了系统进程的Application信息,创建了系统进程的ProcessRecord对象将其保存在进程集合中,方便AMS管理调度;

5、installSystemProvider

  • ActivityManagerService的installSystemProvider方法;
  • Android系统中有很多配置信息都需要保存,这些信息是保存在SettingsProvider中,而这个SettingsProvider也是运行在SystemServer进程中的,由于SystemServer进程依赖SettingsProvider,放在一个进程中可以减少进程间通信的效率损失;
  • 下面就来分析下如何将SettingsProvider.apk也加载到SystemServer进程中;
public final void installSystemProviders() { 
        List<ProviderInfo> providers; 
        synchronized (this) { 
            //找到名称为”System”的进程,就是上一步创建的processRecord对象 
            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 
            //找到所有和system进程相关的ContentProvider 
            providers = generateApplicationProvidersLocked(app); 
            if (providers != null) { 
                for (int i=providers.size()-1; i>=0; i--) { 
                    ProviderInfo pi = (ProviderInfo)providers.get(i); 
                    //再次确认进程为system的provider,把不是该进程provider移除 
                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 
                        Slog.w(TAG, "Not installing system proc provider " + pi.name 
                                + ": not system .apk"); 
                        providers.remove(i); 
                    } 
                } 
            } 
        } 
        if (providers != null) { 
            //把provider安装到系统的ActivityThread中 
            mSystemThread.installSystemProviders(providers); 
        } 
        mCoreSettingsObserver = new CoreSettingsObserver(this); 
    } 
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.

找到名称为system的进程对象,就是SystemServer进程,然后根据进程对象去查询所有有关的ContentProvider,调用系统进程的主线程ActivityThread安装所有相关的ContentProvider,具体是如何查找相关的contentProvider和如何安装ContentProvider到系统主线程的,接着分析下面两个方法;

private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 
        List<ProviderInfo> providers = null; 
        try { 
            //调用PMS根据进程ID和进程名称来查询Provider 
            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager(). 
                queryContentProviders(app.processName, app.uid, 
                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 
            providers = slice != null ? slice.getList() : null; 
        } catch (RemoteException ex) { 
        } 
        int userId = app.userId; 
        if (providers != null) { 
            int N = providers.size(); 
            for (int i=0; i<N; i++) { 
                ProviderInfo cpi = 
                    (ProviderInfo)providers.get(i); 
               …… 
                ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 
           //从AMS管理的contentProvider列表中查询对应的provider      
ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 
                if (cpr == null) { 
                    //如果AMS的Provider列表中没有对应的Provider实例,就根据查询的provider信息,创建一个对象保存到队列中 
                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 
                    mProviderMap.putProviderByClass(comp, cpr); 
                } 
               //同时将provider保存到processRecord对象的pubProviders列表中 
                app.pubProviders.put(cpi.name, cpr); 
                …… 
            } 
        } 
        return providers; 
    } 
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.
  • 这个方法就是从PMS中查询和SystemServer进程相关的Provider,也就是SettingsProvder,然后将它保存到AMS的contentProvider列表中;
  • 同时也将它保存到系统进程对象ProcessRecord的变量pubProviders列表中,保存到AMS的provider列表中是因为AMS需要管理所有的ContentProvder;
  • 保存到进程对象的pubProviders列表中是因为,每个ContentProvider都需要对应到一个进程中去;
  • 接着看如何将SettingsProvider安装到系统的主进程中去;
private void installContentProviders( 
            Context context, List<ProviderInfo> providers) { 
         …… 
        for (ProviderInfo cpi : providers) { 
            //通过installProvider方法把provider封装成一个ContentProviderHolder对象,有利于进程间传输 
            IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi, 
                    false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); 
            if (cph != null) { 
                cph.noReleaseNeeded = true; 
                results.add(cph); 
            } 
        } 
        try { 
            //将上面得到的contentProviderHolder对象发布到AMS服务,getApplicationThread代表本地进程的一个binder对象,binder对象可跨进程传输,它在AMS中对应一个ProcessRecord. 
            ActivityManagerNative.getDefault().publishContentProviders( 
                getApplicationThread(), results); 
       …… 
    } 
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.
  • 该方法将得到的contentProvider对象封装成了contentProviderHolder对象,其实就是Binder对象,这样就可以进程间传输了,然后跨进程调用AMS服务注册Provider;
  • AMS负责管理ContentProvider,只有将ContentProvider注册到AMS服务其他进程才能访问;
  • 接着看AMS如何注册Provider;

6、publishContentProviders

public final void publishContentProviders(IApplicationThread caller, 
            List<ContentProviderHolder> providers) { 
           …… 
            //根据调用者的进程得到相应的processRecord对象,就是系统进程的ProcessRecord 
            final ProcessRecord r = getRecordForAppLocked(caller); 
           …… 
            final int N = providers.size(); 
            for (int i = 0; i < N; i++) { 
                //ActivityThread客户端传过来的provider src 
                ContentProviderHolder src = providers.get(i); 
                //根据src provider name得到一开始保存的进程中保存的ProciderRecord 
                ContentProviderRecord dst = r.pubProviders.get(src.info.name); 
                if (dst != null) { 
                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 
                    //按类将它保存在mProviderMap中 
                    mProviderMap.putProviderByClass(comp, dst); 
                    String names[] = dst.info.authority.split(";"); 
                    for (int j = 0; j < names.length; j++) { 
                        //按authority保存在mProviderMap中 
                        mProviderMap.putProviderByName(names[j], dst); 
                    } 
                   …… 
                    } 
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.
  • AMS的注册服务就是根据参数传过来的provider信息,找到原先进程中pubProviders列表中保存的ContentProviderRecord,然后将它分别以类为key保存在mProviderMap中,和以authority为key保存在mProviderMap中;
  • 即AMS提供了多种方案来查找一个ContentProvider,一种是通过authority来查找,一种是指明CompomentName来查找;
  • 此刻位置一个SettingsProvider就正式注册到SystemServer进程中了,所以可以看出installSystemProvider方法的主要工作就是按照普通进程类似的方式,将SettingsProvider注册到系统进程中,方便系统进程对settings的配置数据进行调用;

7、systemReady

ActivityManagerService的systemReady方法

public void systemReady(final Runnable goingCallback) { 
        synchronized(this) { 
            //初始化Doze模式的controller 
            mLocalDeviceIdleController 
                    = LocalServices.getService(DeviceIdleController.LocalService.class); 
        //重置RecentTasks 
            mRecentTasks.clear(); 
            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked()); 
            mRecentTasks.cleanupLocked(UserHandle.USER_ALL); 
            mTaskPersister.startPersisting(); 
            …… 
            //设置systemReady为true 
            mSystemReady = true; 
        } 
        ArrayList<ProcessRecord> procsToKill = null; 
        //收集那些在AMS之前启动的进程 
        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); 
                } 
            } 
        } 
       //将那些在AMS之前启动的进程杀死,有的进程不能再AMS之前启动 
        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"); 
                } 
            } 
        } 
        //从settingsProvider的设置总初始化部分变量 
        retrieveSettings(); 
        //调用callback方法,该方法在systemServer代码中实现 
        if (goingCallback != null) goingCallback.run(); 
                    //查询那些persistent为1的application,并启动他们所在的进程 
                    List apps = AppGlobals.getPackageManager(). 
                        getPersistentApplications(STOCK_PM_FLAGS); 
                    if (apps != null) { 
                        int N = apps.size(); 
                        int i; 
                        for (i=0; i<N; i++) { 
                            ApplicationInfo info 
                                = (ApplicationInfo)apps.get(i); 
                            if (info != null && 
                                    !info.packageName.equals("android")) { 
                                addAppLocked(info, false, null /* ABI override */); 
                            } 
            } 
            //启动HomeActivity,也就是launcher程序 
            mBooting = true; 
            startHomeActivityLocked(mCurrentUserId, "systemReady"); 
           …… 
        } 
    } 
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.53.54.55.56.57.58.59.60.61.

SystemReady方法也是比较长,大致可以分为:

  • 第一:在systemReady的时候初始化了deviceIdleController等对象
  • 第二:移除并杀死了那些不该在AMS之前启动的进程
  • 第三:执行了参数传入的回调函数
  • 第四:启动了Launcer界面
  • 第五:启动那些persistent配置为1的进程;
  • 再来看些systemReady参数的回调函数做了什么工作.
try { 
                    //ams开始监听native层的crash信息 
                    mActivityManagerService.startObservingNativeCrashes(); 
                } catch (Throwable e) { 
                    reportWtf("observing native crashes", e); 
                } 
                //初始化webVew 
                WebViewFactory.prepareWebViewInSystemServer(); 
                try { 
                    //启动systemUI 
                    startSystemUi(context); 
                } catch (Throwable e) { 
                    reportWtf("starting System UI", e); 
                } 
                try { 
                    //调用其他服务的systemready方法 
                    if (networkScoreF != null) networkScoreF.systemReady(); 
                } catch (Throwable e) { 
                    reportWtf("making Network Score Service ready", e); 
                } 
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.

这个回调函数中主要工作就是启动systemUI并调用其他服务的systemReady方法,SystemReady函数完成了系统就绪的必要的工作,启动了HomeActivity和SystemUI,然后Android系统就全部启动了

APP启动流程分析

当Zygote收到请求:创建一个新的APP进程,之后,会调用ActivityThread的main()方法,代码如下:

可以看到在这里主要做了两件事情:

1>.创建并执行主线程的Looper循环

2>.创建ActivityThread对象,并调用attach(),这里与SystemServer进程不同的是APP的attch的参数是false SystemServer进程的是true. attrch为false时,代码如下:

在attachApplication()中,会找到attachApplicationLocked(),跟踪该方法。会看到如下代码区域:

这里的bindApplication又会通过Binder调用ActivityThread的bindApplication().代码如下:

这里看到主要做了两件事情:

1>.创建AppBindData

2>.通过调用sendMessage()发送Handler消息来调用handBindApplication()。跟到该方法。我们可以看App的Application的创建过程和执行。代码如下:

由上可知应用的Application在创建时的一些动作:

1>.获取到LoadedApk对象 一个应用对应一个LoadedApk

2>.创建应用所需的Context对象。

3>.创建Instrumentation对象。

4>.创建应用的Application

5>.通过调用Instrumentation的callApplicationOnCreate()调用Application的onCreate().

我们梳理一下Android APP启动流程:

如下图所示,系统从Launcher出发,SystemServer进程在收到Launcher进程的启动一个APP的请求后。会先去请求Zygote进程创建一个新的应用进程,此时还是一个空进程。然后Zygote进程就会调用ActivityThread去初始化这个进程,包括Instrumentation,ApplicationThread,AppBindData等对象,创建完以后才会去真正创建APP的根Activity,并调用他的生命周期。

这里主要分析的是上图的第三步的过程。Zygote在收到请求以后,ActivityThread和AMS之间是如何协同工作的,或者说第三步主要做了一些什么。我已经整理成xmind文档,如下图所示:

以上就是framework层学习的ams的启动流程以及app启动流程的解析;想要学习更多framework技术与源码解析可以参考《framework全家桶手册》,进行进阶学习。需要可以点击前往

总结

  • AMS是Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,其职责与操作系统中的进程管理和调度模块相类似,因此它在Android中非常重要;
  • 组件状态管理:包括四大组件的开启,关闭等一系列操作,如startActivity,startActivityAndWait,activityPaused,startService,stopService,removeContentProvider等;
  • 组件状态查询:查询组件当前运行等情况。如getCallingActivity,getService等;
  • Task相关:包括removeTask,removeSubTask,moveTaskBackwards,moveTaskToFront等;
  • AMS是通过ActivityStack及其他数据结构来记录,管理系统中的Activity及其他组件状态的,并提供查询功能的一个系统服务;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/103925.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Effective C++(三):资源管理

个人读书记录&#xff0c;不适用教学内容。 目录 条款13&#xff1a;以对象管理资源 条款14&#xff1a;在资源管理类中小心copying行为 条款15&#xff1a;在资源管理类中提供对原始资源的访问 条款16&#xff1a;成对使用new和delete时要采取相同形式 条款17&#xff1a…

cubeIDE开发, STM32实时时钟(RTC)写入及读取日历时间开发要点

一、RTC简介 实时时钟的缩写是RTC(Real_Time Clock)&#xff0c;核心是晶振&#xff0c;晶振频率一般为32768 Hz 。它为分频计数器提供精确的与低功耗的实基信号。它可以用于产生秒、分、时、日等信息。为了确保时钟长期的准确性&#xff0c;晶振必须正常工作&#xff0c;不能够…

中小企业的公司财务管理系统

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 本课题研究对象是中小企业财务管理系统&#xff0c;设计采用自己开发实践和所学知 识&#xff0c;系统部分主要分为以下…

【圣诞树代码】送她六棵圣诞树,祝她圣诞快乐~(送女朋友必备!)

“ 六棵圣诞树&#xff0c;满足她圣诞愿望 ” 距离25号圣诞节只有几天了&#xff0c;程序员有属于程序员的浪漫&#xff0c;这不来了~ 如果一颗圣诞树不够&#xff0c;那就送她六棵&#xff0c;祝她圣诞快乐~ 直接上效果图—— 01 02 03 04 05 06 代码如下&#xff1a; 第…

[1184]FinalShell下载安装

文章目录FinalShell介绍初步使用更换背景图连接记录删除FinalShell介绍 官网&#xff1a;http://www.hostbuf.com/ http://www.hostbuf.com/?install_fs FinalShell 简介&#xff1a; FinalShell 相当于 xshell ftp 的组合&#xff0c;即&#xff1a;FinalShell xshell f…

【计算机考研408】中断处理流程

中断请求 中断源是请求CPU中断的设备或事件&#xff0c;一台计算机允许有多个中断源。每个中断源向CPU发出中断请求的时间是随机的。 中断响应判优 中断响应优先级是指CPU响应中断请求的先后顺序。当多个中断源同时提出请求时&#xff0c;需通过中断判优逻辑来确定响应哪个中…

Python asyncore socket客户端开发基本使用

目录 介绍 1.定义类并且继承 asyncore.dispatcher 2.实现类中的回调代码 调用父类方法 创建 socket 对象 连接服务器 3.创建对象并且执行 asyncore.loop 进入运行循环 服务端示例代码 运行结果 注意&#xff1a; 介绍 asyncore库是python的一个标准库&#xff0c;提…

作为程序员,你离拿offer就差这个免费且好用的简历制作工具

为什么你的简历总是石沉大海&#xff1f;为什么你投递的岗位迟迟得不到回应&#xff1f;除了岗位招满、HR没看到以及竞争太激烈等客观因素外&#xff0c;最重要的是——“简历”出现了问题。 “简历”就像名片一样&#xff0c;在面试和求职的过程中&#xff0c;一份优质的简历…

数字孪生城市项目的关键技术展望

智慧城市是社会空间、物理空间和信息系统三元有机融合的条件下城市智慧化转型的新型态, 运用以数字孪生为代表的新一代信息化技术优化城市系统, 提升城市品质和综合竞争力, 从而实现可持续发展成为智慧城市构建的新趋势。 数字孪生城市项目的关键技术 北京智汇云舟科技有限公司…

chrome的几种存储storage模式

Storage生命周期存放数据大小与服务器通信localStore 除非被清除&#xff0c;否则永远保存 一般5MB 仅在客户端(即浏览器)中SessionStorage仅在当前会话下有效&#xff0c;关闭页面或者浏览器后被清除 一般5MB 保存&#xff0c;不参与和服务器的通信Cookies一般由服务器生成&a…

荣盛生物将再次上会:前三季度收入约2亿元,曾被暂缓审议

近日&#xff0c;上海证券交易所披露的信息显示&#xff0c;上海荣盛生物药业股份有限公司&#xff08;下称“荣盛生物”&#xff09;将于2022年12月26日接受科创板上市委员会的现场审议&#xff08;即“上会”&#xff09;。据贝多财经了解&#xff0c;荣盛生物曾于11月7月7日…

TCP滑动窗口、流量控制、拥塞控制

TCP滑动窗口、流量控制、拥塞控制一、滑动窗口二、流量控制三、拥塞控制一、滑动窗口 上篇博客我们介绍了TCP报文结构、确认应答机制、超时重传机制、连接管理机制。 TCP保证了可靠传输&#xff0c;但是失去了效率。那么怎么样尽可能提高传输效率呢&#xff1f;&#xff1f;&a…

react笔记_07组件实例化对象的三大属性

目录前提状态(state)作用状态使用总结属性(props)展开运算符复习props-作为属性传入数据props-使用展开运算符展开对象props-进行数据类型限制propTypes语法校验规则举例说明defaultProps语法举例说明refs字符串形式的ref语法举例说明注意点回调形式的ref什么叫做回调&#xff…

RT-Thread 简介

1.RT-Thread 概述 RT-Thread&#xff0c;全称是Real Time-Thread&#xff0c;顾名思义&#xff0c;它是一个嵌入式实时多线程操作系统&#xff0c; 基本属性之一是支持多任务&#xff0c;允许多个任务同时运行并不意味着处理器在同一时刻真地执行了多个任务。 事实上&#xff…

Redis实战——签到统计(BitMap的用法)

1. 什么是BitMap 我们针对签到功能完全可以通过mysql来完成&#xff0c;比如说以下这张表 但是&#xff0c;用户一次签到&#xff0c;就是一条记录&#xff0c;假如有1000万用户&#xff0c;平均每人每年签到次数为10次&#xff0c;则这张表一年的数据量为 1亿条。 每签到一次…

js实现图片的放大缩小(鼠标长按拖拽、鼠标滚轮控制放大缩小)

系列文章目录 文章目录系列文章目录背景与效果图1.背景如下&#xff08;功能图&#xff09;&#xff1a;2.效果图如下&#xff1a;拖拽后的效果缩放的效果放大的效果一、功能&#xff1a;支持鼠标长按拖拽1.鼠标事件&#xff1a;2.拖拽功能流程3.拖拽部分代码如下二、功能&…

HTTP报文详解

个人博客地址&#xff1a; http://xiaohe-blog.top/ 文章目录1. 请求1.1 请求行1.2 请求头1.3 空白行1.4 请求体2. 响应2.1 状态行2.2 响应头2.3 空白行2.4 响应体2.5 HTTP报文总结3. HTTP方法4. GET与POST的区别5. 状态码1. 请求 1.1 请求行 请求方式 请求地址 请求协议版本号…

指针进阶1 2

字符指针 int main() {char ch q;char* pa &ch;return 0; }不仅可以这样写还可以指向一个字符串 int main() {/*char ch q;char* pa &ch;*/char* ph "hello world";printf("%c\n", *ph);//打印遇到\0才会结束&#xff0c;没数据会打印随机值…

pybind11学习 | VS2022下安装配置

pybind11是一个只有头文件&#xff08;header-only&#xff09;的轻量级库&#xff0c;其主要目的是建立C的Python代码绑定&#xff0c;实现C和Python无缝连接。我学习这个工具的目的&#xff0c;是为了能够在Python中调用C代码实现一些计算密集型任务&#xff0c;同时培养自己…

Java后端核心技能知识点

今天带来的是2022全新升级的《Java岗面试核心版》&#xff0c;这个版本里面不仅仅包含了面试题&#xff0c;还有更多的技术难点、大厂算法、实战项目、简历模板等等&#xff0c;全册接近1700页&#xff01;相比上一个版本的287页&#xff0c;升级了多少内容你懂的 大概内容&am…