Android View系统分析之三Activity的启动与显示

前言

Android View系统分析之从setContentView说开来(一)与Android View系统分析之二View与ViewGroup中我们已经简单介绍了一个Activity的UI内容与视图树的组成关系,即View与ViewGroup组成了Activity的可视化视图树,然后将该视图树添加到Activity中的DecorView的content区域,这样整个Activity的UI就填充完成了。那么一个进程和Activity又是如何启动?Activity的UI内容又是如何显示在屏幕上的呢?今天我们就来简单的梳理一下这个过程,大牛就不要往下看了!

Activity的启动过程

我们知道,在Android系统启动时,第一个启动起来的进程就是zygote进程,然后由zygote启动SystemServer,再然后就是启动例如ActivityManagerService、WindowManagerService等系统核心服务,这些服务承载着整个Android系统与客户端程序交互的重担。zygote除了启动系统服务与进程之外,普通的用户进程也由zygote进程fork而来,当一个应用进程启动起来后,就会加载用户在AndroidManifest.xml中配置的默认加载的Activity。此时加载的入口是ActivityThread.main(String[] args)方法,这个方法就是类似于C语言中的main方法一样,是整个应用程序的入口。

在ActivityThread.main(String[] args)这个方法中,主要的功能就是创建Application和创建Activity,并且调用Activity的一些生命周期函数,例如onCreate、onResume等。下面我们就从ActivityThread.main(String[] args)这个入口开始学习吧。

    public static final void main(String[] args) {
        SamplingProfilerIntegration.start();

        Process.setArgV0("");

        // 1、创建UI线程的Looper
        Looper.prepareMainLooper();
        if (sMainThreadHandler == null) {
            sMainThreadHandler = new Handler();
        }
        // 2、创建ActivityThread对象,但它并不是线程感觉是封装了UI线程消息循环与操作Activity生命周期的工具类
        ActivityThread thread = new ActivityThread();
        // 3、调用ActivityThread的attach方法,这是核心方法,Application、Activity的创建入口就在这里
        thread.attach(false);

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        // 4、启动UI线程消息循环
        Looper.loop();

        if (Process.supportsProcesses()) {
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }

        thread.detach();
        String name = (thread.mInitialApplication != null)
            ? thread.mInitialApplication.getPackageName()
            : "";
        Slog.i(TAG, "Main thread of " + name + " is now exiting");
    }


    // UI线程与Application关联
    private final void attach(boolean system) {
        sThreadLocal.set(this);
        mSystemThread = system;
        // 不是系统进程
        if (!system) {
            ViewRoot.addFirstDrawHandler(new Runnable() {
                public void run() {
                    ensureJitEnabled();
                }
            });
            android.ddm.DdmHandleAppName.setAppName("");
            RuntimeInit.setApplicationObject(mAppActivityManagerNativeThread.asBinder());
            // 5、获取ActivityManagerService实例
            IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                // 6、注意这里,将mAppThread与Application进行管理
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
            }
        } else {
            // 代码省略
        }
        // 代码省略
    }
可以看到,在ActivityThread.main中主要的功能就是创建了UI线程消息循环,并且启动了消息循环。最重要的是创建了ActivityThread,并调用了attach方法。在attach方法中又调用了ActivityManagerService中的attachApplication(mAppThread)方法,这个才是我们的重点。mAppThread是ApplicationThread类型,它也不是一个Thread,而是一个Binder,负责与远程的ActivityManagerService进行交互。在了解attachApplication之前,我们先来了解一下ApplicationThread与ActivityThread的关联。代码如下 : 

public final class ActivityThread {

// 定义mAppThread与mH
final ApplicationThread mAppThread = new ApplicationThread();
    final Looper mLooper = Looper.myLooper();
    final H mH = new H();



    // if the thread hasn't started yet, we don't have the handler, so just
    // save the messages until we're ready.
    private final void queueOrSendMessage(int what, Object obj) {
        queueOrSendMessage(what, obj, 0, 0);
    }

    private final void queueOrSendMessage(int what, Object obj, int arg1) {
        queueOrSendMessage(what, obj, arg1, 0);
    }

