Android源码学习笔记:Context、ActivityThread和Activity的生命周期

请尊重原创,转载请注明出处 tianyl_Melodie 的博客,http://blog.csdn.net/tianyl_melodie/article/details/53424116


1、Context和它的子类


在Android中,也被称为上下文,运行环境,通过context可以拿到Android运行时的一些信息,所以我们今天先从Context开始看。通过看Context,我们可以发现它其实是一个抽象类,里面定义了一下我们经常使用的方法:

代码片段
public abstract AssetManager getAssets();
public abstract Resources getResources();
public abstract PackageManager getPackageManager();
public abstract ContentResolver getContentResolver();

既然context只是一个抽象类,定义了一些方法,并没有对应的实现,那么就需要通过它的子类才能知道对应的实现。在Android中,context的子类有非常多,如图:


看到这么多类可能一时半会有点晕,改从哪个类开始看起呢。既然这样,那就从我们用得最多的一个类,Activity开始看起吧。通过观察,我们可以看到,Activity是继承的ContextThemeWrapper,而ContextThemeWrapper又是继承ContextWrapper,然后ContextWrapper才是继承自Context的。其实上图已经清晰的展现出了Activity的父类结构。


那么是不是Context的实现方法都写在ContextWrapper这个类里面呢,我们打开ContextWrapper这个类看一下,可以发现,他所有的方法,都是通过调用一个对象来完成的,代码片段如下:

public AssetManager getAssets() {
  return mBase.getAssets();
}
@Override
public Resources getResources(){
  return mBase.getResources();
}
@Override
public PackageManager getPackageManager() {
  return mBase.getPackageManager();
}
@Override
public ContentResolver getContentResolver() {
  return mBase.getContentResolver();
}
而这个mBase对象,则是最开始通过 ContextWrapper的构造方法传进来的,也就是说 Context的实现类并不是 ContextWrapper,通过这个类的名字,我们也可以理解,它只是一个 Context的包装类。那么 Context的实现到底在哪呢? 通过名字,我们也可以看出来,ContextImpl就是 Context的实现类。


其实,在创建Activity之前,系统会通过ActivityManagerService这个类来初始化一些信息,这其中就包括对ActivityThread中Context的初始化,在这个时候,如果ContextImpl的对象还没有创建,那么就会创建出对应的ContextImpl对象,并作为成员变量进行保存起来。这样,以后在用到Context进行创建对象的时候,就会将这个对象传入。

就是通过这样,所以就变成了现在这样,ContextImpl实现Context的抽象方法,ContextWrapper和它的子类,通过持有ContextImpl的对象,调用对应的方法。对应的UML图如下:


通过查看ContextImpl,我们可以发现,虽说它是Context的实现类,但并非所有的实现方法都写在这个类中。比如有些就是通过PackageInfo这个对象获取的返回值,比如我们经常用到的一个方法:getApplicationContext()。

@Override
public Context getApplicationContext() {
   return (mPackageInfo != null) ?
        PackageInfo.getApplication() : mMainThread.getApplication();
}

通过查看PackageInfo,我们可以发现它其实就是一个LoadedApk类。关于LoadedApk这个类以后学习的时候再细说,我们可以先认为Context的方法都是在ContextImpl这个类中进行实现的即可,还是回归正题。


2、ActivityThread


刚才我们已经知道了, Context的实现类是 ContextImpl,而 Activity作为 ContextWrapper的子类,其实是通过持有 ContextImpl的对象,来实现 Context的抽象方法。那么 Activity 是在什么时候拿到这个 ContextImpl对象的呢。
在前一篇,Handler学习的时候,我们已经知道了, Looper和MessageQueue 的创建,是在 ActivityThread中完成的,其实在创建 Looper和MessageQueue时,还做了其他的一些事情。

首先,在启动一个应用程序的时候,首先是会在Android的ActivityManagerService中,调用ActivityThread的main方法。之前我们学习了ActivityThread的main方法中,创建Looper的过程,现在来看ActivityThread的main方法中的另外一行代码。

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());
        Process.setArgV0("<pre-initialized>");
	    //构建主线程中的MessageQueue和Looper对象
        Looper.prepareMainLooper();
        //构建ActivityThread对象
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        AsyncTask.init();
        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
