app( activity) 启动流程

来源:互联网 发布:oracle sql rowcount 编辑:程序博客网 时间:2024/06/05 16:58

本文主要通过app启动后,分析系统源码的方式来讲解activity启动,本文占时不讲Binder机制

ps:下次有空会学习并且写下Binder机制,况且我的glide源码还没有写完。本人水平有限,欢迎有老司机过来飙车,指教!

这里写图片描述
本文涉及以下几个源码:

  1. ActivityThread
  2. ActivityManagerNative
  3. ActivityManagerService
  4. ActivityStackSupervisor
  5. Instrumentation
  6. Activity
    上面的源码可以通过:
    自己的sdk找到 路径大致为:G:\developsoft\android\sdk_as\sources
    或者通过系统源码下载 这篇文章的网站去下载相关的代码

ok,我们首先来回顾一下,在java中 ,我们要运行一个类,肯定会有一个主函数的入口,那么android也是一样的。
正式开车:
我们根据一个调用的时序图来深入简出的分析代码:

上图;
这里写图片描述
这里写图片描述
这里写图片描述

图片太大了,还不知道怎么截成一张整图,有经验老司机,请留意指教。

好了,我们来看 ActivityThread
这里只看关键的代码:

//主函数的入口函数 public static void main(String[] args) {        SamplingProfilerIntegration.start();        // CloseGuard defaults to true and can be quite spammy.  We        // disable it here, but selectively enable it later (via        // StrictMode) on debug builds, but using DropBox, not logs.        CloseGuard.setEnabled(false);        Environment.initForCurrentUser();        // Set the reporter for event logging in libcore        EventLogger.setReporter(new EventLoggingReporter());        Security.addProvider(new AndroidKeyStoreProvider());        // Make sure TrustedCertificateStore looks in the right place for CA certificates        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());        TrustedCertificateStore.setDefaultUserDirectory(configDir);        Process.setArgV0("<pre-initialized>");        //初始化主线程的Looper        Looper.prepareMainLooper();        ActivityThread thread = new ActivityThread();        thread.attach(false);        if (sMainThreadHandler == null) {            sMainThreadHandler = thread.getHandler();        }        if (false) {            Looper.myLooper().setMessageLogging(new                    LogPrinter(Log.DEBUG, "ActivityThread"));        }    //Looper开始轮询        Looper.loop();        throw new RuntimeException("Main thread loop unexpectedly exited");    }

