從Android app說起

版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:http://www.lxweimin.com/p/76f94c6452c0
先拋幾個問題
1:什么是Activity,它的作用是什么,我們一個android app看到的界面真的是Activity嗎,如果不是,那是什么。
2:我們經常看到的Context,到處都是Context,服務都是通過它獲取的,它和Activity是什么關系。
3:看到的一些文章和帖子總是會說一個Activity會對應一個PhoneWindow,那什么又是PhoneWindow,Activity和PhoneWindow的關系又是什么。
4:我們在自定義的Activity,比如MainActivity的setContentView中設置了xml,最后就是我們看到的視圖,那么它和PhoneWindow和Activity又有什么關系。
5:有View和ViewGroup我們可以理解,但是有時候又會看到一個ViewRootImpl和DecorView。它們又是什么關系,和Activity又是什么關系。
6:Activity,Context,Application,DecorView,PhoneWindow,ActivityThread,以及ActivityManagerService,WindowsManagerService它們是如何構建一個簡單的helloworld android應用的。Application和Activity是誰先創建的,android應用中為什么我們又不用繼承Application寫一個MyApplication類。而如果寫了,它又有什么用。

先說一個場景,當我們點擊手機桌面第一次運行app的時候,Activity是如何啟動的。這個過程要說清楚其實還是比較復雜的,本篇中我們先跳躍式的從main函數開始運行說起。main函數在ActivityThread類中,如下:

創建Activity或者說創建View


public static void main(String[] args) {
       Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
       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());

       // 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.prepareMainLooper();

       ActivityThread thread = new ActivityThread();
       thread.attach(false);

       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);
       Looper.loop();

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

main函數中創建了Looper(關于Looper和Handler和Message在后續講)和ActivityThread,并且調用attach函數和ActivityManagerService關聯起來,為什么需要和ActivityManagerService關聯,因為我們知道Activity何時創建,管理都是ActivityManagerService管理的,所以就需要告訴ActivityManagerService我現在已經運行了main函數,以后有什么需要任務你就需要告訴我,而ActivityManagerService是怎么和應用通信呢,這就需要注意到attach中的這段代碼

private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
}

mgr.attachApplication(mAppThread),mgr是ActivityManagerService的client代理mAppThread是一個Binder對象。

final ApplicationThread mAppThread = new ApplicationThread();

private class ApplicationThread extends ApplicationThreadNative {
// we use token to identify this activity without having to send the
        // activity itself back to the activity manager. (matters more with ipc)
        @Override
        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                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();
            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
}

現在我們知道了,ActivityManagerService持有應用的mAppThread對象,通過mAppThread服務端可以告應用進行啟動Activity和其它的一些操作,比方說調用scheduleLaunchActivity啟動Activity。ActivityThread中有一個H類,它繼承Handler,ActivityManagerService調用應用的操作最終通過H類發送消息,從Binder線程轉換到應用進程的主線程進程完成。

private class H extends Handler {
        public static final int LAUNCH_ACTIVITY         = 100;
}

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);
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
}

handleLaunchActivity中有一個performLaunchActivity調用,它會創建Activity(也就是new一個Activity),我們常常在Activity的onCreate函數中做一些初始化操作,到時我們好像很少寫Activity的構造函數,比如我們的MainActivity,我們其實也是可以寫它的構造函數,并且可也在里面完成一些操作,只是很少這樣做罷了。至此我們終于知道了Activity的創建了。

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
        mSomeActivitiesChanged = true;

        if (r.profilerInfo != null) {
            mProfiler.setProfiler(r.profilerInfo);
            mProfiler.startProfiling();
        }

        // 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.initialize();

        Activity a = performLaunchActivity(r, customIntent);
}

performLaunchActivity比較長,我們截取部分關鍵代碼分析。part1:通過mInstrumentation的newActivity調用new出來我們的Activity,part2:創建了Activity之后會創建應用的運行Application上下文,然后調用關鍵的attach函數

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//part1,通過mInstrumentation的newActivity調用new出來我們的Activity
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);
            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);
            }
        }
//part2,創建了Activity之后會創建應用的運行Application上下文,然后調用關鍵的attach函數
try {
            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 appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (r.overrideConfig != null) {
                    config.updateFrom(r.overrideConfig);
                }
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }
                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);

//part3,創建了Activity和attach之后,就調用到了我們熟悉的Activity的OnCreate
                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
        }
}

創建了Activity之后,在part2中會順帶著獲取到Application的對象,代表著我們應用的Application上下文,如果沒有,就會創建。packageInfo是一個LoadedApk對象

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }
Application app = null;
        try {
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        }

