activity生命周期分析

对于Android开发者来说activity的生命周期是再熟悉不过的东西了,对于下面这张图也是再熟悉不过了;
activity生命周期分析_第1张图片
activity.png

从activity的创建到销毁,会走onCreate()、onStart()、onResume()、onPause()、onStop()、onDestory()等生命周期,对于开发者来说充分理解activity的生命周期可以在适当的回调方法中进行业务逻辑处理;不过这要说的并不是onCreate()、onStart()、onResume()、onPause()、onStop()、onDestory()等生命周期,而是从点击一个app图标这些生命周期是如何走的,界面是如何展示给用户的;说到这些,肯定会提到ActivityThread类。
ActivityThread:它是一个管理应用程序进程中主线程的执行、调度和执行活动,根据活动管理器的请求在其上广播和其他操作。
在用户点击app Launcher 图标时,会去调用ActivityThread类中的main方法,这也是应用程序的主入口;

public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
        SamplingProfilerIntegration.start();

        CloseGuard.setEnabled(false);

        Environment.initForCurrentUser();

        EventLogger.setReporter(new EventLoggingReporter());

        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);

        Process.setArgV0("");
 //实例化准备一个Looper
        Looper.prepareMainLooper();
//实例化一个ActivityThread对象
        ActivityThread thread = new ActivityThread();
//调用attach方法
        thread.attach(false);
//实例化handler对象
        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);
//调用loop()进行消息轮询
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

在main方法中会实例化一个ActivityThread对象,在ActivityThread类中有一个mH成员变量,其实就是一个handler,在handler的handlerMessage回调中发现activity生命周期的方法在那里被调用,其实activity的生命周期都是通过handler消息来管理的,根据handler消息的类型会去调用handleLaunchActivity方法;


activity生命周期分析_第2张图片
handleLaunchActivity.png

从流程图中知道会在handleLaunchActivity方法中调用performLaunchActivity方法,并返回一个Activity实例;

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        ......
        // Make sure we are running with the most recent config.
//配置参数
        handleConfigurationChanged(null, null);
        if (localLOGV) Slog.v(
            TAG, "Handling launch of " + r);
        // Initialize before creating the activity
//初始化WindowManagerGlobal
        WindowManagerGlobal.initialize();

        Activity a = performLaunchActivity(r, customIntent);
        ......
    }

跟着流程图和源码看看activity在performLaunchActivity方法中是如何创建的,

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
        ActivityInfo aInfo = r.activityInfo;
//获取apk包信息
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }
//通过ComponentName和intent也可以启动一个activity
//Intent intent=new Intent();
//ComponentName componentName=ComponentName.createRelative(MainActivity.this,SecondActivity.class);
// intent.setComponent(componentName);
//startActivity(intent);
        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }
        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }
//为activity创建一个上下文
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
//通过反射实例化一个activity对象
            java.lang.ClassLoader cl = appContext.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);
            }
        }
        try {
           ......
            if (activity != null) {
                .......
                appContext.setOuterContext(activity);
//调用activity中的attach方法,这个方法比较重要,这里暂时不说
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);
               ......
                activity.mCalled = false;
//调用Instrumentation中的callActivityOnCreate方法,
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ......
                r.activity = activity;
                r.stopped = true;
                if (!r.activity.mFinished) {
//判断当前activity是否finish,如果没有finish就会调用activity中的performStart方法
                    activity.performStart();
                    r.stopped = false;
                }
               ......
//r.token就是一个IBinder对象,将IBinder为key,ActivityClientRecord对象为value缓存在map集合中
                mActivities.put(r.token, r);
              ......
        return activity;
    }

通过调用Instrumentation中的newActivity就实例化好了一个activity,看下activity在里面是如何被实例化的;

public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
//获取到应用程序的包名
        String pkg = intent != null && intent.getComponent() != null
                ? intent.getComponent().getPackageName() : null;
        return getFactory(pkg).instantiateActivity(cl, className, intent);
    }
public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
            @Nullable Intent intent)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return (Activity) cl.loadClass(className).newInstance();
    }

通过传入的ClassLoader和应用程序包名实例化一个activity,这样子通过反射就实例化好一个activity,就会去调用attch方法,在attch方法中会绑定activity的上下文,初始化PhoneWindow、获取当前线程、setWindowManager等各种操作,而在Instrumentation的callActivityOnCreate方法中会根据实例化好的activity去调用它里面的performCreate方法;

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

在activity的performCreate方法中就会看到调用了onCreate方法;

final void performCreate(Bundle icicle) {
        restoreHasCurrentPermissionRequest(icicle);
        onCreate(icicle);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }

