您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Android中activity從創建到顯示的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
activity是我們平常開發最常用的一個組件,我們有必要了解activity的創建以及顯示的過程,這些應該作為我們的儲備知識。
Activity的創建
Activity的創建以及初始化的過程是在ActivityThread#performLaunchActivity方法中,在這個方法中,有以下幾個關鍵點,
創建Activity
Activity#attach
Instrumentation#callActivityOnCreate
Activity#performStart
Instrumentation#callActivityOnPostCreate
這個地方能看到Activity生命周期的一小部分。我們需要對其中一些點進行學習,在這些點里面都有一些非常重要的操作。
創建Activity的過程就不說了,直接反射。我們重點說下attach方法,
Activity#attach
attach部分代碼如下
mWindow = new PhoneWindow(this, window); mWindow.setWindowControllerCallback(this); mWindow.setCallback(this); mWindow.setOnWindowDismissedCallback(this); mWindow.getLayoutInflater().setPrivateFactory(this);
在Activity的attach方法中,很關鍵的一點就是初始化Window,從這里就能看到,Window的實現類,是PhoneWindow。PhoneWindow的創建對于我們后面的操作很重要。
Activity#onCreate
public void callActivityOnCreate(Activity activity, Bundle icicle, PersistableBundle persistentState) { prePerformCreate(activity); activity.performCreate(icicle, persistentState); postPerformCreate(activity); }
在activity.performCreate中,會調用activity的onCreate方法,這個是我們平常開發中非常熟悉的,在onCreate中,我們調用setContentView去填充布局,并進行一些初始化操作
setContentView
到了我們相當熟悉的setContentView,在setContentView中,會調用PhoneWindow的setContentView方法。我們簡單看下PhoneWindow的setContentView
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); } mContentParent.requestApplyInsets(); final Callback cb = getCallback(); if (cb != null && !isDestroyed()) { cb.onContentChanged(); } mContentParentExplicitlySet = true; }
在PhoneWindoe的setContentView方法中,會進行初始化DecorView,并將我們設置的布局加載到contentparent中。installDecor的具體邏輯我們這里就不多說了。
resume過程
在ActivityThread#handleResumeActivity方法中,有兩個關鍵點。
performResumeActivity
Window#addView
performResumeActivity中會調用activity的performResume,performResume中會調用onResume,然后進入onresume聲明周期中
我們重點說下addView以及后續的處理。
addView
wm.addView(decor, l);
這里的wm是WindowManager,是在attach法法中,通過setWindowManager來實現初始化的,對應的實例為WindowManagerImpl的一個實例。那么,我們去看下WindoeManageImpl的addView方法,在這個方法中,直接調用WindowManagerGlobal的addView方法,我們關心的中點轉移了。其中最關鍵的diam是如下幾行。
root = new ViewRootImpl(view.getContext(), display); view.setLayoutParams(wparams); mViews.add(view); mRoots.add(root); mParams.add(wparams); root.setView(view, wparams, panelParentView);
首先創建一個ViewRootImpl,然后setView。ViewRootImpl#setView方法代碼較長,我們能發現requestLayout這個方法,進去看下。
@Override public void requestLayout() { if (!mHandlingLayoutInLayoutRequest) { checkThread(); mLayoutRequested = true; scheduleTraversals(); } }
在這里,進行了首次線程檢查。
void scheduleTraversals() { if (!mTraversalScheduled) { mTraversalScheduled = true; mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier(); mChoreographer.postCallback( Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null); if (!mUnbufferedInputDispatch) { scheduleConsumeBatchedInput(); } notifyRendererOfFramePending(); pokeDrawLockIfNeeded(); } }
Choreographer,post了一個Callback,這個callback是view刷新的核心所在。我們看下TraversalRunnable的run方法,
final class TraversalRunnable implements Runnable { @Override public void run() { doTraversal(); } }
void doTraversal() { if (mTraversalScheduled) { mTraversalScheduled = false; mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier); if (mProfile) { Debug.startMethodTracing("ViewAncestor"); } performTraversals(); if (mProfile) { Debug.stopMethodTracing(); mProfile = false; } } }
在doTraversal中,又會調用performTraversals方法,我們看下performTraversals方法是干啥的。這個方法非常非常的長,但是在這個方法中,有非常關鍵的performMeasure,performLayout,performDraw等方法,至此,進入的View的的三大過程,,三大過程之后,就顯示在我們面前了。
關于“Android中activity從創建到顯示的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。