    private final 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来发消息, 处理也在H类中的handleMessage函数中
            mH.sendMessage(msg);
        }
    }


    /// AppcationThread 内部类,负责与ActivityManagerService交互
    private final class ApplicationThread extends ApplicationThreadNative {
        private static final String HEAP_COLUMN = "%17s %8s %8s %8s %8s";
        private static final String ONE_COUNT_COLUMN = "%17s %8d";
        private static final String TWO_COUNT_COLUMNS = "%17s %8d %17s %8d";
        private static final String TWO_COUNT_COLUMNS_DB = "%20s %8d %20s %8d";
        private static final String DB_INFO_FORMAT = "  %8d %8d %14d  %s";

        // Formatting for checkin service - update version if row format changes
        private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1;

        // 向UI线程发一个resume activity的消息
        public final void scheduleResumeActivity(IBinder token, boolean isForward) {
            queueOrSendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
        }

        // we use token to identify this activity without having to send the
        // activity itself back to the activity manager. (matters more with ipc)
        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Bundle state, List pendingResults,
                List pendingNewIntents, boolean notResumed, boolean isForward) {
            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.activityInfo = info;
            r.state = state;

            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;

            r.startsNotResumed = notResumed;
            r.isForward = isForward;

            // 向UI线程发一个H.LAUNCH_ACTIVITY的消息
            queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
        }

        // 省略代码

    } // end ApplicationThread



    // H内部类, ApplicationThread通过H类型的对象向UI线程投递消息
    private final class H extends Handler {
        public static final int LAUNCH_ACTIVITY         = 100;
        public static final int PAUSE_ACTIVITY          = 101;
        public static final int PAUSE_ACTIVITY_FINISHING= 102;
        // 其他code省略
        String codeToString(int code) {
            if (DEBUG_MESSAGES) {
                switch (code) {
                    case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
                    case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
                    case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
                    // 代码省略
                }
            }
            return "(unknown)";
        }
        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + msg.what);
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;

                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo);
                    // 加载Activity
                    handleLaunchActivity(r, null);
                } break;
                // activity pause
                case PAUSE_ACTIVITY:
                    handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
                    maybeSnapshot();
                    break;
                // 代码省略              
            }
            if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + msg.what);
        }
    
    } // end H

} // end ActivityThread
ApplicationThread与ActivityManagerService进行交互,然后通过H类的对象mH来发送消息,并且在H类的handleMessage函数中进行处理,然后 handleMessage根据消息的类型调用ActivityThread中对应的方法,比如handleResumeActivity来使Activity变得可见等。因为H的消息队列就是主线程的消息队列,因此这些过程都在UI线程中处理。

好的,我们现在继续关注ActivityManagerService中的attachApplication( mAppThread )。

    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            // 1、转到了attachApplicationLocked
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }


    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {

        // 代码省略
        if (localLOGV) Slog.v(
            TAG, "New app record " + app
            + " thread=" + thread.asBinder() + " pid=" + pid);
        try {
            // 2、ApplicationThread绑定Application
            thread.bindApplication(processName, app.instrumentationInfo != null
                    ? app.instrumentationInfo : app.info, providers,
                    app.instrumentationClass, app.instrumentationProfileFile,
                    app.instrumentationArguments, app.instrumentationWatcher, testMode, 
                    isRestrictedBackupMode || !normalMode,
                    mConfiguration, getCommonServicesLocked());
            updateLruProcessLocked(app, false, true);
            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
        } catch (Exception e) {
             return false;
        }

        // 代码省略

        // See if the top visible activity is waiting to run in this process...
        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
        if (hr != null && normalMode) {
            if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
                    && processName.equals(hr.processName)) {
                try {
                    // 3、正确启动Activity
                    if (mMainStack.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);
                    badApp = true;
                }
            } else {
                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
            }
        }

        return true;
    }
在省略了一大波代码之后,我们抓住了我们需要关心的点,即注释3处,这里才是真正启动activity的地方,这名字真是起得实诚。mMainStack的类型为ActivityStack,我们看看realStartActivityLocked吧。
    // 3中的ActivityStack中的realStartActivityLocked方法
     final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {

        // 代码省略
        try {
            // 代码省略
            // 设置app的dex文件的所在位置,指定包名
            mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
            // 1、注意这里调用了ApplicationThread中的scheduleLaunchActivity方法, 这个方法中会给UI线程发一个
            // LAUNCH_ACTIVITY消息,然后会调用ActivityThread的handleLaunchActivity(ActivityClientRecord r, Intent customIntent)函数
            // 在这个函数中会创建Activity,并且调用Activity的onCreate、onResume函数
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
                    System.identityHashCode(r),
                    r.info, r.icicle, results, newIntents, !andResume,
                    mService.isNextTransitionForward());
            
            // 代码省略            
        } catch (RemoteException e) {
            
        }
        // 代码省略
        
        return true;
    }