if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);//會調用Application的onCreate函數
            } catch (Exception e) {
            }
        }

至此我們明白了Application的創建和它的onCreate函數的調用過程。回調part2中的Activity的attach函數中來,它有一個參數就是Application。

final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window) {
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);

        mWindow = new PhoneWindow(this, window);
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        .
        .  
}

終于看到PhoneWindow了,它就是在Activity的attach的時候創建出來的,這注意兩行關鍵代碼mWindow.setWindowControllerCallback(this)和mWindow.setCallback(this),因為Activity繼承了Window的Callback,所以可以將Activity作為PhoneWindow的回調設置進去,后面PhoneWindow接收到的消息和一些其它操作都是通過這個回調告訴Activity。
part3,創建了Activity和attach之后,就調用到了我們熟悉的Activity的OnCreate

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

final void performCreate(Bundle icicle) {
        restoreHasCurrentPermissionRequest(icicle);
        onCreate(icicle);//onCreate中比如MainActivity繼承Activity,就調用到了MainActivity的onCreate函數
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }

至此終于見到我們熟悉的Activity的onCreate和setContentView(R.layout.activity_main)函數了。setContentView在Activity中如下

public void setContentView(@LayoutRes int layoutResID) {
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
    }

getWindow()返回的是mWindow,就是在上面attach中創建的PhoneWindow,那么PhoneWindow的setContentView又做了什么呢。我們xml布局的視圖又是如何了呢。

public void setContentView(int layoutResID) {
        // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
        // decor, when theme attributes and the like are crystalized. Do not check the feature
        // before this happens.
        if (mContentParent == null) {
            installDecor();
        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            mContentParent.removeAllViews();
        }

        if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
                    getContext());
            transitionTo(newScene);
        } else {
            mLayoutInflater.inflate(layoutResID, mContentParent);
        }
    }

private void installDecor() {
mForceDecorInstall = false;
        if (mDecor == null) {
            mDecor = generateDecor(-1);
        } 
        if (mContentParent == null) {
                    mContentParent = generateLayout(mDecor);
        }
}

protected DecorView generateDecor(int featureId) {
        return new DecorView(context, featureId, this, getAttributes());
    }

到這里我們終于見到DecorView了,DecorView它是什么東西呢,它是繼承FrameLayout的布局,也就是這里我們終于見到了View,現在也明白了Activity的頂布局是DecorView了,我們的xml布局中的View只是DecorView的Content布局內容。

public class DecorView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {

但到目前為止我們僅僅只見到過Activity的創建和它OnCreate函數的運行,也知道了我們的xml視圖實例化之后加入到了DecorView中,這樣就顯示了視圖,如何接收onTouchEvent事件了嗎,當然不是。這才是一部分,或者稱之為View視圖已經準備好了,已經創建了,剩下就是如何顯示它們了。

顯示Activity或者說顯示View

回到開始的handleLaunchActivity,第一部分創建Activity或者說創建View也即運行完performLaunchActivity函數之后,來到了handleResumeActivity函數,如下:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
  }
}

final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        if (!checkAndUpdateLifecycleSeq(seq, r, "resumeActivity")) {
            return;
        }
        r = performResumeActivity(token, clearHide, reason);

        if (r != null) {
            final Activity a = r.activity;
              .
              .
            if (r.window == null && !a.mFinished && willBeVisible) {
                r.window = r.activity.getWindow();
                View decor = r.window.getDecorView();
                decor.setVisibility(View.INVISIBLE);
                ViewManager wm = a.getWindowManager();
                WindowManager.LayoutParams l = r.window.getAttributes();
                a.mDecor = decor;
                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                
                if (a.mVisibleFromClient && !a.mWindowAdded) {
                    a.mWindowAdded = true;
                    wm.addView(decor, l);
                }
}

其中的performResumeActivity會最終運行到Activity的Resume函數。但是這個時候其實我們的View是沒有顯示的,那Activity都Resume了View還沒有顯示,那是什么時候顯示呢,往下看注意這段代碼wm.addView(decor, l);decor是上文中的DecorView對象,wm是什么呢,ViewManager wm = a.getWindowManager()

public WindowManager getWindowManager() {
        return mWindowManager;
    }

那mWindowManager是什么實例呢,它又是在什么地方創建或者賦值的,Activity的attach中有一行mWindowManager = mWindow.getWindowManager(),也就是說mWindowManager是獲取的PhoneWindow的對象。繼續往下跟Window類中有一個setWindowManager函數

public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
            boolean hardwareAccelerated) {
        mAppToken = appToken;
        mAppName = appName;
        mHardwareAccelerated = hardwareAccelerated
                || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);
        if (wm == null) {
            wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
        }
        mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
    }

