Android系统启动-->应用启动-->界面的展示(三)

界面的展示部分:------->界面的加载(Activity、Window、View之间的关系)

我们知道在Instrumentation.java中有个newActivity(),通过反射创建了MainActivity对象,此时MainActivity对象并没有去调用其生命周期 的方法onCrteate( ),而是activity.attach(.....),

ok ,但这里我们先去看看我们熟悉的代码;

Activity中的生命周期方法onCreate(...)中调用了setContentView,如下


1

2

3

4

5

@Override

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    this.setContentView(R.layout.xxxx);

}

我们看一下setContentView(..........)这个方法的源码:


1

2

3

4

5

6

7

8

9

public void setContentView(int layoutResID) {

    getWindow().setContentView(layoutResID);

}

public void setContentView(View view) {

    getWindow().setContentView(view);

}

public void setContentView(View view, ViewGroup.LayoutParams params) {

    getWindow().setContentView(view, params);

}

我用红色标记了,他们都在做一个动作---getWindow(),即往获得Window上设置布局(或view),那这个Window在什么时候创建的?

我们看一下activity.attach(.....)中的源码:


1

2

3

4

5

6

final void attach(.......) {

    ...

    //创建一个Window对象

    mWindow = PolicyManager.makeNewWindow(this);

    ....

}

我们发现Window是个抽象类,那么这里它创建的是Window的哪一个子类?我们继续一步一步看源码:

PolicyManager.java中


1

2

3

4

5

6

public final class PolicyManager {

    private static final IPolicy sPolicy;

    public static Window makeNewWindow(Context context) {

        return sPolicy.makeNewWindow(context);

    }

}

接口IPolicy的实现类Policy.java


1

2

3

public PhoneWindow makeNewWindow(Context context) {

   return new PhoneWindow(context);

}

我们知道了是创建了一个PhoneWindow.

--------------------------------------------

现在我们重新回到MainActivity对象刚被new出来时,调用了attach(...)方法,其实是创建了一个PhoneWindow对象,

然后再去调用onCreate()方法,去设置布局我们从上面的源码我们看到,

其实setContentView()目的就是为了调用PhoneWindow的setContentView(...),看一下源码:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

public class PhoneWindow extends Window implements MenuBuilder.Callback {

    private DecorView mDecor;

    private ViewGroup mContentParent;

    private LayoutInflater mLayoutInflater;

    

    //DecorView其实就是Window中View的RootView

    private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {

        

    }

    

    @Override

    public void setContentView(int layoutResID) {

        if (mContentParent == null) {

            //没看懂,可以理解为让mDecor和mContentParent产生了关系

            //其实就是把View放在RootView上

            installDecor();

        else {

            mContentParent.removeAllViews();

        }

        mLayoutInflater.inflate(layoutResID, mContentParent);

        final Callback cb = getCallback();

        if (cb != null) {

            cb.onContentChanged();

        }

    }

    private void installDecor() {

        if (mDecor == null) {

            mDecor = generateDecor();

            mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);

            mDecor.setIsRootNamespace(true);

        }

        if (mContentParent == null) {

            mContentParent = generateLayout(mDecor);

            .....

            ....

        }

    }

}

到此结合上面的XML图 我们明白了界面是如何展现出的.

时间: 2024-12-28 21:45:20

Android系统启动-->应用启动-->界面的展示(三)的相关文章

Android系统启动-->应用启动-->界面的展示(一)

参考资料: 1,老罗的Android之旅http://blog.csdn.net/luoshengyang/article/details/6689748 2,Android核心分析http://www.linuxidc.com/Linux/2011-04/33966.htm Android系统的启动: 我们想来一张系统架构图: 一,上面用Git下载编译过程略掉,直接看最后我们Build 的产物. Build 的产物中最重要的是三个镜像文件,位于 /out/target/product/<pro

Android系统启动--&gt;应用启动--&gt;界面的展示(二)

