WindowManager和Window添加View的区别(转)

WindowManager中有个添加View的函数:

public void addView(View view, ViewGroup.LayoutParams params)

Window中有个添加View的函数:

public void addContentView(View view, ViewGroup.LayoutParams params)

弄清楚这两个类和这两个函数的作用设计到Android整个Surface系统,这里不详述,只作说明,供自己记录。

事实上,这两个函数是Activity上显示View至关重要的控制函数,它们在框架层已经有了明确的分工。查看这两个函数的调用过程可以发现addView的调用是针对ViewRootImpl的,也就是它添加的View相当于最底层的PhoneWindow.DecorView;而addContentView最终指向了ViewGroup.addView(childView)。下面用实验进行验证:

activity_main.xml

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:gravity="center"
 6     android:orientation="vertical" >
 7
 8     <ImageView
 9         android:id="@+id/text1"
10         android:layout_width="match_parent"
11         android:layout_height="200dp"
12         android:background="#ff0088"
13         android:text="@string/hello_world" />
14
15 </LinearLayout>

MainActivity.java

 1 public class MainActivity extends Activity {
 2
 3     private ImageView mImageView;
 4
 5     @Override
 6     protected void onCreate(Bundle savedInstanceState) {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.activity_main);
 9         }
10 }

如果只有上述内容,这个Activity的效果图和View树如下:

 

View树和layout布局是相一致的。

现在我们使用addContentView()来添加新的内容:

 1 public class MainActivity extends Activity {
 2
 3     private ImageView mImageView;
 4
 5     @Override
 6     protected void onCreate(Bundle savedInstanceState) {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.activity_main);
 9
10         mImageView = (ImageView) this.findViewById(R.id.text1);
11         ImageView m = new ImageView(this);
12         m.setBackgroundColor(Color.BLUE);
13             getWindow().addContentView(m, new
14         ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,200));
15         }
16 }

此时它的效果图和View树如下:

 

我们发现,新添加的内容是和layout的根视图是平等的,这是这个使用这个函数必须要明白的,也就是说使用addContentView添加的内容等效于setContentView(R.layout.main_activity)。

现在我们使用addView()来添加新的内容:

 1 public class MainActivity extends Activity {
 2
 3     private ImageView mImageView;
 4
 5     @Override
 6     protected void onCreate(Bundle savedInstanceState) {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.activity_main);
 9
10         mImageView = (ImageView) this.findViewById(R.id.text1);
11         ImageView m = new ImageView(this);
12         m.setBackgroundColor(Color.BLUE);
13         // getWindow().addContentView(m, new
14         // ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,200));
15         WindowManager.LayoutParams wl = new WindowManager.LayoutParams();
16         wl.height = 200;
17         wl.width = WindowManager.LayoutParams.MATCH_PARENT;
18         getWindowManager().addView(m, wl);
19     }
20 }

此时它的效果图和View树如下:

而且Hierarchy View工具不能显示这个View树,原因就是因为addView添加的内容等同于所有视图的根视图DecorView:

如上,PhoneWindow$DecorView中这个DecorView是所有视图的根视图,而使用addView添加的内容等效于DecorView,明白这一点对于使用这个函数至关重要。

时间: 2024-10-28 14:43:30

WindowManager和Window添加View的区别(转)的相关文章

Android中Window添加View的底层原理

一,WIndow和windowManager Window是一个抽象类,它的具体实现是PhoneWindow,创建一个window很简单,只需要创建一个windowManager即可,window具体实现在windowManagerService中,windowManager和windowManagerService的交互是一个IPC的过程. 下面是用windowManager的例子: mFloatingButton = new Button(this); mFloatingButton.set

[BS-20] 导航控制器和视图控制器在添加控制器的区别

导航控制器和视图控制器在添加控制器的区别 1. 因导航控制器拥有导航栈,有一个普通视图控制器都没有的数组viewControllers,加入该数组中的视图控制器默认以push的方式进入导航栈.导航控制器有个[UINavigationController alloc] initWithRootViewController:rootVC]; 的初始化方法,调用该方法相当于把rootVC加入数组viewControllers的第一个位置,作为栈底部的rootVC是不会被pop出去的,与导航控制器共生死

debug debug Unable to add window android.view.View--permission denied for this window type

1 AlertDialog builder=new AlertDialog.Builder(context).setTitle("注意:") 2 .setIcon(R.drawable.dailog_icon) 3 .setMessage("MS0"+ReceiveNumber+"请求建立语音连接,是否同意?") 4 .setPositiveButton("同意", new DialogInterface.OnClickLis

Android进阶笔记08:Android 中Activity、Window和View之间的关系

1. Android 中Activity.Window和View之间的关系(比喻): Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图) LayoutInflater像剪刀,Xml配置像窗花图纸.  2. 详解:       Activity是Android应用程序的载体,允许用户在其上创建一个用户界面,并提供用户处理事件的API,如onKeyEvent, onTouchEvent等. 并维护应用程序的生命周期.Activity本身是个庞大的载体,

Activity Threa创建Window和View分析

http://blog.csdn.net/ljsbuct/article/details/7094580 1. 入口. 以前一直都说Activity的人口是onCreate方法.其实android上一个应用的入口,应该是ActivityThread.和普通的java类一样,入口是一个main方法. public static final void main(String[] args) {         SamplingProfilerIntegration.start();        …

Activity创建Window和View分析

一.Activity启动Activity由ActivityThread负责启动. ActivityThread的分析将在<ActivityThread分析>中,在此,只需要知道创建activity的入口在ActivityThread就行,不影响以下的分析.    ActivityThread.java    private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {   

window、view相关

View.Window以及Activity主要是用于显示并与用户交互window view activity surfaceView 三者间的关系: 在Activity中要设置View时,通常用的方法是:setContentView(id); 而实际在Activity类中用的是:getWindow().setContentView(id); 此即view是放到window上的,获得window的方法是:activity.this.getWindow(); Activity实际上是继承 Conte

Activity、Window、View之间的关系

一.首先说说View和ViewGroup吧 Android系统中的所有UI类都是建立在View和ViewGroup这两个类的基础上的.所有View的子类成为"Widget",所有 ViewGroup的子类成为"Layout".View和ViewGroup之间采用了组合设计模式,可以使得"部分-整体"同等对待. ViewGroup作为布局容器类的最上层,布局容器里面又可以有View和ViewGroup. 二.LayoutInflater,Layou

Android中动态添加View的两种方法

一.使用xml的方式: 1.LayoutInflater: 这个类可以把xml表述的Layout解析为View,从而可以使addView()方法添加View. 2.LayoutInflater与findViewById的区别: 两者都是实例化某一个对象,不同的是findViewById是通过找xml布局文件下的一个具体的widget控件进行实例化,而LayoutInflater是找res/layout 下的xml布局文件来实例化的. 3.使用方法: LayoutInflater inflater