Android 7.0 Gallery图库源码分析1 - 初识Gallery源码

分析一个项目的源代码时,第一件事就是查看清单文件,找到程序入口,我们从Gallery2源码的清单文件中可以看到GalleryActivity是此应用的启动Activity。

1 <activity android:name="com.android.gallery3d.app.GalleryActivity" android:label="@string/app_name"
2                 android:configChanges="keyboardHidden|orientation|screenSize">
3             <intent-filter>
4                 <action android:name="android.intent.action.MAIN" />
5                 <category android:name="android.intent.category.DEFAULT" />
6                 <category android:name="android.intent.category.LAUNCHER" />
7                 <category android:name="android.intent.category.APP_GALLERY" />
8             </intent-filter>
找到GalleryActivity,它继承自AbstractGalleryActivity,实现OnCancelListener,OnCancelListener暂时不用考虑,它只是处理dialog防止内存泄漏,我们首先查看onCreate方法
 1 @Override
 2     protected void onCreate(Bundle savedInstanceState) {
 3         super.onCreate(savedInstanceState);
 4         requestWindowFeature(Window.FEATURE_ACTION_BAR);
 5         //使用ActionBar的覆盖模式
 6         requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
 7
 8         if (getIntent().getBooleanExtra(KEY_DISMISS_KEYGUARD, false)) {
 9             //加载布局之前解除锁屏
10             getWindow().addFlags(
11                     WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
12         }
13         //加载布局
14         setContentView(R.layout.main);
15
16         if (savedInstanceState != null) {
17             getStateManager().restoreFromState(savedInstanceState);
18         } else {
19             //根据Intent类型初始化
20             initializeByIntent();
21         }
22     }

我们首先分析布局,找到R.layout.main

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2         android:id="@+id/gallery_root"
 3         android:orientation="vertical"
 4         android:layout_width="match_parent"
 5         android:layout_height="match_parent">
 6     <include layout="@layout/gl_root_group"/>
 7     <FrameLayout android:id="@+id/header"
 8             android:visibility="gone"
 9             android:layout_alignParentTop="true"
10             android:layout_width="match_parent"
11             android:layout_height="wrap_content"/>
12     <FrameLayout android:id="@+id/footer"
13             android:visibility="gone"
14             android:layout_alignParentBottom="true"
15             android:layout_alignParentLeft="true"
16             android:layout_alignParentRight="true"
17             android:layout_width="match_parent"
18             android:layout_height="wrap_content"/>
19 </RelativeLayout>

根据id我们可以判断layout/gl_root_group这个布局应该是最主要的,用来显示主要内容,header和footer暂且不管。gl_root_group是通过include标签来引用的,我们找到此布局。

 1 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 2     <com.android.gallery3d.ui.GLRootView
 3             android:id="@+id/gl_root_view"
 4             android:layout_width="match_parent"
 5             android:layout_height="match_parent"/>
 6     <View android:id="@+id/gl_root_cover"
 7             android:layout_width="match_parent"
 8             android:layout_height="match_parent"
 9             android:background="@android:color/black"/>
10 </merge>

它有两个布局。第一个是GLRootView,它继承自GLSurfaceView,也就是说它是使用OpenGL ES来绘制界面,它也是整个界面的核心;第二个是View,根据它的id可以看出它是覆盖在GLRootView上的,至于它的作用我们在GLRootView的onDrawFrame方法中可以发现下面这段代码,它是应用第一次绘制界面时覆盖在SurfaceView上面,防止第一次绘制时SurfaceView变透明,影响美观,之后都会隐藏此View。

 1 // We put a black cover View in front of the SurfaceView and hide it
 2 // after the first draw. This prevents the SurfaceView being transparent
 3 // before the first draw.
 4 if (mFirstDraw) {
 5             mFirstDraw = false;
 6             post(new Runnable() {
 7                     @Override
 8                     public void run() {
 9                         View root = getRootView();
10                         View cover = root.findViewById(R.id.gl_root_cover);
11                         cover.setVisibility(GONE);
12                     }
13                 });
14         }

我们接着看GLRootView,它继承自GLSurfaceView,所以它绘制界面核心就是下面三个方法。

 1 public class GLRootView extends GLSurfaceView
 2         implements GLSurfaceView.Renderer, GLRoot {
 3     @Override
 4     public void onSurfaceCreated(GL10 gl1, EGLConfig config) {
 5         //Suface创建好会回调此方法,一般这个方法都是做些绘制界面的准备工作
 6     }
 7
 8     @Override
 9     public void onSurfaceChanged(GL10 gl1, int width, int height) {
10         //Suface改变时回调此方法,比如横竖屏转换等,这里面一般是重新设置界面size等
11     }
12
13     @Override
14     public void onDrawFrame(GL10 gl) {
15        //每绘制一帧都会回调此方法,也就是说你想绘制三角形还是纹理贴图等都是在这方法里面实现。
16
17         try {
18             //这个方法是实际绘制界面的
19             onDrawFrameLocked(gl);
20         } finally {
21             mRenderLock.unlock();
22         }
23     }
24 }

我们接着查看onDrawFrameLocked方法

 1 private void onDrawFrameLocked(GL10 gl) {
 2         ......
 3         //mContentView是GLView类型,mCanvas是GLCanvas类型,这是绘制界面的主要工具
 4         if (mContentView != null) {
 5            mContentView.render(mCanvas);
 6         } else {
 7             // Make sure we always draw something to prevent displaying garbage
 8             mCanvas.clearBuffer();
 9         }
10         ......
11     }

现在讲讲GLView和GLCanvas这两个类,GLView是界面显示的UI组件,图库界面是有很多个小控件组成的,GLView就是这些小控件的基类,它可以渲染到GLCanvas上,并且接受触摸事件。GLCanvas就是一个画布,GLView的size等定义好了怎么显示到界面上呢?其实就是通过GLCanvas来实现,GLCanvas是一个接口,它最终是使用OpenGL ES的GLES20.glDrawArrays(type, 0, count)来绘制每个GLView,它可以绘制直线、矩形等形状,没学过OpenGL ES的可以参考我之前的文章,对OpenGL ES有个大概了解。

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语言实现绘图,现在一般都是使用它。

现在就将这些,至于GLView和GLCanvas的细节后面再详解。

原文地址:https://www.cnblogs.com/zhao-shan/p/9838262.html

时间: 2024-10-12 21:06:53

Android 7.0 Gallery图库源码分析1 - 初识Gallery源码的相关文章

[转] jQuery源码分析-如何做jQuery源码分析

jQuery源码分析系列(持续更新) jQuery的源码有些晦涩难懂,本文分享一些我看源码的方法,每一个模块我基本按照这样的顺序去学习. 当我读到难度的书或者源码时,会和<如何阅读一本书>结合起来进行学习.推荐读读这本书,你可以从这里和这里下载. 第一部分:检视阅读 1. 收集参考资料:官方文档.书籍.百度/谷歌,专题/博客等,快速的浏览,对涉及的知识点.范围.深度.是否有参考意义等有大致的了解和判断,知道这些文章的作者想要解释或解决什么问题. 第二部分:分析阅读 2. 细读官方文档,官方有非

android4.0 的图库Gallery2代码分析(四) 之相册的数据处理以及显示

最近迫于生存压力,不得不给人兼职打工.故在博文中加了个求点击的链接.麻烦有时间的博友们帮我点击一下.没时间的不用勉强啊.不过请放心,我是做技术的,肯定链接没病毒,就是我打工的淘宝店铺.嘻嘻.http://shop108130013.taobao.com.谢谢捧场.以后就每周写篇原创的技术博客回报大家,实在是迫于生计,无所不用其极.请谅解. 相册的数据处理以及显示 相册的处理都包含在AlbumSetPage中.要明白相册的形成过程,一定要清楚AlbumSetPage的形成过程. AlbumSetP

MyBatis源码分析-IDEA新建MyBatis源码工程

MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录.项目GitHub地址 下载MyBatis源码,导入到IDEA工程(Maven工程)中,工程结构如下: 在pom.xml中新增如下依赖: <!-- MyS

wifidog源码分析Lighttpd1.4.20源码分析之插件系统(3)---PLUGIN_TO_SLOT宏

前面讲了lighttpd插件系统的加载和初始化,这一篇中,将介绍一下plugin.c中的宏PLUGIN_TO_SLOT.在将PLUGIN_TO_SLOT宏之前,我们先来看看lighttpd中插件系统的对外接口.这个接口所对的“外”指的是lighttpd服务器.前面已经提到,在运行的过程中,lighttpd不知道所加载的插件都是干什么用的,只知道这些插件所实现的接口,也就是在plugin结构体中那些函数指针有哪些对于某个插件是NULL,哪些是具体的函数地址.既然lighttpd只知道这些,那么它又

Java源码分析系列之HttpServletRequest源码分析

从源码当中 我们可以 得知,HttpServletRequest其实 实际上 并 不是一个类,它只是一个标准,一个 接口而已,它的 父类是ServletRequest. 认证方式 public interface HttpServletRequest extends ServletRequest 从阅读源码 当中 ,我们 可以 获得 如下认证信息: /** * String identifier for Basic authentication. Value "BASIC" */ pu

Dubbo源码分析(八):Javassist字节码技术生成代理

Java动态编程的作用:      通过配置生成代码,减少重复编码和维护成本 我们常用到的动态特性主要是反射,在运行时查找对象属性.方法,修改作用域,通过方法名称调用方法等.在线的应用不会频繁使用反射,因为反射的性能开销较大.其实还有一种和反射一样强大的特性,但是开销却很低,它就是Javassit. Javassit其实就是一个二方包,提供了运行时操作Java字节码的方法.大家都知道,Java代码编译完会生成.class文件,就是一堆字节码.JVM(准确说是JIT)会解释执行这些字节码(转换为机

Dubbo源码分析(一):Dubbo源码的结构概述

1.dubbo源码的结构 Dubbo源文件主要包含以上这么多包,其中:  dubbo-common 公共逻辑模块,包括Util类和通用模型. dubbo-remoting 远程通讯模块,相当于Dubbo协议的实现,如果RPC用RMI协议 则不需要使用此包. dubbo-rpc 远程调用模块,抽象各种协议,以及动态代理,只包含一对一的调用, 不关心集群的管理.  dubbo-cluster 集群模块,将多个服务提供方伪装为一个提供方,包括:负载均衡, 容 错,路由等,集群的地址列表可以是静态配置的

JDK1.8源码分析02之阅读源码顺序

序言:阅读JDK源码应该从何开始,有计划,有步骤的深入学习呢? 下面就分享一篇比较好的学习源码顺序的文章,给了我们再阅读源码时,一个指导性的标志,而不会迷失方向. 很多java开发的小伙伴都会阅读jdk源码,然而确不知道应该从哪读起.有些零零散散的学习,知识与知识之间没有相互联系起来,不成知识体系.以下为小编整理的通常所需阅读的源码范围. 标题为包名,后面序号为优先级1-4,优先级递减 1.java.lang 1) Object 1 2) String 1 3) AbstractStringBu

android4.0 的图库Gallery2代码分析(三) 之Applition的初始化准备

Applition的初始化准备 图库的一切动作都明显地起源于Application.这是区别与其他那种感觉不到Application存在,仅仅感觉到Activity存在的简单应用的一个特点. 图库的application就是GalleryAppImpl.java. 可以说GalleryAppImpl是图库的基石.它扩展Application这是必定的,代表他就是一个Application,同时它额外实现了GalleryApp的interface. GalleryApp中很清楚地表明了自己的作为图