调用完onCreate方法后,接着会根据实例化好的activity,并且当前activity没有finish,就会去调用自己的performStart()方法;

final void performStart() {
        ......
//通过传入当前的activity在Instrumentation的callActivityOnStart方法中调用activity自己的onStart方法
        mInstrumentation.callActivityOnStart(this);
        ......
        mActivityTransitionState.enterReady(this);
    }
public void callActivityOnStart(Activity activity) {
        activity.onStart();
    }

这样子activity的onCreate、onStart方法就走了;接着看onResume,先去看handleResumeActivity

final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
//根据activity创建时缓存的IBinder获取对应的ActivityClientRecord对象
        ActivityClientRecord r = mActivities.get(token);
//检查和更新生命周期
        if (!checkAndUpdateLifecycleSeq(seq, r, "resumeActivity")) {
            return;
        }

        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
        mSomeActivitiesChanged = true;

        // TODO Push resumeArgs into the activity for consideration
//需要注意performResumeActivity方法的调用
        r = performResumeActivity(token, clearHide, reason);
        if (r != null) {
//这里的ActivityClientRecord对象不为null
//获取缓存中的activity实例
            final Activity a = r.activity;
            if (localLOGV) Slog.v(
                TAG, "Resume " + r + " started activity: " +
                a.mStartedActivity + ", hideForNow: " + r.hideForNow
                + ", finished: " + a.mFinished);

            final int forwardBit = isForward ?
                    WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;

            // If the window hasn't yet been added to the window manager,
            // and this guy didn't finish itself or start another activity,
            // then go ahead and add the window.
            boolean willBeVisible = !a.mStartedActivity;
            if (!willBeVisible) {
                try {
                    willBeVisible = ActivityManager.getService().willActivityBeVisible(
                            a.getActivityToken());
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
            if (r.window == null && !a.mFinished && willBeVisible) {
//获取activity attch初始化时的window对象
                r.window = r.activity.getWindow();
//获取window对象中的DecorView
                View decor = r.window.getDecorView();
//设置DecorView为不可见
                decor.setVisibility(View.INVISIBLE);
//获取activity中对应的ViewManager
                ViewManager wm = a.getWindowManager();
                WindowManager.LayoutParams l = r.window.getAttributes();
                a.mDecor = decor;
//给window设置参数
                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                if (r.mPreserveWindow) {
                    a.mWindowAdded = true;
                    r.mPreserveWindow = false;
                    // Normally the ViewRoot sets up callbacks with the Activity
                    // in addView->ViewRootImpl#setView. If we are instead reusing
                    // the decor view we have to notify the view root that the
                    // callbacks may have changed.
                    ViewRootImpl impl = decor.getViewRootImpl();
                    if (impl != null) {
                        impl.notifyChildRebuilt();
                    }
                }
                if (a.mVisibleFromClient) {
                    if (!a.mWindowAdded) {
                        a.mWindowAdded = true;
//将设置好的DecorView通过ViewManager添加到布局中
                        wm.addView(decor, l);
                    } else {
                        // The activity will get a callback for this {@link LayoutParams} change
                        // earlier. However, at that time the decor will not be set (this is set
                        // in this method), so no action will be taken. This call ensures the
                        // callback occurs with the decor set.
                        a.onWindowAttributesChanged(l);
                    }
                }

            // If the window has already been added, but during resume
            // we started another activity, then don't yet make the
            // window visible.
            } else if (!willBeVisible) {
                if (localLOGV) Slog.v(
                    TAG, "Launch " + r + " mStartedActivity set");
                r.hideForNow = true;
            }

            // Get rid of anything left hanging around.
            cleanUpPendingRemoveWindows(r, false /* force */);

            // The window is now visible if it has been added, we are not
            // simply finishing, and we are not starting another activity.
            if (!r.activity.mFinished && willBeVisible
                    && r.activity.mDecor != null && !r.hideForNow) {
                if (r.newConfig != null) {
                    performConfigurationChangedForActivity(r, r.newConfig);
                    if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
                            + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig);
                    r.newConfig = null;
                }
                if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
                        + isForward);
                WindowManager.LayoutParams l = r.window.getAttributes();
                if ((l.softInputMode
                        & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
                        != forwardBit) {
                    l.softInputMode = (l.softInputMode
                            & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
                            | forwardBit;
                    if (r.activity.mVisibleFromClient) {
                        ViewManager wm = a.getWindowManager();
                        View decor = r.window.getDecorView();
//通过ViewManager更新布局的摆放
                        wm.updateViewLayout(decor, l);
                    }
                }

                r.activity.mVisibleFromServer = true;
                mNumVisibleActivities++;
                if (r.activity.mVisibleFromClient) {
                    r.activity.makeVisible();
                }
            }

            if (!r.onlyLocalRequest) {
                r.nextIdle = mNewActivities;
                mNewActivities = r;
                if (localLOGV) Slog.v(
                    TAG, "Scheduling idle handler for " + r);
                Looper.myQueue().addIdleHandler(new Idler());
            }
            r.onlyLocalRequest = false;

            // Tell the activity manager we have resumed.
            if (reallyResume) {
                try {
                    ActivityManager.getService().activityResumed(token);
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            }

        } else {
            // If an exception was thrown when trying to resume, then
            // just end this activity.
            try {
                ActivityManager.getService()
                    .finishActivity(token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }

一进入handleResumeActivity方法就去调用了performResumeActivity方法,

public final ActivityClientRecord performResumeActivity(IBinder token,
            boolean clearHide, String reason) {
//通过缓存的IBinder获取ActivityClientRecord对象
        ActivityClientRecord r = mActivities.get(token);
        if (localLOGV) Slog.v(TAG, "Performing resume of " + r
                + " finished=" + r.activity.mFinished);
        if (r != null && !r.activity.mFinished) {
//这里的ActivityClientRecord 对象不为空且当前activity也没有finish掉
            ......
//调用performResume
                r.activity.performResume();
            ......
        }
        return r;
    }
final void performResume() {
//这里也会先调用performRestart方法,
        performRestart();
      ......
        mInstrumentation.callActivityOnResume(this);
       ......
    }

和onStart的流程一样,在performResume方法中还是通过Instrumentation中的callActivityOnResume方法利用传入的当前activity,去调用自己的onResume方法;

public void callActivityOnResume(Activity activity) {
        activity.mResumed = true;
        activity.onResume();
        
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i

不过不同的是,在调用onResume的同时会接着在handleResumeActivity方法中根据activity创建时缓存的对象获取Window、DecorView、ViewManager等实例,并进行参数设置,将设置好参数的view通过ViewManager添加到布局中,也是在onResume生命周中,将布局和view绘制渲染完毕,添加到布局中展示给用户;onResume走完就是onPause,在handlePauseActivity方法中和handleResumeActivity一样,也是根据缓存获取对应的实例对象,判断检查和更新生命周期,调用performPauseActivity方法;

private void handlePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport, int seq) {
        ActivityClientRecord r = mActivities.get(token);
        if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);
        if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
            return;
        }
        if (r != null) {
            //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
            if (userLeaving) {
                performUserLeavingActivity(r);
            }
            r.activity.mConfigChangeFlags |= configChanges;
//注意performPauseActivity的调用
            performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
            // Make sure any pending writes are now committed.
            if (r.isPreHoneycomb()) {
                QueuedWork.waitToFinish();
            }
            // Tell the activity manager we have paused.
            if (!dontReport) {
                try {
                    ActivityManager.getService().activityPaused(token);
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            }
            mSomeActivitiesChanged = true;
        }
    }

在performPauseActivity中利用重载调用的是多一个参数的performPauseActivity方法;

final Bundle performPauseActivity(IBinder token, boolean finished,
            boolean saveState, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
    }

这样就只能去看多一个参数的performPauseActivity方法逻辑了;

final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
            boolean saveState, String reason) {
//finished这个参数上面传入的是tr
        if (r.paused) {
//走到这里activity还没有finish
            if (r.activity.mFinished) {
                // If we are finishing, we won't call onResume() in certain cases.
                // So here we likewise don't want to call onPause() if the activity
                // isn't resumed.
                return null;
            }
            RuntimeException e = new RuntimeException(
                    "Performing pause of activity that is not resumed: "
                    + r.intent.getComponent().toShortString());
            Slog.e(TAG, e.getMessage(), e);
        }
        if (finished) {
//改变activity finish的状态 
            r.activity.mFinished = true;
        }

        // Next have the activity save its current state and managed dialogs...
        if (!r.activity.mFinished && saveState) {
            callCallActivityOnSaveInstanceState(r);
        }
//在该方法中会调用Instrumentation中的callActivityOnPause方法
        performPauseActivityIfNeeded(r, reason);

        // Notify any outstanding on paused listeners
//定义一个OnActivityPausedListener 集合
        ArrayList listeners;
        synchronized (mOnPauseListeners) {
//将当前onPause的activity中mOnPauseListeners中移除并将移除返回的数据赋值给listeners
            listeners = mOnPauseListeners.remove(r.activity);
        }
        int size = (listeners != null ? listeners.size() : 0);
        for (int i = 0; i < size; i++) {
//遍历listeners集合
            listeners.get(i).onPaused(r.activity);
        }

        return !r.activity.mFinished && saveState ? r.state : null;
    }

剩下的就会onCreate的调用走向差不多了;

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

handleStopActivity和handlePauseActivity差不多,这里就不写了,自己可以在ActivityThread类中慢慢看,就接着看handleDestroyActivity方法;handleDestroyActivity在调用onDestory的逻辑走向和之前那些一样的,这里就只说下当activity调用onDestory后页面、页面上的view、activity实例的处理;

private void handleDestroyActivity(IBinder token, boolean finishing,
            int configChanges, boolean getNonConfigInstance) {
//一样调用performDestroyActivity 在performDestroyActivity方法中会调用Instrumentation的
//callActivityOnDestroy方法,接着调用activity中的onDestory方法
        ActivityClientRecord r = performDestroyActivity(token, finishing,
                configChanges, getNonConfigInstance);
        if (r != null) {
//移除activity中的window对象,在cleanUpPendingRemoveWindows方法中,会将window移除调用将window对象置为null
            cleanUpPendingRemoveWindows(r, finishing);
//获取对应的windowManager实例
            WindowManager wm = r.activity.getWindowManager();
//获取DecorView
            View v = r.activity.mDecor;
            if (v != null) {
                if (r.activity.mVisibleFromServer) {
                    mNumVisibleActivities--;
                }
                IBinder wtoken = v.getWindowToken();
                if (r.activity.mWindowAdded) {
                    if (r.mPreserveWindow) {
                        // Hold off on removing this until the new activity's
                        // window is being added.
                        r.mPendingRemoveWindow = r.window;
                        r.mPendingRemoveWindowManager = wm;
                        // We can only keep the part of the view hierarchy that we control,
                        // everything else must be removed, because it might not be able to
                        // behave properly when activity is relaunching.
//将window上的view清除掉
                        r.window.clearContentView();
                    } else {
//移除window上的view
                        wm.removeViewImmediate(v);
                    }
                }
                if (wtoken != null && r.mPendingRemoveWindow == null) {
                    WindowManagerGlobal.getInstance().closeAll(wtoken,
                            r.activity.getClass().getName(), "Activity");
                } else if (r.mPendingRemoveWindow != null) {
                    // We're preserving only one window, others should be closed so app views
                    // will be detached before the final tear down. It should be done now because
                    // some components (e.g. WebView) rely on detach callbacks to perform receiver
                    // unregister and other cleanup.
                    WindowManagerGlobal.getInstance().closeAllExceptView(token, v,
                            r.activity.getClass().getName(), "Activity");
                }
//移除完view后将DecorView置为null
                r.activity.mDecor = null;
            }
            if (r.mPendingRemoveWindow == null) {
                // If we are delaying the removal of the activity window, then
                // we can't clean up all windows here.  Note that we can't do
                // so later either, which means any windows that aren't closed
                // by the app will leak.  Well we try to warning them a lot
                // about leaking windows, because that is a bug, so if they are
                // using this recreate facility then they get to live with leaks.
                WindowManagerGlobal.getInstance().closeAll(token,
                        r.activity.getClass().getName(), "Activity");
            }

            // Mocked out contexts won't be participating in the normal
            // process lifecycle, but if we're running with a proper
            // ApplicationContext we need to have it tear down things
            // cleanly.
            Context c = r.activity.getBaseContext();
            if (c instanceof ContextImpl) {
                ((ContextImpl) c).scheduleFinalCleanup(
                        r.activity.getClass().getName(), "Activity");
            }
        }
        if (finishing) {
            try {
                ActivityManager.getService().activityDestroyed(token);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
        mSomeActivitiesChanged = true;
    }

通过上面知道activity调用onDestory后,只是将window上的view进行移除,并将DecorView置为null,并没有将当前的activity实例置为null,所以activity调用onDestory后,页面销毁了,但是activity实例一直在内存中,等待gc的回收,如果内存中的activity实例还被持有,就会造成内存泄露,这是开发中需要注意的。

总结:
1.activity的生命周期是通过handler消息来控制的;
2.activity的实例创建是通过反射来实现的;
3.在activity onResume生命周期后,才将布局view绘制添加到系统布局中并显示给用户;
4.在activity onDestory生命周期后,只是将window、window中的view,DecorView移除并置为null,并没有将activity实例置为null,activity实例仍然在内存中,如果在gc时还有持有该activity的引用就会造成内存泄露,也就是说activity onDestory后只是页面的销毁,并不代表当前activity实例的销毁。

你可能感兴趣的:(activity生命周期分析)