Android应用程序窗口View的创建过程.docx

上传人:b****4 文档编号:27119022 上传时间:2023-06-27 格式:DOCX 页数:21 大小:21.70KB
下载 相关 举报
Android应用程序窗口View的创建过程.docx_第1页
第1页 / 共21页
Android应用程序窗口View的创建过程.docx_第2页
第2页 / 共21页
Android应用程序窗口View的创建过程.docx_第3页
第3页 / 共21页
Android应用程序窗口View的创建过程.docx_第4页
第4页 / 共21页
Android应用程序窗口View的创建过程.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

Android应用程序窗口View的创建过程.docx

《Android应用程序窗口View的创建过程.docx》由会员分享,可在线阅读,更多相关《Android应用程序窗口View的创建过程.docx(21页珍藏版)》请在冰豆网上搜索。

Android应用程序窗口View的创建过程.docx

Android应用程序窗口View的创建过程

Android应用程序窗口View的创建过程

View类是Android中非常重要的一个类.view是应用程序界面的直观体现,我们看到的应用程序界面就可以看作是View(视图)组成的.

那么我们应用程序的界面是怎么创建的呢,也就是应用程序的View是什么时候创建的?

在android中与界面直接相关的就是Activity了.

我们平时在Activity的onCreate()函数中,通过调用它的setContentView()函数,将我们应用程序的界面资源设置进去.然后运行程序就可以看到我们布局文件里描述的界面了.

从我们调用setContentView()函数将界面资源设置进去,到运行完成界面完全显示出来,其中经过了很多过程.

这里我主要是通过源码来分析一下其中最终界面到底是什么样的View?

然后分析一下View的measure,layout,draw过程.

因为我们设置界面是setContentView()中设置的,所以就从该函数开始来分析.

分析点击android桌面app图标启动应用程序的过程一文中我们知道Activity的onCreate()函数最先被调用.第五十步

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

