Android中activity從創(chuàng)建到顯示的基本介紹
前言
說道Android中的Activity,如果你做過iOS開發(fā)的話,Activity類似于iOS中的ViewController(視圖控制器)。在應用中能看到的東西都是放在活動中的?;顒邮前沧块_發(fā)比較重要的東西,是用戶交互和數據的入口。本篇博客要介紹的內容是活動的創(chuàng)建,活動的跳轉與值的透傳。
iOS中的ViewController也是有自己的生命周期的,了解Activity或者ViewController的生命周期是很有必要的,本文將詳細的給大家介紹關于Android中activity從創(chuàng)建到顯示的相關內容,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧。
activity是我們平常開發(fā)最常用的一個組件,我們有必要了解activity的創(chuàng)建以及顯示的過程,這些應該作為我們的儲備知識。
Activity的創(chuàng)建
Activity的創(chuàng)建以及初始化的過程是在ActivityThread#performLaunchActivity方法中,在這個方法中,有以下幾個關鍵點,
- 創(chuàng)建Activity
- Activity#attach
- Instrumentation#callActivityOnCreate
- Activity#performStart
- Instrumentation#callActivityOnPostCreate
這個地方能看到Activity生命周期的一小部分。我們需要對其中一些點進行學習,在這些點里面都有一些非常重要的操作。
創(chuàng)建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的創(chuàng)建對于我們后面的操作很重要。
Activity#onCreate
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);
postPerformCreate(activity);
}
在activity.performCreate中,會調用activity的onCreate方法,這個是我們平常開發(fā)中非常熟悉的,在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以及后續(xù)的處理。
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);
首先創(chuàng)建一個ViewRootImpl,然后setView。ViewRootImpl#setView方法代碼較長,我們能發(fā)現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)窗口對象(Window)創(chuàng)建指南
- 在當前Activity之上創(chuàng)建懸浮view之WindowManager懸浮窗效果
- Android開發(fā)中Activity創(chuàng)建跳轉及傳值的方法
- Android中Activity跳轉的創(chuàng)建步驟總結
- Android簡單創(chuàng)建一個Activity的方法
- Android基于OpenGL的GLSurfaceView創(chuàng)建一個Activity實現方法
- Android中為activity創(chuàng)建菜單
- Android創(chuàng)建一個Activity的方法分析
相關文章
SimpleCommand框架ImageLoader API詳解(三)
這篇文章主要為大家詳細介紹了SimpleCommand框架ImageLoader API,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10