之前我们看的是main中对Looper对象的构建,在构建完Looper对象之后,会执行这两行代码:

ActivityThread thread = new ActivityThread();
thread.attach(false);
首先是创建一个ActivityThread对象,这时就会初始化 ActivityThread类中的一些成员。然后调用 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());
            IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                // Ignore
            }
        } else {
            // Don't set application object here -- if the system crashes,
            // we can't display an alert, we just want to die die die.
            android.ddm.DdmHandleAppName.setAppName("system_process",
                                                    UserHandle.myUserId());
            try {
                mInstrumentation = new Instrumentation();
                ContextImpl context = new ContextImpl();
                context.init(getSystemContext().mPackageInfo, null, this);
                Application app = Instrumentation.newApplication(Application.class, context);
                mAllApplications.add(app);
                mInitialApplication = app;
                app.onCreate();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
            }
        }
        // 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;
                            
                            queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);
                        }
                    }
                }
            }
            @Override
            public void onLowMemory() {
            }
            @Override
            public void onTrimMemory(int level) {
            }
        });
    }
这里的代码有点多,我们可以简单的看一下,在main方法,中,我们通过thread.attach(false)调用到了这里,此时的判断,"!system"为true,执行了这样一行代码:

IActivityManager mgr = ActivityManagerNative.getDefault();
这里,通过这个方法,拿到的其实是一个ActivityManagerService远程代理对象,我们将通过它和 ActivityManagerService进行通信,这里就不深入研究了,待到以后学习 ActivityManagerService再看。

mgr.attachApplication(mAppThread);
在拿到这个代理对象之后,将mAppThread传了进去。我们可以简单理解,在应用程序启动的时候,首先会通过 ActivityManagerService调用到 ActivityThread的main(),然后在main()中,创建了一个 ActivityThread对象,并初始化了它的成员变量,然后拿到了 ActivityManagerService的远程代理对象,将成员变量 mAppThread传了进去。看到这里, ActivityManagerService和 ActivityThread通信的关联,已经基本完成了。


3、ApplicationThread


mAppThread是ApplicationThread这个类的实例,在创建ActivityThread时,就创建了这个对象,之后又将它传入了ActivityManagerService的远程代理对象,可以理解ActivityManagerService和ActivityThread是通过ApplicationThread进行通信的。我们仔细查看这个类,发现它是继承自ApplicationThreadNative。而ApplicationThreadNative类实现了IApplicationThread这个接口,我们查看这个接口对象:

代码片段:
void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
            int configChanges) throws RemoteException;
void scheduleStopActivity(IBinder token, boolean showWindow,
            int configChanges) throws RemoteException;
void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;
void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException;
void scheduleResumeActivity(IBinder token, int procState, boolean isForward)
            throws RemoteException;
void scheduleCreateService(IBinder token, ServiceInfo info,
            CompatibilityInfo compatInfo, int processState) throws RemoteException;
void scheduleBindService(IBinder token,
            Intent intent, boolean rebind, int processState) throws RemoteException;
void scheduleUnbindService(IBinder token,
            Intent intent) throws RemoteException;
上面代码是 IApplicationThread接口中定义的一些,方法,我们可以发现它其实都是一下对activity生命周期的管理。而 ApplicationThreadNative这个类则实现了这些管理生命周期的方法,通过在 onTransact方法中,调用对应的方法,代码如下:
@Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        case SCHEDULE_PAUSE_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IApplicationThread.descriptor);
            IBinder b = data.readStrongBinder();
            boolean finished = data.readInt() != 0;
            boolean userLeaving = data.readInt() != 0;
            int configChanges = data.readInt();
            schedulePauseActivity(b, finished, userLeaving, configChanges);
            return true;
        }
        case SCHEDULE_STOP_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IApplicationThread.descriptor);
            IBinder b = data.readStrongBinder();
            boolean show = data.readInt() != 0;
            int configChanges = data.readInt();
            scheduleStopActivity(b, show, configChanges);
            return true;
        }