好嘛,绕来绕去,最终调用了ActiivityThread中的内部类的ApplicationThread中的scheduleLaunchActivity函数。该函数会发一个这个方法中会给UI线程发一个
H.LAUNCH_ACTIVITY消息,然后会调用ActivityThread的handleLaunchActivity(ActivityClientRecord r, Intent customIntent)函数,在这个函数中会创建将要启动的Activity,并且调用其生命周期函数onCreate、onResume。ApplicationThread中的scheduleLaunchActivity函数的代码在上文已经给出,下面我们看看ActivityThread的handleLaunchActivity(ActivityClientRecord r, Intent customIntent)函数。
// ActivityThread中的handleLaunchActivity
private final 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.
        unscheduleGcIdler();

        if (localLOGV) Slog.v(
            TAG, "Handling launch of " + r);
        // 1、创建并且加载Activity,调用其onCreate函数
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            Bundle oldState = r.state;
            // 2、调用Activity的onResume方法,使Activity变得可见
            handleResumeActivity(r.token, false, r.isForward);

        }
    }


     private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        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 activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            // 1、创建Activity
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            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 {
            // 2、创建Application
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
            if (localLOGV) Slog.v(
                    TAG, r + ": app=" + app
                    + ", appName=" + app.getPackageName()
                    + ", pkg=" + r.packageInfo.getPackageName()
                    + ", comp=" + r.intent.getComponent().toShortString()
                    + ", dir=" + r.packageInfo.getAppDir());

            if (activity != null) {
                // 构建Context
                ContextImpl appContext = new ContextImpl();
                appContext.init(r.packageInfo, r.token, this);
                appContext.setOuterContext(activity);
                // 获取Activity的title
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mConfiguration);
            
                    // 3、Activity与context, Application关联起来
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstance,
                        r.lastNonConfigurationChildInstances, config);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstance = null;
                r.lastNonConfigurationChildInstances = null;
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
                // 4、回调Activity的onCreate方法
                mInstrumentation.callActivityOnCreate(activity, r.state);
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                r.activity = activity;
                r.stopped = true;
                // 5、执行Activity的onStart方法
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
                // 代码省略
            }
            r.paused = true;

            mActivities.put(r.token, r);

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
      
        }

        return activity;
    }


    final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();

        // 1、最终调用Activity的onResume方法
        ActivityClientRecord r = performResumeActivity(token, clearHide);

        if (r != null) {
            final Activity a = r.activity;

            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 = ActivityManagerNative.getDefault().willActivityBeVisible(
                            a.getActivityToken());
                } catch (RemoteException e) {
                }
            }

            // 2、这里是重点,在这里使DecorView变得可见
            if (r.window == null && !a.mFinished && willBeVisible) {
                // 获取Window,即PhoneWindow类型
                r.window = r.activity.getWindow();
                // 3、获取Window的顶级视图,并且使它可见
                View decor = r.window.getDecorView();
                decor.setVisibility(View.INVISIBLE);
                // 4、获取WindowManager
                ViewManager wm = a.getWindowManager();
                // 5、构建LayoutParams参数
                WindowManager.LayoutParams l = r.window.getAttributes();
                a.mDecor = decor;
                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                if (a.mVisibleFromClient) {
                    a.mWindowAdded = true;
                    // 6、将DecorView添加到WindowManager中,最终的操作是通过WindowManagerService的addView来操作
                    wm.addView(decor, 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;
            }

            // 代码省略
    }


    // 
 public final ActivityClientRecord performResumeActivity(IBinder token,
            boolean clearHide) {
        ActivityClientRecord r = mActivities.get(token);
       
        if (r != null && !r.activity.mFinished) {
                try {
                // 代码省略
                // 执行onResume
                r.activity.performResume();

                r.paused = false;
                r.stopped = false;
                r.state = null;
            } catch (Exception e) {
   
            }
        }
        return r;
    }

如上述代码,在调用ActivityThread的handleLaunchActivity(ActivityClientRecord r, Intent customIntent)后会调用performLaunchActivity函数来创建Activity,并且将Activity与Application关联上,然后调用Activity的onCreate、onStart函数。再之后是调用handleResumeActivity函数,handleResumeActivity函数又调用performResumeActivity函数来回调Activity的onResume函数,之后将Activity的DecorView设置为可见,并且添加到WindowManager中,此时Activity也就显示在屏幕上了。时序图大致如下 :

Android View系统分析之三Activity的启动与显示_第1张图片

由此,我们可以得出,在Activity的onResume方法中,Activity的内容还是没有可见,执行完OnResume之后才会可见。那么Activity的DecorView又是如何通过WindowManager显示在屏幕上的呢?我们下篇文章再来学习吧~



你可能感兴趣的:(Android,View系统解析)