0. 原文拜读
https://blog.youkuaiyun.com/lb377463323/article/details/68946581
- 作者:NULL____
- 来源:优快云
- 原文:https://blog.youkuaiyun.com/lb377463323/article/details/68946581
版权声明:本文为博主原创文章,转载请附上博文链接!
1. 程序入口
基于Android Mainfest
launcher 桌面图标属性
<activity android:name="com.android.gallery3d.app.GalleryActivity"
android:theme="@style/AppTheme"
android:configChanges="keyboardHidden|orientation|screenSize|locale|fontScale|layoutDirection|screenLayout|smallestScreenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.APP_GALLERY" />
</intent-filter>
程序入口
package com.android.gallery3d.app;
public final class GalleryActivity extends AbstractGalleryActivity implements OnCancelListener {
查看继承的关系
package com.android.gallery3d.app;
public abstract class AbstractGalleryActivity extends AbstractPermissionActivity
implements GalleryContext {
查看继承关系
package com.android.gallery3d.app;
import android.support.v4.app.FragmentActivity;
public abstract class AbstractPermissionActivity extends FragmentActivity {
private static final String TAG = "AbstractPermissionActivity";
上述查看这里是一个Acitivity
2. GalleryActivity.onCreate
onCreate 本身做的事情以初始化参数为主,重点在接受的Intent意图[initializeByIntent()函数]再进行区分初始化
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 监听屏幕模式与大小改变事件监听
listenerScreenModeChange();
getScreenMode();
// Intent中如果需要解锁屏幕
if (getIntent().getBooleanExtra(KEY_DISMISS_KEYGUARD, false)) {
// 则进行解除锁屏状态
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
// 添加Flag 锁屏时可以点开页面
Window win = getWindow();
WindowManager.LayoutParams params = win.getAttributes();
params.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
win.setAttributes(params);
// 加载布局
setContentView(R.layout.gallery_main);
// 初始化控件
initView();
// 保存activity的一些状态
mSavedInstanceState = savedInstanceState;
// 是否有 Manifest.permission.READ_PHONE_STATE 的权限状态(AbstractPermissionActivity)
if (isPermissionGranted()) {
//
init();
}
}
private void init() {
// 切换屏幕触发重新加载时 增加判断是否展示ViewPager
if (mSavedInstanceState != null && !isShowPagerView()) {
getStateManager().restoreFromState(mSavedInstanceState);
} else {
// 根据 Intent 类型进行初始化
initializeByIntent();
}
mSavedInstanceState = null;
}
3. 查看布局 R.layout.gallery_main
核心布局
<RelativeLayout
android:id="@+id/gallery_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<include layout="@layout/gl_root_group" />
</RelativeLayout>
查看 include 标签
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<com.android.gallery3d.ui.GLRootView
android:id="@+id/gl_root_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
// 第一次启动的美观优化
// We put a black cover View in front of the SurfaceView and hide it
// after the first draw. This prevents the SurfaceView being transparent
// before the first draw.
<View android:id="@+id/gl_root_cover"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fafafa"
/>
</merge>
重点是 gl_root_view 的自定义布局
package com.android.gallery3d.ui;
// The root component of all <code>GLView</code>s. The rendering is done in GL
// thread while the event handling is done in the main thread. To synchronize
// the two threads, the entry points of this package need to synchronize on the
// <code>GLRootView</code> instance unless it can be proved that the rendering
// thread won't access the same thing as the method. The entry points include:
// (1) The public methods of HeadUpDisplay
// (2) The public methods of CameraHeadUpDisplay
// (3) The overridden methods in GLRootView.
public class GLRootView extends GLSurfaceView
查看继承关系
package android.opengl;
public class GLSurfaceView extends SurfaceView implements Callback2 {
上述发现时 SurfaceView ,这里需要重点关注以下回调接口
package com.android.gallery3d.ui;
public class GLRootView extends GLSurfaceView
/**
* Called when the context is created, possibly after automatic destruction.
*/
// This is a GLSurfaceView.Renderer callback
@Override
public void onSurfaceCreated(GL10 gl1, EGLConfig config) {
//Suface创建好会回调此方法,一般这个方法都是做些绘制界面的准备工作
}
/**
* Called when the OpenGL surface is recreated without destroying the
* context.
*/
// This is a GLSurfaceView.Renderer callback
@Override
public void onSurfaceChanged(GL10 gl1, int width, int height) {
//Suface改变时回调此方法,比如横竖屏转换等,这里面一般是重新设置界面size等
}
@Override
public void onDrawFrame(GL10 gl) {
//每绘制一帧都会回调此方法
...
try {
//这个方法是实际绘制界面的
onDrawFrameLocked(gl);
} finally {
mRenderLock.unlock();
}
}
继续上述,重点再查看 onDrawFrameLocked
package com.android.gallery3d.ui;
public class GLRootView extends GLSurfaceView
implements GLSurfaceView.Renderer, GLRoot {
// GLView是界面显示的UI组件,图库界面是有很多个小控件组成的,GLView就是这些小控件的基类, 它可以渲染到GLCanvas上,并且接受触摸事件。
private GLCanvas mCanvas;
// GLCanvas就是一个画布,GLView的size等定义好了怎么显示到界面上呢?其实就是通过GLCanvas来实现,GLCanvas是一个接口,它最终是使用OpenGL ES的GLES20.glDrawArrays(type, 0, count)来绘制每个GLView,它可以绘制直线、矩形等形状
private GLView mContentView;
private void onDrawFrameLocked(GL10 gl) {
...
//mContentView是GLView类型,mCanvas是GLCanvas类型,这是绘制界面的主要工具
if (mContentView != null) {
mContentView.render(mCanvas);
} else {
// Make sure we always draw something to prevent displaying garbage
mCanvas.clearBuffer();
}
...