Android8.0.0-r4的APK的显示

       Android系统提供了一个默认的Home应用程序——Luncher,用来显示系统中已经安装了的应用程序,它是由System进程负责启动的,同时它也是系统中第一个启动的应用程序。
       将系统中已经安装了的应用程序显示出来的目的是为了让用户有一个统一的人口来启动它们,一个根AciLivity组件的启动过程就代表了一个应用程序的启动过程。 因此,应用程序Launcher在显示一个应用程序时,只需要获得它的根Activity组件信息即可

       一个应用程序的根Activity组件的类型被定义为CATEGORY_LAUNCHER,同时它的Action名称被定义为ACTION_MAIN,这样应用程序Launcher就可以通过这两个条件来请求Package管理服务PackageManagerService返回系统中所有已经安装了的应用程序的根Activity即组件信息。获得了系统中已经安装了的应用程序的根Activity组件信息之后,应用程序Launcher就会分别将它们封装成一个快捷图标,并且显示在系统的屏幕中,这样用户就可以通过点击这些快捷图标来启动相应的应用程序了。接下来,我们就通过分析应用程序Launcher的启动过程来说明系统中已经安装了的应用程序的显 示过程。 System进程是由 Zygote进程负责启动的, 而System进程在启动过程中, 又会创建一个ServerThread线程来启动系统中的关键服务。 当系统中的关键服务都启动起来之 后, 这个ServerThread线程就会通知Activity管理服务ActivityManagerService将应用程序Launcher启动起来。

1.在SystemServer中启动AMS服务

    代码路径:/frameworks/base/services/java/com/android/server/SystemServer.java

         (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/java/com/android/server/SystemServer.java)

259    public static void main(String[] args) {
260        new SystemServer().run();
261    }
 

在main中创建一个SystemServer的匿名对象并调用它的run函数

263    public SystemServer() {
264        // Check for factory test mode.
265        mFactoryTestMode = FactoryTest.getMode();
266        // Remember if it's runtime restart(when sys.boot_completed is already set) or reboot
267        mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));
268    }

创建匿名对象,在构造函数中得到启动模式和sys.boot_completed的属性。用来判断是否为正常模式启动和boot启动是否完成。

在run函数中会对系统属性进行初始化设置,并启动一些关键的服务:

391        // Start services.
392        try {
393            traceBeginAndSlog("StartServices");
394            startBootstrapServices();
395            startCoreServices();
396            startOtherServices();
397            SystemServerInitThreadPool.shutdown();

例如此次要说明的AMS服务就在startBootstrapServices()函数中启动

 
511        // Activity manager runs the show.
512        traceBeginAndSlog("StartActivityManager");
513        mActivityManagerService = mSystemServiceManager.startService(
514                ActivityManagerService.Lifecycle.class).getService();
515        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
516        mActivityManagerService.setInstaller(installer);
517        traceEnd();
 

startOtherServices()中调用AcitivtyManagerService的成员函数 systemReady()将应用程序Launcher启动起来。

1641        // We now tell the activity manager it is okay to run third party
1642        // code.  It will call back into us once it has gotten to the state
1643        // where third party code can really run (but before it has actually
1644        // started launching the initial applications), for us to complete our
1645        // initialization.
1646        mActivityManagerService.systemReady(() -> {
1647            Slog.i(TAG, "Making services ready");
1648            traceBeginAndSlog("StartActivityManagerReadyPhase");
1649            mSystemServiceManager.startBootPhase(
1650                    SystemService.PHASE_ACTIVITY_MANAGER_READY);
1651            traceEnd();
1652            traceBeginAndSlog("StartObservingNativeCrashes");
1653            try {
1654                mActivityManagerService.startObservingNativeCrashes();
1655            } catch (Throwable e) {
1656                reportWtf("observing native crashes", e);
1657            }
1658            traceEnd();
          ............................................

2.ActivityManagerService.systemReady

代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java    (http://androidxref.com/8.0.0_r4/xref//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java)

在校验系统底层启动完成后,通过AMS类的成员函数startHomeActivityLocked来执行启动应用程序Launcher的操作。

14031
14032    public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
14033        traceLog.traceBegin("PhaseActivityManagerReady");
14034        synchronized(this) {
14035            if (mSystemReady) {
      .....................................

14144            mBooting = true;
14145            // Enable home activity for system user, so that the system can always boot. We don't
14146            // do this when the system user is not setup since the setup wizard should be the one
14147            // to handle home activity in this case.
14148            if (UserManager.isSplitSystemUser() &&
14149                    Settings.Secure.getInt(mContext.getContentResolver(),
14150                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14151                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14152                try {
14153                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14154                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14155                            UserHandle.USER_SYSTEM);
14156                } catch (RemoteException e) {
14157                    throw e.rethrowAsRuntimeException();
14158                }
14159            }
14160            startHomeActivityLocked(currentUserId, "systemReady");
14161
14162            try {
14163                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14164                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14165                            + " data partition or your device will be unstable.");
14166                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14167                }
14168            } catch (RemoteException e) {
14169            }
14199            } catch (Throwable t) {
14200                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14201            } finally {
14202                Binder.restoreCallingIdentity(ident);
14203            }
14204            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14205            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14206            traceLog.traceEnd(); // ActivityManagerStartApps
14207            traceLog.traceEnd(); // PhaseActivityManagerReady
14208        }
14209    }
 

3.ActivityManagerService.startHomeActivityLocked

代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java    (http://androidxref.com/8.0.0_r4/xref//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java)

在AMS的成员函数startHomeActivityLocked中,通过getHomeIntent()来获取启动Launcher的Intent,通过resolveActivityInfo(intent, STOCK_PM_FLAGS, userId)获取要启动的Launcher的主Activity的信息,最后通过调用ActivityStarter.startHomeActivityLocked(intent, aInfo, myReason)来真正启动Launcher。

4048    boolean startHomeActivityLocked(int userId, String reason) {

4049        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4050                && mTopAction == null) {
4051            // We are running in factory test mode, but unable to find
4052            // the factory test app, so just sit around displaying the
4053            // error message and don't try to start anything.
4054            return false;
4055        }
4056        Intent intent = getHomeIntent();//获取启动Launcher的Intent
4057        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);//获取要启动的Launcher的主Activity的信息
4058        if (aInfo != null) {
4059            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4060            // Don't do this if the home app is currently being
4061            // instrumented.
4062            aInfo = new ActivityInfo(aInfo);
4063            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4064            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4065                    aInfo.applicationInfo.uid, true);
4066            if (app == null || app.instr == null) {
4067                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4068                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4069                // For ANR debugging to verify if the user activity is the one that actually
4070                // launched.
4071                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4072                mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4073            }
4074        } else {
4075            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4076        }
4077
4078        return true;
4079    }

4.ActivityStarter.startHomeActivityLocked

代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java    (http://androidxref.com/8.0.0_r4/xref//frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java)

最后通过调用来启动Launcher的主Activity,通过Launcher来将应用图标显示在桌面上

640    void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
641        mSupervisor.moveHomeStackTaskToTop(reason);
642        mLastHomeActivityStartResult = startActivityLocked(null /*caller*/, intent,
643                null /*ephemeralIntent*/, null /*resolvedType*/, aInfo, null /*rInfo*/,
644                null /*voiceSession*/, null /*voiceInteractor*/, null /*resultTo*/,
645                null /*resultWho*/, 0 /*requestCode*/, 0 /*callingPid*/, 0 /*callingUid*/,
646                null /*callingPackage*/, 0 /*realCallingPid*/, 0 /*realCallingUid*/,
647                0 /*startFlags*/, null /*options*/, false /*ignoreTargetSecurity*/,
648                false /*componentSpecified*/, mLastHomeActivityStartRecord /*outActivity*/,
649                null /*container*/, null /*inTask*/, "startHomeActivity: " + reason);
650        if (mSupervisor.inResumeTopActivity) {
651            // If we are in resume section already, home activity will be initialized, but not
652            // resumed (to avoid recursive resume) and will stay that way until something pokes it
653            // again. We need to schedule another resume.
654            mSupervisor.scheduleResumeTopActivities();
655        }
656    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值