PhoneWindow繼承Window,注意attach中有一段

mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);

也就是說mWindowManager是我們的mContext.getSystemService(Context.WINDOW_SERVICE)獲取到的WINDOW_SERVICE調用的createLocalWindowManager創建的WindowManagerImpl對象

public final class WindowManagerImpl implements WindowManager {
    //注意這個WindowManagerGlobal,它是一個單例對象,就是說一個進程只有一個實例
    private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
    public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
           return new WindowManagerImpl(mContext, parentWindow);
    }
}

mContext為Context對象,Context是一個抽象類,它的實現類是ContextImpl,查看ContextImpl的getSystemService函數,最終調用到了SystemServiceRegistry的getSystemService,而getSystemService返回的是它的HashMap SYSTEM_SERVICE_FETCHERS中保存的注冊的服務,一下就是我們常用到的ActivityManager和WindowManager

@Override
    public Object getSystemService(String name) {
        return SystemServiceRegistry.getSystemService(this, name);
    }

final class SystemServiceRegistry {
    private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES =
            new HashMap<Class<?>, String>();
    private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
            new HashMap<String, ServiceFetcher<?>>();
    private static int sServiceCacheSize;

    // Not instantiable.
    private SystemServiceRegistry() { }

    static {
        registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
                new CachedServiceFetcher<ActivityManager>() {
            @Override
            public ActivityManager createService(ContextImpl ctx) {
                return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
            }});
        registerService(Context.WINDOW_SERVICE, WindowManager.class,
                new CachedServiceFetcher<WindowManager>() {
            @Override
            public WindowManager createService(ContextImpl ctx) {
                return new WindowManagerImpl(ctx);
            }});
}

回到handleResumeActivity中的wm.addView(decor, l);,也就是調用到了WindowManagerImpl的addView

@Override
    public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        applyDefaultToken(params);
        mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
    }

最終調用到了WindowManagerGlobal中的addView,它里面又做了什么呢

public final class WindowManagerGlobal {
        private final ArrayList<View> mViews = new ArrayList<View>();
        private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
        public void addView(View view, ViewGroup.LayoutParams params,
                    Display display, Window parentWindow) {
                ViewRootImpl root;
                View panelParentView = null;

                synchronized (mLock) {
                    int index = findViewLocked(view, false);
                    root = new ViewRootImpl(view.getContext(), display);
                    view.setLayoutParams(wparams);

                    mViews.add(view);
                    mRoots.add(root);
                    mParams.add(wparams);
                }

                // do this last because it fires off messages to start doing things
                try {
                    root.setView(view, wparams, panelParentView);
                } catch (RuntimeException e) {
                }
         }
}

這里我們終于見到了ViewRootImpl。但是,什么,做了這么多,就是看到new了一個ViewRootImpl對象,然后將View和new的ViewRootImpl對象分別add到mViews和mRoots列表中,說好的顯示View呢,怎么接收Event等呢。add就行了嗎?這個就要從ViewRootImpl的setView說起了,說說ViewRootImpl了。

public final class ViewRootImpl implements ViewParent,
        View.AttachInfo.Callbacks, ThreadedRenderer.HardwareDrawCallbacks {
public ViewRootImpl(Context context, Display display) {
        mContext = context;
        //代表WindowManagerService的WindowSession
        mWindowSession = WindowManagerGlobal.getWindowSession();
        mDisplay = display;
        mBasePackageName = context.getBasePackageName();
        mThread = Thread.currentThread();
        mWinFrame = new Rect();
        //代表WindowManagerService和ViewRootImpl通信的mWindow,W對象
        mWindow = new W(this);
        mFirst = true; // true for the first time the view is added
        mAdded = false;
        //代表View和ViewRootImpl關聯的對象AttachInfo
        mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this);
        mFallbackEventHandler = new PhoneFallbackEventHandler(context);
        //我們常常說的編舞者對象Choreographer,控制UI刷新的,怎么做的1s內刷新60HZ的
        mChoreographer = Choreographer.getInstance();
        mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
        loadSystemProperties();
    }
}