看这个方法 thread.attach(false);删除其他的方法,我们只留关键的代码。

 private void attach(boolean system) {        //判断是否是系统应用        sCurrentActivityThread = this;        mSystemThread = system;        if (!system) {          //非系统应用            ViewRootImpl.addFirstDrawHandler(new Runnable() {                @Override                public void run() {                    ensureJitEnabled();                }            });            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",                                                    UserHandle.myUserId());            RuntimeInit.setApplicationObject(mAppThread.asBinder());            //2、调用 ActivityManagerNative.getDefault();            final IActivityManager mgr = ActivityManagerNative.getDefault();            try {                //7. mgr.attachApplication(mAppThread);                mgr.attachApplication(mAppThread);            } catch (RemoteException ex) {                // Ignore            }            // Watch for getting close to heap limit.            BinderInternal.addGcWatcher(new Runnable() {                @Override public void run() {                    if (!mSomeActivitiesChanged) {                        return;                    }                    Runtime runtime = Runtime.getRuntime();                    long dalvikMax = runtime.maxMemory();                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();                    if (dalvikUsed > ((3*dalvikMax)/4)) {                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)                                + " total=" + (runtime.totalMemory()/1024)                                + " used=" + (dalvikUsed/1024));                        mSomeActivitiesChanged = false;                        try {                            mgr.releaseSomeActivities(mAppThread);                        } catch (RemoteException e) {                        }                    }                }            });        } else {          //系统应用        }        // add dropbox logging to libcore        DropBox.setReporter(new DropBoxReporter());        ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {            @Override            public void onConfigurationChanged(Configuration newConfig) {                synchronized (mResourcesManager) {                    // We need to apply this change to the resources                    // immediately, because upon returning the view                    // hierarchy will be informed about it.                    if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {                        // This actually changed the resources!  Tell                        // everyone about it.                        if (mPendingConfiguration == null ||                                mPendingConfiguration.isOtherSeqNewer(newConfig)) {                            mPendingConfiguration = newConfig;                            sendMessage(H.CONFIGURATION_CHANGED, newConfig);                        }                    }                }            }            @Override            public void onLowMemory() {            }            @Override            public void onTrimMemory(int level) {            }        });    }

执行到 IActivityManager mgr = ActivityManagerNative.getDefault(); 这个方法,我们看看这个方法返回了什么?
我们来到:ActivityManagerNative

  /**     * Retrieve the system's default/global activity manager.     */    //3、调用IActivityManager getDefault()    static public IActivityManager getDefault() {        return gDefault.get();    }

接着调用:

  //4、    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {        protected IActivityManager create() {            //4、谁返回来的?            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;        }    };

这样就关联上了ActivityManagerService 我们看这句代码 IBinder b = ServiceManager.getService(“activity”); 那么我们去ActivityManagerService 是什么时候add进去的?我们继续往下看

 public static void setSystemProcess() {        try {            ActivityManagerService m = mSelf;        //5、添加进去            ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);            ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats);            ServiceManager.addService("meminfo", new MemBinder(m));            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));            ServiceManager.addService("dbinfo", new DbBinder(m));            if (MONITOR_CPU_USAGE) {                ServiceManager.addService("cpuinfo", new CpuBinder(m));            }            ServiceManager.addService("permission", new PermissionController(m));    }

我们接着回到 ActivityThread 找到 mgr.attachApplication(mAppThread);

    if (!system) {            ViewRootImpl.addFirstDrawHandler(new Runnable() {                @Override                public void run() {                    ensureJitEnabled();                }            });            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",                                                    UserHandle.myUserId());            RuntimeInit.setApplicationObject(mAppThread.asBinder());            //2、调用 ActivityManagerNative.getDefault();            final IActivityManager mgr = ActivityManagerNative.getDefault();            try {                //7. mgr.attachApplication(mAppThread);                mgr.attachApplication(mAppThread);            } catch (RemoteException ex) {                // Ignore            }

就是调用ActivityManagerService 里的 attachApplication(IApplicationThread thread)方法

 @Override    public final void attachApplication(IApplicationThread thread) {        synchronized (this) {            int callingPid = Binder.getCallingPid();            final long origId = Binder.clearCallingIdentity();            //我们注意这个方法 attachApplicationLocked(thread, callingPid);            attachApplicationLocked(thread, callingPid);            Binder.restoreCallingIdentity(origId);        }    }

我们来看下 attachApplicationLocked(thread, callingPid); 我只看一些关键的方法

  private final boolean attachApplicationLocked(IApplicationThread thread,            int pid) {        // See if the top visible activity is waiting to run in this process...        if (normalMode) {            try {                //10\ attachApplicationLocked(app, mHeadless)                if (mStackSupervisor.attachApplicationLocked(app, mHeadless)) {                    didSomething = true;                }            } catch (Exception e) {                badApp = true;            }        }        // Find any services that should be running in this process...        if (!badApp) {            try {                didSomething |= mServices.attachApplicationLocked(app, processName);            } catch (Exception e) {                badApp = true;            }        }        // Check if a next-broadcast receiver is in this process...        if (!badApp && isPendingBroadcastProcessLocked(pid)) {            try {                didSomething |= sendPendingBroadcastsLocked(app);            } catch (Exception e) {                // If the app died trying to launch the receiver we declare it 'bad'                badApp = true;            }        }        return true;    }

这就进入一个关键类了 ActivityStackSupervisor 我们看这个方法mStackSupervisor.attachApplicationLocked(app, mHeadless)

这里由于版本不一样,有的版本参数是2个,有的是一个,忽略这些细节,如果费用纠结这些细节的话,请一定要下载版本一直的源码,这里我就偷个懒,不下载了。

我们来看看ActivityStackSupervisor 这个类

boolean attachApplicationLocked(ProcessRecord app) throws Exception {        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 {                   //看这个方法的名字就能猜到干啥的了, realStartActivityLocked()                            if (realStartActivityLocked(hr, app, true, true)) {                                didSomething = true;                            }                        } catch (Exception e) {                            Slog.w(TAG, "Exception in new application when starting activity "                                  + hr.intent.getComponent().flattenToShortString(), e);                            throw e;                        }                    }                }            }        }

我们来看看 ActivityStackSupervisor 里的 realStartActivityLocked()都做了啥?

//9真正的启动    final boolean realStartActivityLocked(ActivityRecord r,            ProcessRecord app, boolean andResume, boolean checkConfig)            throws RemoteException {            //执行启动的方法            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,                    System.identityHashCode(r), r.info,                    new Configuration(mService.mConfiguration), r.compat,                    app.repProcState, r.icicle, results, newIntents, !andResume,                    mService.isNextTransitionForward(), profileFile, profileFd,                    profileAutoStop);            if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {                // This may be a heavy-weight process!  Note that the package                // manager will ensure that only activity can run in the main                // process of the .apk, which is the only thing that will be                // considered heavy-weight.                if (app.processName.equals(app.info.packageName)) {                    if (mService.mHeavyWeightProcess != null                            && mService.mHeavyWeightProcess != app) {                        Slog.w(TAG, "Starting new heavy weight process " + app                                + " when already running "                                + mService.mHeavyWeightProcess);                    }                    mService.mHeavyWeightProcess = app;                    Message msg = mService.mHandler.obtainMessage(                            ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);                    msg.obj = r;                    mService.mHandler.sendMessage(msg);                }            }        } catch (RemoteException e) {            if (r.launchFailed) {                // This is the second time we failed -- finish activity                // and give up.                Slog.e(TAG, "Second failure launching "                      + r.intent.getComponent().flattenToShortString()                      + ", giving up", e);                mService.appDiedLocked(app, app.pid, app.thread);                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,                        "2nd-crash", false);                return false;            }            // This is the first time we failed -- restart process and            // retry.            app.activities.remove(r);            throw e;        }        return true;    }

我们来看上面的这个方法 app.thread.scheduleLaunchActivity( ) app.thread又回到了ActivityThread类中,我们看看这个方法有些什么

   public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,                ActivityInfo info, Configuration curConfig, 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();      //看到这里感觉熟悉了吧,发送了一个消息我们来找找看            sendMessage(H.LAUNCH_ACTIVITY, r);        }

我们在handleMessage(Message msg) 中找到了 handleLaunchActivity(r, null);

    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);                    //通过handle启动activity                    handleLaunchActivity(r, null);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                } break;

接着源码继续看 handleLaunchActivity(ActivityClientRecord r, Intent customIntent)

private void  handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {        // If we are getting ready to gc after going to the background, well        // we are back active so skip it.        //执行启动        Activity a = performLaunchActivity(r, customIntent);        } 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            }        }    }

我们看到 通过反射的方式 mInstrumentation.newActivity( cl, component.getClassName(), r.intent);创建了一个 Activity。 好了,到了我们今天最后的一个类,也是最重要的一个类了,希望你坚持看下去:mInstrumentation 代表的就是 Instrumentation

rivate Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");        Activity activity = null;        //反射创建一个Activity        try {            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);            }        }        return activity;    }

我们来看看Instrumentation 他是如何创建一个activity的

 public Activity newActivity(ClassLoader cl, String className,            Intent intent)            throws InstantiationException, IllegalAccessException,            ClassNotFoundException {        return (Activity)cl.loadClass(className).newInstance();    }

我们在回 ActivityThread 看看 mInstrumentation 都调用哪些方法?
mInstrumentation.callActivityOnDestroy(r.activity);
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,r.persistentState);
mInstrumentation.callActivityOnDestroy(r.activity);
mInstrumentation.callActivityOnPause(r.activity);
mInstrumentation.callActivityOnUserLeaving(r.activity);
~~~~~~~~~~~~~~~~~~~~~~~~~等等 剩下方法 童靴你自己找下吧
我们来举例看一个 mInstrumentation.callActivityOnPause(r.activity); 里面它是怎么实现的?
我们在 Instrumentation 发现 是调用 activity.performPause();

   public void callActivityOnPause(Activity activity) {        activity.performPause();    }

那我们在去activity的源码一探究竟。

final void performPause() {        mDoReportFullyDrawn = false;        mFragments.dispatchPause();        mCalled = false;        onPause();        mResumed = false;        if (!mCalled && getApplicationInfo().targetSdkVersion                >= android.os.Build.VERSION_CODES.GINGERBREAD) {            throw new SuperNotCalledException(                    "Activity " + mComponent.toShortString() +                    " did not call through to super.onPause()");        }        mResumed = false;    }

果然有这个方法,并且 onPause();的生命周期方法也在里面。

不知道,你们明白了么? 欢迎老司机指教!

原创粉丝点击