privateActivityperformLaunchActivity(ActivityClientRecordr,IntentcustomIntent){

....

Activityactivity=null;

try{

java.lang.ClassLoadercl=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(Exceptione){

....

}

try{

Applicationapp=r.packageInfo.makeApplication(false,mInstrumentation);

...

if(activity!

=null){

ContextappContext=createBaseContextForActivity(r,activity);

CharSequencetitle=r.activityInfo.loadLabel(appContext.getPackageManager());

Configurationconfig=newConfiguration(mCompatConfiguration);

...

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;

inttheme=r.activityInfo.getThemeResource();

if(theme!

=0){

activity.setTheme(theme);

}

activity.mCalled=false;

mInstrumentation.callActivityOnCreate(activity,r.state);

.....

}

这里首先创建Activity的实例,然后mInstrumentation.callActivityOnCreate(activity,r.state)该函数最终就会调用Activity的onCreate()函数.

好了,看setContentView()函数

第一步:

setContentView()

在frameworks/base/core/java/android/app/Activity.java中

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

publicvoidsetContentView(intlayoutResID){

getWindow().setContentView(layoutResID);

initActionBar();

}

publicvoidsetContentView(Viewview){

getWindow().setContentView(view);

initActionBar();

}

publicvoidsetContentView(Viewview,ViewGroup.LayoutParamsparams){

getWindow().setContentView(view,params);

initActionBar();

}

Activity中setContentView()函数有三个重载函数,一般用第一个比较多,这里就按第一个继续往下分析,其实它们最终实现都一样.

首先看getWindow()函数

第二步:

getWindow()

在frameworks/base/core/java/android/app/Activity.java中

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

publicWindowgetWindow(){

returnmWindow;

}

Activity的成员变量mWindow是Window类型,它是什么时候被赋值的呢?

这里还是到分析点击android桌面app图标启动应用程序的过程一文中第五十步看看

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

privateActivityperformLaunchActivity(ActivityClientRecordr,IntentcustomIntent){

....

Activityactivity=null;

try{

java.lang.ClassLoadercl=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(Exceptione){

...

}

try{

Applicationapp=r.packageInfo.makeApplication(false,mInstrumentation);

...

if(activity!

=null){

ContextappContext=createBaseContextForActivity(r,activity);

CharSequencetitle=r.activityInfo.loadLabel(appContext.getPackageManager());

Configurationconfig=newConfiguration(mCompatConfiguration);

...

activity.attach(appContext,this,getInstrumentation(),r.token,

r.ident,app,r.intent,r.activityInfo,title,r.parent,

r.embeddedID,r.lastNonConfigurationInstances,config);

....

}

这里创建Activity的实例后,就通过activity.attach()函数给activity内部变量赋值,所以进attach()函数里面看看

第三步:

attach()

在frameworks/base/core/java/android/app/Activity.java中

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

finalvoidattach(Contextcontext,ActivityThreadaThread,

Instrumentationinstr,IBindertoken,intident,

Applicationapplication,Intentintent,ActivityInfoinfo,

CharSequencetitle,Activityparent,Stringid,

NonConfigurationInstanceslastNonConfigurationInstances,

Configurationconfig){

...

mWindow=PolicyManager.makeNewWindow(this);//

....

}

mWindow=PolicyManager.makeNewWindow(this);这里就是给activity中mWindow赋值.那继续看PolicyManager.makeNewWindow(this)这个函数

第四步:

makeNewWindow()

在frameworks/base/core/Java/com/android/internal/policyPolicyManager.java中

 

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

//Thestaticmethodstospawnnewpolicy-specificobjects

publicstaticWindowmakeNewWindow(Contextcontext){

returnsPolicy.makeNewWindow(context);

}

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

publicfinalclassPolicyManager{

privatestaticfinalStringPOLICY_IMPL_CLASS_NAME=

"com.android.internal.policy.impl.Policy";

privatestaticfinalIPolicysPolicy;

static{

//Pullintheactualimplementationofthepolicyatrun-time

try{

ClasspolicyClass=Class.forName(POLICY_IMPL_CLASS_NAME);

sPolicy=(IPolicy)policyClass.newInstance();

}catch(ClassNotFoundExceptionex){

....

}

这里继续调用sPolicy.makeNewWindow(context);由上面代码可以知道这里的sPolicy其实是Policy类型

第五步:

makeNewWindow()

在frameworks/base/policy/src/com/android/internal/policy/impl/Policy.java中

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

publicclassPolicyimplementsIPolicy{

.

publicWindowmakeNewWindow(Contextcontext){

returnnewPhoneWindow(context);

}

这里直接newPhoneWindow(context)返回,可知PhoneWindow类是Window类的子类,进入PhoneWindow类看看

第六步:

PhoneWindow()

在frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java中

 

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

publicclassPhoneWindowextendsWindowimplementsMenuBuilder.Callback{

.

publicPhoneWindow(Contextcontext){

super(context);

mLayoutInflater=LayoutInflater.from(context);

}

来看一下PhoneWindow类的构造函数,首先是调用了其父类(Window)的构造函数,然后创建了一个LayoutInflater对象mLayoutInflater,这个对象根据它的名字大概可以知道它是渲染布局资源的

去Window类的构造函数看看

第七步:

Window()

在frameworks/base/core/java/android/view/Window.java中

 

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

publicWindow(Contextcontext){

mContext=context;

}

回到第二步中,这是我们知道getWindow()返回其实是一个PhoneWindow对象,即Activity的成员变量mWindow是PhoneWindow类型.

然后回到第一步中,那么接着其实是调用PhoneWindow.setContentView()了

 

第八步:

setContentView()

在frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java中

 

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

publicvoidsetContentView(intlayoutResID){

if(mContentParent==null){

installDecor();

}else{

mContentParent.removeAllViews();

}

mLayoutInflater.inflate(layoutResID,mContentParent);

finalCallbackcb=getCallback();

if(cb!

=null&&!

isDestroyed()){

cb.onContentChanged();

}

}

PhoneWindow的成员变量mContentParent是ViewGroup类型,第一次进来为null,所以调用installDecor()函数,那我们首先看看该函数

第九步:

installDecor()

在frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java中

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

privatevoidinstallDecor(){

if(mDecor==null){

mDecor=generateDecor();

mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);

...

}

if(mContentParent==null){

mContentParent=generateLayout(mDecor);

//SetupdecorpartofUItoignorefitsSystemWindowsifappropriate.

mDecor.makeOptionalFitsSystemWindows();

mTitleView=(TextView)findViewById(com.android.internal.R.id.title);

if(mTitleView!

=null){

mTitleView.setLayoutDirection(mDecor.getLayoutDirection());

if((getLocalFeatures()&(1<

=0){

ViewtitleContainer=findViewById(com.android.internal.R.id.title_container);

if(titleContainer!

=null){

titleContainer.setVisibility(View.GONE);

}else{

mTitleView.setVisibility(View.GONE);

}

if(mContentParentinstanceofFrameLayout){

((FrameLayout)mContentParent).setForeground(null);

}

}else{

mTitleView.setText(mTitle);

}

}else{

mActionBar=(ActionBarView)findViewById(com.android.internal.R.id.action_bar);

if(mActionBar!

=null){

mActionBar.setWindowCallback(getCallback());

if(mActionBar.getTitle()==null){

mActionBar.setWindowTitle(mTitle);

}

finalintlocalFeatures=getLocalFeatures();

if((localFeatures&(1<

=0){

mActionBar.initProgress();

}

if((localFeatures&(1<

=0){

mActionBar.initIndeterminateProgress();

}

booleansplitActionBar=false;

finalbooleansplitWhenNarrow=

(mUiOptions&ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW)!

=0;

if(splitWhenNarrow){

splitActionBar=getContext().getResources().getBoolean(

com.android.internal.R.bool.split_action_bar_is_narrow);

}else{

splitActionBar=getWindowStyle().getBoolean(

com.android.internal.R.styleable.Window_windowSplitActionBar,false);

}

finalActionBarContainersplitView=(ActionBarContainer)findViewById(

com.android.internal.R.id.split_action_bar);

if(splitView!

=null){

mActionBar.setSplitView(splitView);

mActionBar.setSplitActionBar(splitActionBar);

mActionBar.setSplitWhenNarrow(splitWhenNarrow);

finalActionBarContextViewcab=(ActionBarContextView)findViewById(

com.android.internal.R.id.action_context_bar);

cab.setSplitView(splitView);

cab.setSplitActionBar(splitActionBar);

cab.setSplitWhenNarrow(splitWhenNarrow);

}elseif(splitAionBar){

Log.e(TAG,"Requestedsplitact

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 面试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1