ViewRootImpl的構造函數中的幾個關鍵對象都作了注釋 //代表WindowManagerService的WindowSession//代表WindowManagerService和ViewRootImpl通信的mWindow,W對象//代表View和ViewRootImpl關聯的對象AttachInfo//我們常常說的編舞者對象Choreographer,控制UI刷新的,怎么做的1s內刷新60HZ的。
上文說的要從ViewRootImpl的setView說起,setView怎么說呢,代碼比較長,截取關鍵部分

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
        synchronized (this) {
            if (mView == null) {
                mView = view;

                mAttachInfo.mDisplayState = mDisplay.getState();
                mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);

                // If the application owns the surface, don't enable hardware acceleration
                if (mSurfaceHolder == null) {
                    enableHardwareAcceleration(attrs);//硬件加速初始化部分
                }
// Schedule the first layout -before- adding to the window
                // manager, to make sure we do the relayout before receiving
                // any other events from the system.
                requestLayout();
                if ((mWindowAttributes.inputFeatures
                        & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
                    mInputChannel = new InputChannel();
                }
                mForceDecorViewVisibility = (mWindowAttributes.privateFlags
                        & PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0;
                try {
                    mOrigWindowType = mWindowAttributes.type;
                    mAttachInfo.mRecomputeGlobalAttributes = true;
                    collectViewAttributes();
                    //mWindowSession添加窗口顯示,一個應用只分配一個sWindowSession
                    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                            getHostVisibility(), mDisplay.getDisplayId(),
                            mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                            mAttachInfo.mOutsets, mInputChannel);
                } catch (RemoteException e) {
                }
              //mInputChannel,輸入通道,WindowInputEventReceiver,輸入事件接收相關代碼
              if (mInputChannel != null) {
                    if (mInputQueueCallback != null) {
                        mInputQueue = new InputQueue();
                        mInputQueueCallback.onInputQueueCreated(mInputQueue);
                    }
                    mInputEventReceiver = new WindowInputEventReceiver(mInputChannel,
                            Looper.myLooper());
                }
}

setView中的enableHardwareAcceleration(attrs)是關于硬件加速的,設計到View的
Draw問題,mWindowSession的addToDisplay是將視圖和窗口關聯的過程。mInputChannel輸入通道,WindowInputEventReceiver接收輸入事件,有了這些一個app的完整的顯示,UI更新,接收事件等終于準備好了,剩下的就是點擊屏幕,事件如何傳遞到Activity和View的問題,View如何將內容顯示出來,并且不斷的進行UI更新,這個就是Choreographer和Draw的問題,而怎么Draw就涉及到硬件加速Draw和softDraw,本篇就先到這,下篇再講。
這里我們總結下ActivityThread接收到ActivityManagerService通過Binder調用,創建Activity的過程,這些過程是平時做應用開發會有所涉及的。

1:ActivityThread的mAppThread成員變量調用scheduleLaunchActivity成員函數準備啟動Activity,發送LAUNCH_ACTIVITY轉換給ActivityThread的H類對象mH處理(轉換到主線程處理)。
2:mH對象接收到LAUNCH_ACTIVITY消息之后handleMessage調用handleRelaunchActivity成員函數,參數為ActivityClientRecord對象,表示記錄Activity的一些Client端信息,比如包名,組件名稱等等。
3:handleLaunchActivity函數中調用performLaunchActivity,執行啟動Activity。
   3.1:performLaunchActivity函數調用mInstrumentation new出需要啟動的Activity,比如MainActivity
        3.1.1:new出Activity之后,通過調用LoadedApk的makeApplication,創建應用的Application對象,同時創建Activity自己的Context
              3.1.2:這一切準備好之后,調用Activity的attach函數。
                     3.1.2.1:attach中主要創建了PhoneWindow對象,作為Activity對應的Window對象。
              3.1.3:Activity的attach運行完成之后通過mInstrumentation調用Activity的OnCreate,調用到我們熟悉的OnCreate函數
                     3.1.3.1:OnCreate·函數中,調用setContentView。這時會new出Activity窗口的根布局DecorView同時將我們自己的xml布局實例化成View,并添加到DecorView根布局中。
   3.2:handleResumeActivity函數運行完成之后執行handleResumeActivity,在handleResumeActivity函數中將DecorView加入到WindowManager中,
       在add DecorView的過程中創建了ViewRootImpl對象。ViewRootImpl對象完成UI Draw,消息接收等,細節后續篇章講解。
4:進入Looper消息循環,等等消息輸入
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,923評論 6 535
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,740評論 3 420
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,856評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,175評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,931評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,321評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,383評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,533評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,082評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,891評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,067評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,618評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,319評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,732評論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,987評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,794評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,076評論 2 375