01 Gallery 源码-GalleryActivity的初始化

本文深入剖析了Android中GalleryActivity的启动过程,从程序入口、关键布局到自定义GLRootView的绘制流程,揭示了图库应用如何响应Intent意图并初始化界面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0. 原文拜读

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();
        }
        ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值