......
当然,它也只是一个抽象类,具体的实现方法是实现是它的子类中,比如: ApplicationThreadProxy和ApplicationThread ApplicationThreadProxy看名字可以猜测它是一个代理类,其实他 的实现方式是通过 IBinder进行的,这块以后在学习IBinder的时候再仔细学习 ,当然它并不是我们今天的重点,我们回到今天的重点 ApplicationThread。

刚才在 ApplicationThreadNative这个类中,我们已经看到了,它是通过一个 onTransact方法调用不同的方法进行不同的逻辑处理的,比如说我们想启动一个Activity,那么它会执行里面的这样的逻辑:
 case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IApplicationThread.descriptor);
            Intent intent = Intent.CREATOR.createFromParcel(data);
            IBinder b = data.readStrongBinder();
            int ident = data.readInt();
            ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
            Configuration curConfig = Configuration.CREATOR.createFromParcel(data);
            CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
            int procState = data.readInt();
            Bundle state = data.readBundle();
            List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
            List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
            boolean notResumed = data.readInt() != 0;
            boolean isForward = data.readInt() != 0;
            String profileName = data.readString();
            ParcelFileDescriptor profileFd = data.readInt() != 0
                    ? ParcelFileDescriptor.CREATOR.createFromParcel(data) : null;
            boolean autoStopProfiler = data.readInt() != 0;
            scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, procState, state,
                    ri, pi, notResumed, isForward, profileName, profileFd, autoStopProfiler);
            return true;
        }
在上面代码中,我们可以看到这样一行:
 scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, procState, state,
                    ri, pi, notResumed, isForward, profileName, profileFd, autoStopProfiler);
刚才我们已经说了, ApplicationThreadNative只是一个抽象类, ApplicationThread才是实现类,那么现在,通过这行代码,就会回调到 ApplicationThread中,我们看看在 ApplicationThread中是如何实现启动Activity的流程的。

下面就是启动Activity的逻辑:

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
                int procState, Bundle state, List<ResultInfo> pendingResults,
                List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
                String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
            updateProcessState(procState, false);
            ActivityClientRecord r = new ActivityClientRecord();
            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;
            r.startsNotResumed = notResumed;
            r.isForward = isForward;
            r.profileFile = profileName;
            r.profileFd = profileFd;
            r.autoStopProfiler = autoStopProfiler;
            updatePendingConfiguration(curConfig);
            queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
        }

代码虽然有点多,但是逻辑还是很清晰的。可以看出这里它做了两件事。
①创建一个ActivityClientRecord的对象作为参数。
②将传入传入queueOrSendMessage方法。
我们查看 queueOrSendMessage 这个方法,可以跟踪到这里:
private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
        synchronized (this) {
            if (DEBUG_MESSAGES) Slog.v(
                TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
                + ": " + arg1 + " / " + obj);
            Message msg = Message.obtain();
            msg.what = what;
            msg.obj = obj;
            msg.arg1 = arg1;
            msg.arg2 = arg2;
            mH.sendMessage(msg);
        }
    }
这里创建了一个Message对象,并且将传入的一些参数保存到了Message中。然后通过一个mH进行发送。

那么mH又是什么呢?‘
其实它是 ActivityThread 一个成员对象, 在创建ActivityThread的时候,通过这行代码创建了它。
final H mH = new H();
再看一下H类的定义,我们可以发现,它其实就是一个Handler对象:
private class H extends Handler
看到这里,想必大家也就明白了。

①在应用启动的时候,首先会创建一个进程process,然后创建ActivityThread这个对象。
②根据我们之前学习的Handler,可以知道,在 ActivityThread的main方法中,会创建一个 Looper和MessageQueue对象。
③在创建完 Looper和MessageQueue对象后,还会创建一个 ApplicationThread对象,并且拿到 ActivityManagerService的远程代理对象,实现和 ActivityManagerService的通信。
④创建一个H类的实例,而这个H类实际上是一个Handler对象。
⑤调用 Looper.loop()方法,开始轮询消息队列。
然后当要启动一个Activity的时候,根据刚才查看的ApplicationThread的逻辑,最后会通过mH.sendMessage(msg)这行代码,回调到这个消息队列中来。

