android7.0之系统应用Gallery2整体分析以及开始过程

时间:2024-03-19 14:26:52

不积跬步,无以至千里

     Gallery2,图库是也。
     因为新项目需要负责这个模块,所以要提前做一下功课,因此在网上也看了不少从android4.4到android6.0的文章的分析,说实话,刚开始看Gallery2代码有点懵逼,这是什么,完全和自己想的逻辑不一样,然后稍微了解之后,感觉Gallery2,牛批,牛批…..

     接下来给大家分析一下

     他有一个首界面即Launcher界面为GalleryActivity,这个就是首界面如下图:
android7.0之系统应用Gallery2整体分析以及开始过程
     接下来它(GalleryActivity)有一个父类即AbstractGalleryActivity,其中要说的是这个app的所有上下文引用其实都用的是由AbstractGalleryActivity赋值的mActivity。
     接下来要说一下这个界面了,其实Gallery2神奇的是就是他虽然有好多界面的切换,但是他只有一个Activity,其实的界面都是由GLRootView.java画出来的界面,其中常见的包括AlbumSetPage(相册缩略图),AlbumPage(好多照片组成的缩略图),PhotoPage(单张照片),ManageCachePage(缓存管理),SlideShowPage(单张滑屏界面),这些界面有一个父类就是ActivityState,为什么呢?
     因为本身不是用的Activity做载体实现界面与逻辑,而是通过通过OpenGl系统运行库来画界面,这样的操作,因为OpenGl会更高效的实现2D与3D图形的绘制,而取代固有的Activity的跳转界面与图片的展示。同样,你不使用Activity,但必定也需要生命周期这种Activity的逻辑,因此ActivityState来总体来控制界面的逻辑,各个界面实现内部的方法,再去实现各自的逻辑,多态的体现,从而又引出了一个负责界面切换的StateManager,接下来给大家介绍一下几个Manager。
     StateManager(负责界面的切换的管理者)、DataManager(负责数据的管理者)、OrientationManager(重力方向的管理者)、SelectionManager(选择照片的管理者),这是所有的管理者,由于界面与数据之间还需要绑定,所以也会有各自界面的Adapter。
     下面就给大家从首界面开始分析一下吧,大家根据AndroidManifest.xml文件也知道了,第一个界面是GalleryActivity。
android7.0之系统应用Gallery2整体分析以及开始过程
     首先,是ActionBar的覆盖模式,然后如果是锁屏状态需要先解锁,然后加载布局文件,然后如果上次有保存状态恢复保存状态,如果没有则调用initializeByIntent方法。
接下来,看一下initializeByIntent这个方法。
android7.0之系统应用Gallery2整体分析以及开始过程
     分析一下,获取意图action,并根据不同的意图有不同的处理,为什么?因为这里考虑到,由不同的app,发过来的调用,例如:聊qq发一张照片,让你从相册图库中获取,这里就有这个意图,所以第一个到第三个都是从外界面跳转过来的意图,而第四个是点击图库图标进来的默认界面即:startDefaultPage方法。接下里看一下这个方法。
android7.0之系统应用Gallery2整体分析以及开始过程
     分析一下,一些不重要的初始化就不说了,说一下主要逻辑,通过一个Bundle,放置了媒体库的路径(通过代码如下路径为:),其中先是获取DataManager对象,然后调用方法getTopSetPath。
android7.0之系统应用Gallery2整体分析以及开始过程
     获取的路径是TOP_SET_PATH,如下图:
android7.0之系统应用Gallery2整体分析以及开始过程
     然后是下半部分的getStateManager().startState(AlbumSetPage.class, data),首先看到获取了StateManager对象,然后调用了startState方法,接下来看一下这个方法:
android7.0之系统应用Gallery2整体分析以及开始过程
     分析一下,根据你传过来的klass,创建一个实例,然后这里会出现一个新的东西mStack这是对象是一个栈,用来管理你这些界面的,如果你打开了这个界面,就会把你push进去,如果你退出了,就会把你remove掉。说一下代码的逻辑吧,你可以看一下,他是判断了这个栈为不为空,如果不为空,则把这个顶部的界面onPause掉。然后下面执行了state的initialize方法,会初始化上下文引用,然后调用了mStack.push方法说的就是把这个AlbumSetPage放入栈中,然后调用这个AlbumSetPage的onCreate方法,再执行一下ActivityState的resume方法,初始化一下ActionBar。
     AlbumSetPage界面的流程等下一篇文章再说,再说一下,我们加载的那个布局文件main.xml
android7.0之系统应用Gallery2整体分析以及开始过程
     由图可知,其中有header、footer布局,这个布局就相当于整个界面的头、底布局,然后引入gl_root_group这个布局,接下来看一下这个布局。
android7.0之系统应用Gallery2整体分析以及开始过程
     由图可知,有一个自定义View的GLRootView,有一个gl_root_cover的View,GLRootView即咱们之前说的各个画面的转换都是通过GLRootView画的,而gl_root_cover是一层布局,逻辑在GLRootView里面有对这个布局的控制,如下:
android7.0之系统应用Gallery2整体分析以及开始过程
     根据英文,也可以知道,当你第一次打开的时候会把这个布局放到这个GLRootView的布局之上,防止这个SurfaceView变成透明,第二次以后会把这个布局去掉。接下来看一下这个GLRootView它继承的opengl的GLSurfaceView,它主要有以下几个方法。
android7.0之系统应用Gallery2整体分析以及开始过程
     一般都是Surface创建好,会回调此方法,一般都是绘制界面的准备工作。
android7.0之系统应用Gallery2整体分析以及开始过程
     一般都是Surface改变时,比如说横竖屏切换,一般都是重新设置界面size等
android7.0之系统应用Gallery2整体分析以及开始过程
     每绘制一帧都会回调此方法,就是说你想绘制什么图形,都是在这里实现的
     其中这个onDrawFrameLocked方法。
android7.0之系统应用Gallery2整体分析以及开始过程
     详细如下图:
android7.0之系统应用Gallery2整体分析以及开始过程
     其中的mContentView是GLView需要画出的界面,mCanvas是GLCanvas承载界面的画布,其中每次画一个界面的时候就会加一个锁,以达到同步的目的。
     其中这个GLView就和UI的小组件一样,因为咱们这里所有界面都不是用的activity,自然就会用不到组件,然后这里的组件都是GLView组成的,而GLView是这些组件的基类。它可以渲染到GLCanvas上,并且接受触摸事件。GLCanvas就是一个画布,GLView的size等定义好了怎么显示到界面上呢?其实就是通过GLCanvas来实现,GLCanvas是一个接口,它最终是使用OpenGL ES的GLES20.glDrawArrays(type, 0, count)来绘制每个GLView,它可以绘制直线、矩形等形状。
     GLView的子类在com.android.gallery3d.ui目录里,以view.java结尾的都是它的子类,像EdgeView、PhotoView、ScrollBarView、SlideshowView、SlotView、TileImageView、UndoBarView等,每个代表一种UI组件类型。
     GLCanvas有GLES11Canvas和GLES20Canvas两个子类,GLES11Canvas代表OpenGL ES 1.1之前的版本,使用固定管线绘图,这个版本太老可以不考虑了;GLES20Canvas代表OpenGL ES 2.0之后的版本,使用shader语言实现绘图,现在一般都是使用它。