美文网首页
源码分析之App启动源码分析

源码分析之App启动源码分析

作者: 噜噜丶 | 来源:发表于2017-09-14 23:31 被阅读0次

    想必大家都知道Java程序在启动的时候,最开始加载的函数是main函数

    public static void main(String [] args){
            
        }
    

    那么我们Android应用程序是基于Java虚拟机进行开发的,自然入口函数也是main函数,可是平时我们在写Android应用程序并没有看到这个东西啊。那么接下来我们从main函数看起,在桌面点击了App那一刻到底发生了什么。首先来到ActivityThread下,main函数就在这里。

     public static void main(String[] args) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
           //省略部分代码   这里调用了Looper.prepare,解释了我们在主线程可以直接通过Handler去取消息,而在子线程需要手动初始化Looper
            Looper.prepareMainLooper();
    
            ActivityThread thread = new ActivityThread();
    //主要代码是这行,绑定了ActivityThread
            thread.attach(false);
    
            if (sMainThreadHandler == null) {
                sMainThreadHandler = thread.getHandler();
            }
    
            if (false) {
                Looper.myLooper().setMessageLogging(new
                        LogPrinter(Log.DEBUG, "ActivityThread"));
            }
    
            // End of event ActivityThreadMain.
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            Looper.loop();
    
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
    

    这里主要就是对ActivityThread进行绑定,那我们继续

     private void attach(boolean system) {
            sCurrentActivityThread = this;
            mSystemThread = system;
          //省略部分源码
                RuntimeInit.setApplicationObject(mAppThread.asBinder());
                final IActivityManager mgr = ActivityManagerNative.getDefault();
                try {
                    mgr.attachApplication(mAppThread);
                } catch (RemoteException ex) {
                    // Ignore
                }
    

    可以看到绑定了Application,不过这个ActivityManagerNative.getDefault()是个什么还需要仔细考量。

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
            protected IActivityManager create() {
                IBinder b = ServiceManager.getService("activity");
                if (false) {
                    Log.v("ActivityManager", "default service binder = " + b);
                }
                IActivityManager am = asInterface(b);
                if (false) {
                    Log.v("ActivityManager", "default service = " + am);
                }
                return am;
            }
        };
    

    我们可以看到ActivityManagerNative.getDefault()拿到的是一个标准的单例
    ,那我们继续看下去,这里通过ServiceManager.getService("activity"),我们来到了ActivityManagerService这个类下,找到如何添加

     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));
    

    我们点开Context.ACTIVITY_SERVICE = “activity”,这不就是我们要找的吗,这里传递了一个this进去,这个this指向的是当前的ActivityManagerService,那么我们在ActivityThread最开始看到的就是调用的ActivityManagerService的attachApplication,总算找到码头了。

    final IActivityManager mgr = ActivityManagerNative.getDefault();
                try {
                    mgr.attachApplication(mAppThread);
    
    private final boolean attachApplicationLocked(IApplicationThread thread,
                int pid) {
    //省略部分源码,太长了,还是看重要的方法为妙,容易懵逼
     ProfilerInfo profilerInfo = profileFile == null ? null
                        : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
                thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                        profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                        app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(mConfiguration), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked());
                updateLruProcessLocked(app, false, null);
                app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
    }
    

    这里看到我们又回到了ActivityThread里面。

    public final void bindApplication(String processName, ApplicationInfo appInfo,
                    List<ProviderInfo> providers, ComponentName instrumentationName,
                    ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                    IInstrumentationWatcher instrumentationWatcher,
                    IUiAutomationConnection instrumentationUiConnection, int debugMode,
                    boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
                    Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
                    Bundle coreSettings) {
    
                if (services != null) {
                    // Setup the service cache in the ServiceManager
                    ServiceManager.initServiceCache(services);
                }
    
                setCoreSettings(coreSettings);
                IPackageManager pm = getPackageManager();
                android.content.pm.PackageInfo pi = null;
                try {
                    pi = pm.getPackageInfo(appInfo.packageName, 0, UserHandle.myUserId());
                } catch (RemoteException e) {
                }
                if (pi != null) {
                    boolean sharedUserIdSet = (pi.sharedUserId != null);
                    boolean processNameNotDefault =
                    (pi.applicationInfo != null &&
                     !appInfo.packageName.equals(pi.applicationInfo.processName));
                    boolean sharable = (sharedUserIdSet || processNameNotDefault);
    
                    // Tell the VMRuntime about the application, unless it is shared
                    // inside a process.
                    if (!sharable) {
                        VMRuntime.registerAppInfo(appInfo.packageName, appInfo.dataDir,
                                                appInfo.processName);
                    }
                }
    
                AppBindData data = new AppBindData();
                data.processName = processName;
                data.appInfo = appInfo;
                data.providers = providers;
                data.instrumentationName = instrumentationName;
                data.instrumentationArgs = instrumentationArgs;
                data.instrumentationWatcher = instrumentationWatcher;
                data.instrumentationUiAutomationConnection = instrumentationUiConnection;
                data.debugMode = debugMode;
                data.enableOpenGlTrace = enableOpenGlTrace;
                data.restrictedBackupMode = isRestrictedBackupMode;
                data.persistent = persistent;
                data.config = config;
                data.compatInfo = compatInfo;
                data.initProfilerInfo = profilerInfo;
                sendMessage(H.BIND_APPLICATION, data);
            }
    

    也只是初始化了ServiceManager,通过Handler去发送了一个消息。 那我们是走错码头了吗,那还是继续回到ActivityManagerService的attachApplicationLocked

     if (normalMode) {
                try {
    //注意,在这里把我们的app传进去了
                    if (mStackSupervisor.attachApplicationLocked(app)) {
                        didSomething = true;
                    }
                } catch (Exception e) {
                    Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                    badApp = true;
                }
            }
    
    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
            final String processName = app.processName;
            boolean didSomething = false;
            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
                ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                    final ActivityStack stack = stacks.get(stackNdx);
                    if (!isFrontStack(stack)) {
                        continue;
                    }
                    ActivityRecord hr = stack.topRunningActivityLocked(null);
                    if (hr != null) {
                        if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                                && processName.equals(hr.processName)) {
                            try {
            //这里就是 真的要去启动Activity了!!!
                                if (realStartActivityLocked(hr, app, true, true)) {
                                    didSomething = true;
                                }
                            } catch (RemoteException e) {
                                Slog.w(TAG, "Exception in new application when starting activity "
                                      + hr.intent.getComponent().flattenToShortString(), e);
                                throw e;
                            }
                        }
                    }
                }
            }
            if (!didSomething) {
                ensureActivitiesVisibleLocked(null, 0);
            }
            return didSomething;
        }
    

    千辛万苦,终于要即将开始启动我们的Activity了,哈哈哈。

    final boolean realStartActivityLocked(ActivityRecord r,
                ProcessRecord app, boolean andResume, boolean checkConfig)
                throws RemoteException {
    //在这里做了一些判断,判断当前是否是resume状态回来的
     if (andResume) {
                    app.hasShownUi = true;
                    app.pendingUiClean = true;
                }
                app.forceProcessStateUpTo(mService.mTopProcessState);
                app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                        System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                        new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
                        task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                        newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
    }
    
     public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                    ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                    CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                    int procState, Bundle state, PersistableBundle persistentState,
                    List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                    boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
    
                updateProcessState(procState, false);
    
                ActivityClientRecord r = new ActivityClientRecord();
    
                r.token = token;
                r.ident = ident;
                r.intent = intent;
                r.referrer = referrer;
                r.voiceInteractor = voiceInteractor;
                r.activityInfo = info;
                r.compatInfo = compatInfo;
                r.state = state;
                r.persistentState = persistentState;
    
                r.pendingResults = pendingResults;
                r.pendingIntents = pendingNewIntents;
    
                r.startsNotResumed = notResumed;
                r.isForward = isForward;
    
                r.profilerInfo = profilerInfo;
    
                r.overrideConfig = overrideConfig;
                updatePendingConfiguration(curConfig);
    
                sendMessage(H.LAUNCH_ACTIVITY, r);
            }
    

    可以看到验证了我们客户端Activity的一些信息之后,还是通过Handler发送消息来启动我们的Activity。

     public void handleMessage(Message msg) {
                if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
                switch (msg.what) {
                    case LAUNCH_ACTIVITY: {
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                        final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
    
                        r.packageInfo = getPackageInfoNoCheck(
                                r.activityInfo.applicationInfo, r.compatInfo);
                        handleLaunchActivity(r, null);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    } break;
                    case RELAUNCH_ACTIVITY: {
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
                        ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                        handleRelaunchActivity(r);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    } break;
                    case PAUSE_ACTIVITY:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                        handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,
                                (msg.arg1&2) != 0);
                        maybeSnapshot();
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case PAUSE_ACTIVITY_FINISHING:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                        handlePauseActivity((IBinder)msg.obj, true, (msg.arg1&1) != 0, msg.arg2,
                                (msg.arg1&1) != 0);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case STOP_ACTIVITY_SHOW:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
                        handleStopActivity((IBinder)msg.obj, true, msg.arg2);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case STOP_ACTIVITY_HIDE:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
                        handleStopActivity((IBinder)msg.obj, false, msg.arg2);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case SHOW_WINDOW:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
                        handleWindowVisibility((IBinder)msg.obj, true);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case HIDE_WINDOW:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
                        handleWindowVisibility((IBinder)msg.obj, false);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case RESUME_ACTIVITY:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
                        handleResumeActivity((IBinder) msg.obj, true, msg.arg1 != 0, true);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case SEND_RESULT:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
                        handleSendResult((ResultData)msg.obj);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case DESTROY_ACTIVITY:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
                        handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
                                msg.arg2, false);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
    

    在这里看到我们activity的生命周期都在这里。看来方向没有错啊,赶紧捧起了我的咖啡继续干起来。我们这边就从StartActiviy这个看吧。

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        
            // Initialize before creating the activity
            WindowManagerGlobal.initialize();
    
            Activity a = performLaunchActivity(r, customIntent);
    
            if (a != null) {
                r.createdConfig = new Configuration(mConfiguration);
                Bundle oldState = r.state;
                handleResumeActivity(r.token, false, r.isForward,
                        !r.activity.mFinished && !r.startsNotResumed);
    
                if (!r.activity.mFinished && r.startsNotResumed) {
                    // The activity manager actually wants this one to start out
                    // paused, because it needs to be visible but isn't in the
                    // foreground.  We accomplish this by going through the
                    // normal startup (because activities expect to go through
                    // onResume() the first time they run, before their window
                    // is displayed), and then pausing it.  However, in this case
                    // we do -not- need to do the full pause cycle (of freezing
                    // and such) because the activity manager assumes it can just
                    // retain the current state it has.
                    try {
                        r.activity.mCalled = false;
                        mInstrumentation.callActivityOnPause(r.activity);
                       
                        if (r.isPreHoneycomb()) {
                            r.state = oldState;
                        }
                        if (!r.activity.mCalled) {
                            throw new SuperNotCalledException(
                                "Activity " + r.intent.getComponent().toShortString() +
                                " did not call through to super.onPause()");
                        }
    
                    } catch (SuperNotCalledException e) {
                        throw e;
    
                    } catch (Exception e) {
                        if (!mInstrumentation.onException(r.activity, e)) {
                            throw new RuntimeException(
                                    "Unable to pause activity "
                                    + r.intent.getComponent().toShortString()
                                    + ": " + e.toString(), e);
                        }
                    }
                    r.paused = true;
                }
            } else {
                // If there was an error, for any reason, tell the activity
                // manager to stop us.
                try {
                    ActivityManagerNative.getDefault()
                        .finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
                } catch (RemoteException ex) {
                    // Ignore
                }
            }
        }
    

    我们可以看到Activity a = performLaunchActivity(r, customIntent);
    哇,我们的Activity来了,那我们在平时都是new Activity,这里到底怎么拿到Activity的呢。?

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    //验证Activity的信息,Intent,最后通过反射拿到Activity的实例、
    Activity activity = null;
            try {
                java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
                activity = mInstrumentation.newActivity(
                        cl, component.getClassName(), r.intent);
                StrictMode.incrementExpectedActivityCount(activity.getClass());
                r.intent.setExtrasClassLoader(cl);
                r.intent.prepareToEnterProcess();
                if (r.state != null) {
                    r.state.setClassLoader(cl);
                }
            } catch (Exception e) {
                if (!mInstrumentation.onException(activity, e)) {
                    throw new RuntimeException(
                        "Unable to instantiate activity " + component
                        + ": " + e.toString(), e);
                }
            }
    }
    

    顿觉索然无味,其实源码也是反射来拿到这个Activity。
    到这里,我们的Activity实例已经拿到了,那么Activity的生命还没看到调用啊,onCreate,onStart呢?那我们继续在这里方法看下去,可以看到这样的代码。

      activity.mCalled = false;
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnCreate(activity, r.state);
                    }
    

    嗯,对,callActivityOnCreate!!!从单词都知道这是调用onCreate()了。hhh~~

     public void callActivityOnCreate(Activity activity, Bundle icicle,
                PersistableBundle persistentState) {
            prePerformCreate(activity);
            activity.performCreate(icicle, persistentState);
            postPerformCreate(activity);
        }
    

    activity.performCreate(icicle, persistentState);那么我们只要到Activity下搜索一下这个方法就可以看到onCreate()的调用啦~~

    文章基于Android源码7.0,也许大家看的源码各不相同,本质缺大同小异,个人理解如有差错,欢迎评论指出。

    相关文章

      网友评论

          本文标题:源码分析之App启动源码分析

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