每当启动一个带activity的app时,首先zygote会fork一个子进程,执行app的代码,它的入口为activityThread的main函数,并创建了一个Looper。
1.一个重要的方法是activityThread的mInstrumentation.newActivity,最终会创建一个PhoneWindow和一个WindowManagerImpl的LocalWindowManager 。
2.接下来一个重要的方法是activityThread的performLaunchActivity中的mInstrumentation.callActivityOnCreate,最终会调用activity的onCreate。在onCreate中会调用setContentView,其实调用的是PhoneWindow的setContentView,在此方法中,会创建一个FrameLayout,mDecor,即DecorView,在PhoneWindow的generateLayout中它处理了标题栏的样式并通过findbyid得到一个Fragment的对象mContentParent,它就是我们在activity中通过setContentView放入的布局或View
3.然后是activityThread的handleResumeActivity中 得到DecorView View decor = r.window.getDecorView();和LocalWindowManager ViewManager wm = a.getWindowManager(); 然后调用wm.addView(decor, l); 然后会调用WindowManagerImpl的addView,最终会调用ViewRootImpl的setView,
有些版本ViewRootImpl为ViewRoot,改了个名字
4.class ViewRootImpl extends Handler implements ViewParent,View.AttachInfo.Callbacks,HardwareRenderer.HardwareDrawCallbacks ViewRootImpl继承了Handler,实现了ViewParent
里面还有三个重要的变量 Surface类型的mSurface W类型的mWindow基于Binder View类型的mView即DecorView
4.1 在ViewRootImpl的构造方法中,调用getWindowSession会通过Binder远程调用WindowManagerService的openSession,会得到一个Binder服务端的Session的对象引用sWindowSession 用于RootViewImpl与WindowManagerService通讯 mWindow则是WindowManagerService与RootViewImpl通讯
4.2 在步骤3中讲到会调用ViewRootImpl的setView,里面会调用sWindowSession.add(mWindow,mSeq,mWindowAttributes,getHostVisibility(),mAttachInfo.mContentInsets.mInputChannel); 也就是WindowManagerService的add,最终会得到一个SurfaceSession 这个后来再用
5 接第三步ViewRootImpl的setView 重要的一个方法为requestLayout,接着调用里面的scheduleTraversals接着是sendEmptyMessage(DO_TRAVERSAL); 接着是performTraversals(); 在performTraversals中 重要的方法是relayoutWindow和mView.draw(layerCanvas);还有View的绘制流程
5.1 relayoutWindow最终调用WindowManagerService的relayoutWindow 在这里 会得到一个Surface的对象 并通过Binder传递给 ViewRootImpl的mSurface 在WindowManagerService中得到的Surface中有native层请求SurfaceFling创建的一块内存缓冲区 也就是屏幕显示的东西
5.2 host.measure测量View大小
5.3 host.layout确定View的位置
5.4 mView.draw(layerCanvas);则开始了各个View的draw流程 layerCanvas是通过mSurface 得到的
5.5 View树的重新遍历 当调用invalidate requestLayout requestFocus时 会重新遍历 将调用ViewRootImpl的performTraversals
以上是参照pdf<深入理解android卷1><android内核剖析> 以及http://androidxref.com/4.0.3_r1/
二、ndroid最基本的画图需要四个基本组件 bitmap canvas drawing primitive(路径,文字,图片等) paint 这些都会画在canvas上
还有一些相关的类 如管理路径的PathEffect族 图像混合的XferModes 图形变换的Matrix(大多的Tween动画就是通过它实现) 等
三、 颜色渲染的Shader族 Drawable族(这个也是基于Canvas)
四、自定义控件
1 组合现有控件,变为一个新的控件,简单封装 方便使用
2 继承现有控件 添加一些功能
3 继承View或ViewGroup 可以实现复杂的效果 一般步骤为
3.1 自定义属性 <declare-styleable>
3.2 重写onMeasure()[setMeasuredDimension(width, height)保存结果] onLayout() onDraw()
3.3 点击事件(onTouch、onClick) 以及相关的 如GestureDetector 事件拦截Scroller
五 SurfaceView和GLSurfaceView 都是异步 不过GLSurfaceView是基于opengles
六 动画
1 逐帧动画 AnimationDrawable
2 补间动画 TranslateAnimation ScaleAnimation RotateAnimation AlphaAnimation
还有控制速率的interpolator和动画组AnimationSet 也可以使用xml
补间动画主要是start时调用invalide() 在View的draw时 得到Animtion中的变换参数Transformation的对象
然后通过canvas进行相应的变换 它是通过invalid驱动的 <android内核剖析>13.11.2
逐帧动画和补间动画还有AnimationListener的回调以及一个AnimationUtils工具类,他们都继承自Animation
3 属性动画
3.1属性动画主要是ValueAnimator和它的子类ObjectAnimator和TimeAnimator
ValueAnimator主要是通过animator.addUpdateListener(new AnimatorUpdateListener()里面的回调设置View的属性
ObjectAnimator是对ValueAnimator的扩展,提供了便捷的方法
TimeAnimator 不是很明白作用,简单封装了ValueAnimator,提供了一个回调TimeListener,在animationFrame中会调用回调方法,应该是每个时间点都会回调吧
此外 还有动画组AnimatorSet,ValueAnimator继承的Animator,Interpolator族,AnimationListener,TypeEvaluator计算动画帧的时间点,PropertyValuesHolder封装了动画帧的信息,ViewPropertyAnimator一个view需要显示多个动画时使用,框架做了优化,如果只改变view的一个属性,用ObjectAnimator就好,Keyframe关键帧,封装了time/value,主要作用是多个keyFrame之间可以定义不同的Interpolator
属性动画是通过Handler驱动的
3.2 布局动画 LayoutTransition
布局动画主要有两个方法
调用动画有五个时机 ①APPEARING控件变为可见时 ②CHANGE_APPEARING,View树发生变动,控件即将显现 ③CHANGE_DISAPPEARING,View树发生变动,控件即将隐藏 ④CHANGING,View树发生变动,控件正在移动 ⑤DISAPPEARING控件变为不可见时
setStagger(type,time) 两个动画之间的间隔时间setAnimator (type,animation) 设置动动
布局动画靠View树改变驱动
七 其他
7.1 Camera 关于3d转换
7.2 ColorMatrix 更改图片的颜色和透明度
7.3 Movie gif显示
7.4 YuvImage 将YUV转换为jpeg
7.4 Picture 可以在上面用paint画图,具体不太清楚
7.5 MaskFilter族 对Paint的alpha通道的转换
7.6 ColorFilter族 对每一个RGB通道应用转换
八 Bitmap BitmapFactory 对于图片优化,BitmapFactory.Options还是很重要的
有些乱了