按照doc的介绍,标准的Activity.OnCreate()的实现通常是如下形式:
//首先根据某个XML布局设置界面
SetContentView(R.layout.XYZ);
//以下是得到上述layout:XYZ对应的XML中间定义一些控件的引用,使用Activity.findViewById(),比如
Button buttonTest = this.findViewById(R.id.button1);这些代码可能很平凡,但是因为这两天初次接触Android,我总觉得这里有一点蹊跷。
首先XML中的定义的button怎么就转换成java中Button对象了呢?
其次,倘若这些XML中定义的控件,比如button1是全局的,那么为什么findViewById()是隶属于当前的Activity对象成员方法而不是全局静态方法呢?后来我猜测,也许SetContentView(R.layout.XYZ)实际上是根据某个XYZ.XML中的内容建立一系列的控件对象,比如button1,那么此后就可以在该Activity里调用findViewById得到刚才建立的对象的句柄了。
以上猜测根据如下3个试验事实:
1.如果不SetContentView直接findViewById,那么会出现找不到资源的错误。可见SetContentView在某种意义上做了把XML中控件实例化的工作。
2.如果两个Activity用一个layout初始化,例如都执行SetContentView(R.layout.XYZ),然后分别用findViewById得到两个Activity中的button1的一个实例对象的引用,那么你会发现这两个引用并不指向同一个实例对象。(我用一个global的Button引用测试过)也就是说这两组同样的界面中的控件是两组独立的实例对象。
综上,我猜测Activity代码和XML布局协同工作的机制如下:
setContentView实际上是一个对象创建器和设置器。它根据某个资源ID指定的layout建立一系列对象并初始化他们的属性,此时这些对象的引用需要通过findViewById获得。当执行findViewById时,当前Activity查看自己是不是已经建立了对应该ID的对象,如果还没有建立则会出现资源找不到的错误。换句话说一个layout.XML实际上是一个用来创建对象组的模板,setContentView则根据这样的模板建立一组java控件对象,从而实现一个界面,进而可以用findViewById得到这个已建立界面上各个控件的句柄。这也就是XML和java联合编程的机制之一。:) 以上拙见,恳请各位androider,尤其是看过setContentView和findViewById源码的达人指教。

解决方案 »

  1.   

    这样猜测不如直接看android源码
      

  2.   

    嗯,理解的很深刻,一个xml就是承载一个布局(不仅仅是activity的布局)其次,每个activity对象都是不同的,所以引用的layout只针对当前activity,你重新启动一个同样的activity,他们也不一样,布局里面的控件的一些事件以及属性也可以不一样。最后,xml展示的东西全部可以用java代码通过android的api实现,xml只是简化工作并且使得可视化编辑布局更简单方便。祝你android旅途愉快