4、Activity的启动过程


看了那么多,终于要揭开我们Activity启动的神秘面纱了,是不是有点小激动呢。
我们继续看在类H中,是如何处理消息,启动Activity。
首先看处理消息的 handleMessage()方法。
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");
                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
......
首先,它会拿到ActivityClientRecord这个对象,之前我们在scheduleLaunchActivity方法中,已经大概知道它里面保存的是一些关于Activity的信息。
然后再调用了handleLaunchActivity这个方法。
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        unscheduleGcIdler();
        if (r.profileFd != null) {
            mProfiler.setProfiler(r.profileFile, r.profileFd);
            mProfiler.startProfiling();
            mProfiler.autoStopProfiler = r.autoStopProfiler;
        }
        handleConfigurationChanged(null, null);
        if (localLOGV) Slog.v(
            TAG, "Handling launch of " + r);
        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) {
                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 {
            try {
                ActivityManagerNative.getDefault()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null);
            } catch (RemoteException ex) {
                // Ignore
            }
        }
    }
虽然这个方法有点多,但其实它里面的逻辑并不复杂。
首先,它会做一些判断,然后通过这样一行代码,拿到需要启动的Activity
Activity a = performLaunchActivity(r, customIntent);
然后,再是调用Activity的Resume方法:

handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);
最后则是调用 Activity的 OnPause 方法:
mInstrumentation.callActivityOnPause(r.activity);  

看到这里,聪明的朋友可能已经会猜到了,既然调用了 Resume方法和 OnPause方法,那么OnCreate肯定是调用了,既然这里没有,那么肯定就写在 performLaunchActivity这个方法里面。

接下来,我们就仔细看看在 performLaunchActivity中,是如何调用 OnCreate方法的。
performLaunchActivity这个方法非常长,这里我就不全部列出来,而是列出里面重要的地方了:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
	......
        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);
            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 {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            if (activity != null) {
                Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config);
                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }
                activity.mCalled = false;
                mInstrumentation.callActivityOnCreate(activity, r.state);
               
			   ......
            }
            r.paused = true;
            mActivities.put(r.token, r);
        } catch 
			......
        return activity;
    }
首先,系统会拿到Activity的类加载器,然后通过newInstance方法创建出Activity对象:

java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
然后,系统会拿到对应的Application对象:

Application app = r.packageInfo.makeApplication(false, mInstrumentation);
最后,系统才会调用 Activity的OnCreate方法:

mInstrumentation.callActivityOnCreate(activity, r.state);
看到这里,我们也基本清楚了一个应用,从进程启动,到Activity创建的过程。


5、总结


①在应用启动的时候,首先会创建一个进程process,然后创建ActivityThread这个对象。
②根据我们之前学习的Handler,可以知道,在 ActivityThread的main方法中,会创建一个 Looper和MessageQueue对象。
③在创建完 Looper和MessageQueue对象后,还会创建一个 ApplicationThread对象,并且拿到 ActivityManagerService的远程代理对象,实现和 ActivityManagerService的通信。
④创建一个H类的实例,而这个H类实际上是一个Handler对象。
⑤调用 Looper.loop()方法,开始轮询消息队列。
⑥然后当要启动一个Activity的时候,通过ActivityManagerService通知 ApplicationThreadNative ,调用到 onTransact方法。
⑦在 onTransact中进行判断,调用到对应的实现类 ApplicationThread的 scheduleLaunchActivity方法。
⑧在scheduleLaunchActivity方法中,先创建对应的参数信息ActivityClientRecord,然后通过queueOrSendMessage发送消息。
⑨Handler收到消息,在 handleMessage中进行处理,在 handleMessage中拿到对应的 ActivityClientRecord进行,然后作为参数传入,并调用方法 handleLaunchActivity方法。
⑩在 handleLaunchActivity中通过 mInstrumentation 调用对应的生命周期。

到此,我们对于Context的实现类,、ActivityThread的创建和Activity的生命周期的基本分析也算是告一段落了,当然,对于Activity生命周期的分析并没有完全结束。后面我们将继续 学习。










  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值