美文网首页
Android进程被启动后,启动组件方式

Android进程被启动后,启动组件方式

作者: 雪国落叶 | 来源:发表于2020-03-22 23:31 被阅读0次

    当启动组件时,如果被启动组件所在的进程不存在,需要先启动组件所在的进程,然后再执行启动组件。
    AMS通过socket----->zygote--->fork进程-->执行ActivityThread main方法-->执行AMS#attachApplication
    在attachApplication:

    private final boolean attachApplicationLocked(IApplicationThread thread,
                int pid, int callingUid, long startSeq) {
            ProcessRecord app;
            long startTime = SystemClock.uptimeMillis();
            if (pid != MY_PID && pid >= 0) {
                synchronized (mPidsSelfLocked) {
                    app = mPidsSelfLocked.get(pid);
                }
            } else {
                app = null;
            }
           // It's possible that process called attachApplication before we got a chance to
            // update the internal state.
            if (app == null && startSeq > 0) {
                final ProcessRecord pending = mPendingStarts.get(startSeq);
                if (pending != null && pending.startUid == callingUid
                        && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
                                startSeq, true)) {
                    app = pending;
                }
            }
          // 处理provider
           mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
    
            boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
            List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
    
            if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
                Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
                msg.obj = app;
                mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
            }
    
            if (app.isolatedEntryPoint != null) {
                    // This is an isolated process which should just call an entry point instead of
                    // being bound to an application.
                    thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
                } else if (app.instr != null) {
                    thread.bindApplication(processName, appInfo, providers,
                            app.instr.mClass,
                            profilerInfo, app.instr.mArguments,
                            app.instr.mWatcher,
                            app.instr.mUiAutomationConnection, testMode,
                            mBinderTransactionTrackingEnabled, enableTrackAllocation,
                            isRestrictedBackupMode || !normalMode, app.persistent,
                            new Configuration(getGlobalConfiguration()), app.compat,
                            getCommonServicesLocked(app.isolated),
                            mCoreSettingsObserver.getCoreSettingsLocked(),
                            buildSerial, isAutofillCompatEnabled);
                } else {
                    thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                            null, null, null, testMode,
                            mBinderTransactionTrackingEnabled, enableTrackAllocation,
                            isRestrictedBackupMode || !normalMode, app.persistent,
                            new Configuration(getGlobalConfiguration()), app.compat,
                            getCommonServicesLocked(app.isolated),
                            mCoreSettingsObserver.getCoreSettingsLocked(),
                            buildSerial, isAutofillCompatEnabled);
                }
    
               updateLruProcessLocked(app, false, null);
               // Remove this record from the list of starting applications.
               mPersistentStartingProcesses.remove(app);
                if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
                       "Attach application locked removing on hold: " + app);
                mProcessesOnHold.remove(app);
                
           // 处理activity  See if the top visible activity is waiting to run in this process...
            if (normalMode) {
                try {
                    if (mStackSupervisor.attachApplicationLocked(app)) {
                        didSomething = true;
                    }
                } catch (Exception e) {
                    Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                    badApp = true;
                }
            }
    
            // 处理服务  Find any services that should be running in this process...
            if (!badApp) {
                try {
                    didSomething |= mServices.attachApplicationLocked(app, processName);
                    checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
                } catch (Exception e) {
                    Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                    badApp = true;
                }
            }
    
            // 处理广播 Check if a next-broadcast receiver is in this process...
            if (!badApp && isPendingBroadcastProcessLocked(pid)) {
                try {
                    didSomething |= sendPendingBroadcastsLocked(app);
                    checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
                } catch (Exception e) {
                    // If the app died trying to launch the receiver we declare it 'bad'
                    Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
                    badApp = true;
                }
            }
    

    首先里面没有关于provider的处理,因为进程启动后,会installProvider启动所有的provider。所以不需要做选择性处理。
    1.启动activity部分
    mStackSupervisor.attachApplicationLocked(app)---> realStartActivityLocked-->app.thread.sheduleLaunchActivity 发送LAUNCH_ACTIVITY-->ActivityThread#handleLaunchActivity--> performLaunchActivity-->Instrumentation.newActivity-->Instrumentation.callActivityOnCreate()

    在attachApplicationLocked过程中,会查找到focusedStack,然后从这个栈里面获取所有运行可见的列表,
    遍历列表,activity.app == null表示还没有启动,并且uid和processName一致,则执行realStartActivityLocked

    final String processName = app.processName;
            boolean didSomething = false;
            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
                final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
                for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
                    final ActivityStack stack = display.getChildAt(stackNdx);
                    if (!isFocusedStack(stack)) {
                        continue;
                    }
                    stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
                    final ActivityRecord top = stack.topRunningActivityLocked();
                    final int size = mTmpActivityList.size();
                    for (int i = 0; i < size; i++) {
                        final ActivityRecord activity = mTmpActivityList.get(i);
                        if (activity.app == null && app.uid == activity.info.applicationInfo.uid
                                && processName.equals(activity.processName)) {
                            try {
                                if (realStartActivityLocked(activity, app,
                                        top == activity /* andResume */, true /* checkConfig */)) {
                                    didSomething = true;
                                }
                            } catch (RemoteException e) {
                                Slog.w(TAG, "Exception in new application when starting activity "
                                        + top.intent.getComponent().flattenToShortString(), e);
                                throw e;
                            }
                        }
                    }
                }
            }
            if (!didSomething) {
                ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
            }
            return didSomething;
    
    1. 处理服务
      mServices.attachApplicationLocked(app, processName);

    参考:
    https://blog.csdn.net/qq_26287435/article/details/104905607?fps=1&locationNum=2

    相关文章

      网友评论

          本文标题:Android进程被启动后,启动组件方式

          本文链接:https://www.haomeiwen.com/subject/crqjyhtx.html