我是靠谱客的博主 自觉面包,最近开发中收集的这篇文章主要介绍app( activity) 启动流程,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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

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

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

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

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();的生命周期方法也在里面。

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

最后

以上就是自觉面包为你收集整理的app( activity) 启动流程的全部内容,希望文章能够帮你解决app( activity) 启动流程所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部