1.来源
问题的来源是因为现在的公司准备转向Android,但是又不想放弃原来的系统,所以想把原来在linux上直接跑的系统移植到Android上来,当然一大重头任务就是对原有界面库的移植和Android图形系统的修改。
我们需要对Android的图形系统加以修改,以实现原有系统的图形效果。原来的系统中有一种页面切换效果,需要将它在Android上实现出来。一开始我是在应用程序层面上,重载装载页面的viewgroup的绘制函数实现的。但是,由于view的内容太过复杂以及在页面切换时系统需要做很多事情,所以切换的动画过程很卡,出现跳帧的现象。
所以我们想到在Android的底层,也就在SurfaceFlinger这个层面上做这种效果。
要想在SurfaceFlinger上面做出这种页面切换效果,而且能根据程序设置决定效果的样式,那么我们需要从应用程序层传递标志到SurfaceFlinger。
我们在SurfaceFlinger里的drawWithOpenGl里,可以得到一个Layer的alpha值,而在应用程序里,我们可以通过来改变此activity对应的surface的alpha值。
Window window = null; WindowManager.LayoutParams wl; window = getWindow(); wl = window.getAttributes(); wl.alpha = 0.5f; window.setAttributes(wl);
所以需要以Window的LayoutParams.alpha为例,研究Android的图形系统是怎样将WindowManager.LayoutParams里的alpha属性传递到SurfaceFlinger中的drawWithOpenGL中去的。
2.过程分析
1.从Activity类开始
既然在程序中首先是在Activity类中通过getWindow()方法取得Window,那么我们就从Activity类开始。它的实现也很简单,就是返回了一个Window的实例mWindow.public Window getWindow() { return mWindow; }
那么我们转到Window类中去看看。2.Window类
找到它的位置:./frameworks/base/core/java/android/view/Window.java,按它的类的说明:它是一个顶层的窗口外观和行为策略的抽象类。它的实例应该被用作顶层窗口而添加到Window Manager中去。它提供标准的UI策略,例如背景,标题区域以及默认键处理等。它有一个惟一的实现类:android.policy.PhoneWindow.我们先看public void setAttributes(WindowManager.LayoutParams a) ,这个函数的功能是详细的定制窗口的属性:可见这个函数的功能就是将传进来的属性拷贝到它的成员变量里面,然后调用回调变量的方法。public void setAttributes(WindowManager.LayoutParams a) { mWindowAttributes.copyFrom(a); if (mCallback != null) { mCallback.onWindowAttributesChanged(mWindowAttributes); } }
在Window类里面找到mCallback的赋值,发现它是通过Window::