深入分析Activity 绘制机制

来源:互联网 发布:篮球教学软件大全 编辑:程序博客网 时间:2024/03/28 17:10
我们写的第一个程序一般是这样:
public class MainActivity extends Activity{

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
}

运行起来后,就会显示一个基本的页面。

现在我们梳理下,这个基本页面的创建和显示逻辑。


创建一个新的Activity,zygote进程会fork一个子进程,这个子进程的入口函数就是ActivityThread的main函数,该函数的

handleLaunchActivity函数负责Activity的创建工作。

每个Activity内部有一个Window对象和WindowManager对象。

这个window是PhoneWindow对象。window对应的就是手机上的显示单元。Window有个方法getDecorView()
返回一个FrameLayout类型的ViewGroup,这就是根View,即DecorView。这个view包括toolbar,状态栏和ContentView,
这个ContentView就是我们调用setContentView(R.layout.activity_main)所设置view的父view。

这个WindowManager是LocalWindowManager对象,该对象将工作代理到WindowManagerImpl对象去实现,而
这个类将所有的事转到让WindowManagerGlobal这个对象去执行。WindowManagerGlobal是单例的。

handleLaunchActivity函数中,创建完DecorView后,会调用WindowManager.addView(DecorView). 在addView函数中,
会创建一个viewroot对象,该对象非常重要,它继承自ViewParent。WindowManager中对保存viewroot,decorview和layoutparams对象数组,
然后调用ViewRoot.setView(decorview, layoutparams);

下面我们来分析下viewroot都做什么事。
public final class ViewRoot extends Handler implements ViewParent, View.AttachInfo.Callbacks {
 final W mWindow; 
 View mView; 
...
}

W是viewroot的内部类,
 static class W extends IWindow.Stub {

在ViewRoot的构造函数中,会调用getWindowSession获得IWindowSession接口,该接口是和WindowManagerService进行Binder通信的bp端。
在ViewRoot.setView()函数中,会调用WindowManagerService的add()方法将W成员对象通过binder设置给WindowManagerService。

这样ViewRoot可通过IWindowSession和WindowManagerService通信,而WindowManagerService可以通过IWindow和ViewRoot通信,这样双向通信就建立了。

看下IWindow中定义的方法,大家就大概明白一点了。

public void dispatchDragEvent(DragEvent event) 
public void windowFocusChanged(boolean hasFocus, boolean inTouchMode)
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,Rect visibleInsets, 
Rect stableInsets, boolean reportDraw, Configuration newConfig) 

绘制逻辑,当需要绘制或刷新界面时,会调到
void draw(boolean fullRedrawNeeded){

 canvas = mSurface.lockCanvas(dirty);
 mView.draw(canvas);
...
}

会调到DecorView的draw函数,然后一级一级调到各个view的draw()函数,最终界面就绘制出来。



























0 0
原创粉丝点击