在一个Lancher里面我们点击一个快捷键图表,Android系统做了什么? 我们先看Lancher.java中的源码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public final class Launcher extends Activity{     //onCick事件     public void onClick(View v) {         Object tag = v.getTa

Android仿iOS启动界面

第一部 -------------------------------------------------------------------------------- [问题] 由于Activity只能到onResume时,才能展示到前台,所以,如果为MainActivity设置背景的话,无论onCreate-onResume速度多快,都会出现短暂的带title的空页,这是我们不想要的. [方法] 只需在AndroidManifest.xml为你的<application>加上theme属性

App启动界面效果设计

转载请标明出处:http://blog.csdn.net/u012637501/article/details/45746617 每个Android应用启动之后都会出现一个Splash启动界面,大多数的Splash界面都是会等待一定时间,然后切换到下一个界面.但如果app启动时间过长,可使用启动界面让用户耐心等待这段枯燥的时间.Splash界面一般用于显示产品的LOGO.产品名称.版本信息等,也可以完成对系统状况的检测,如网络是否连通.电源是否充足.检测新版本等,也可以预先加载相关数据.启动界面

Android 跨进程启动Activity黑屏(白屏)的三种解决方案

原文链接:http://www.cnblogs.com/feidu/p/8057012.html 当Android跨进程启动Activity时,过程界面很黑屏(白屏)短暂时间(几百毫秒?).当然从桌面Lunacher启动一个App时也会出现相同情况,那是因为App冷启动也属于跨进程启动Activity.为什么没会出现这种情况呢?真正元凶就是Android创建进程需要准备很多资源,它是一个耗时的操作. 黑屏(白屏)原因 当A进程启动B进程中的一个Activity时,Android系统会先有zygo

Android基础之——startActivityForResult启动界面并返回数据,上传头像

在android应用的开发过程中,经常会出现启动一个界面后填写部分内容后带着数据返回启动前的界面,最典型的应用就是登录过程.在很多应用程序的模块中,都有"我的"这个模块,在未登录状态下点击其中的某一项,就会弹出登录界面,登录完成后回到我的界面,会显示一些登录后的数据,这个功能的实现就要用到startActivityForResult. 下面通过一个小demo来说明一下startActivityForResult的使用,以及在实际开发中的一些应用. demo的效果图如下: 主界面布局:

Android系统启动流程(一)解析init进程启动过程

前言 作为"Android框架层"这个大系列中的第一个系列,我们首先要了解的是Android系统启动流程,在这个流程中会涉及到很多重要的知识点,这个系列我们就来一一讲解它们,这一篇我们就来学习init进程. 1.init简介 init进程是Android系统中用户空间的第一个进程,作为第一个进程,它被赋予了很多极其重要的工作职责,比如创建zygote(孵化器)和属性服务等.init进程是由多个源文件共同组成的,这些文件位于源码目录system/core/init.本文将基于Androi

Android中Activity启动模式详解,可以控制程序按home键后进来还会调用一个自己不喜欢的界面

其实这是很简单的一个问题.但是这还是要对android中activity的启动模式有相当的理解才行,当点击home键的时候,懂Android的人都知道,他会把当前activity放到后退栈中, 栈(Stack)又称堆栈,它是一种运算受限的线性表,其限制是仅允许在表的一端进行插入和删除运算.人们把此端称为栈顶,栈顶的第一个元素被称为栈顶元素,相对地,把另一端称为栈底.向一个栈插入新元素又称为进栈或入栈,它是把该元素放到栈顶元素的上面,使之成为新的栈顶元素:从一个栈删除元素又称为出栈或退栈,它是把栈

Android 设置启动界面

启动界面的意义是为了让后台处理耗时的复杂工作,当工作处理完成后,即可进入主界面.相比让用户等待布局加载完成,使用一张图片作为启动背景,会带来更好的体验. 首先,需要建立一个简单的布局: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:lay