Android12 Gallery2源码分析(一)

1.首先查看AndroidManifest.xml查看清单文件,查找程序的入口:

<activity android:name="com.android.gallery3d.app.GalleryActivity" 
         android:label="@string/app_name"
        android:exported="true"
        android:configChanges="keyboardHidden|orientation|screenSize|screenLayout">
    <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>
    ...
    </activity>

2.找到com.android.gallery3d.app.GalleryActivity,继承AbstractGalleryActivity 并实现了OnCancelListener,OnCancelListener为dialog的取消事件。首先进入onCreate()方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_ACTION_BAR);
    requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);

    if (getIntent().getBooleanExtra(KEY_DISMISS_KEYGUARD, false)) {
        getWindow().addFlags(
                WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
    }

    setContentView(R.layout.main);

    if (savedInstanceState != null) {
        getStateManager().restoreFromState(savedInstanceState);
    } else {
        if (CheckPermissionActivity.hasUnauthorizedPermission(this)) {
            requestPermissions(CheckPermissionActivity.REQUEST_PERMISSIONS,
                    CheckPermissionActivity.REQUEST_CODE_ASK_PERMISSIONS);
            mUnInit = true;
        } else {
            initializeByIntent();
        }
    }
}

我们首先查找布局 R.layout.main

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/gallery_root"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#1a1a1a">
    <include layout="@layout/gl_root_group"/>
    <FrameLayout android:id="@+id/header"
            android:visibility="gone"
            android:layout_alignParentTop="true"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    <FrameLayout android:id="@+id/footer"
            android:visibility="gone"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentRight="true"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
</RelativeLayout>

布局很简单,由三部分组成,gl_root_group、header、footer,根据名字和布局 可知,header、footer仅为上层的一些自定义布局,Gallery显示功能的布局为

查找布局:

<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"/>
    <View android:id="@+id/gl_root_cover"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/black"/>
</merge>

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

// 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.
if (mFirstDraw) {
    mFirstDraw = false;
    post(new Runnable() {
            @Override
            public void run() {
                View root = getRootView();
                View cover = root.findViewById(R.id.gl_root_cover);
                cover.setVisibility(GONE);
            }
        });
}

GLRootView 继承自 GlSurfaceView,实现了GlSurfaceView.Renderer接口,其中的三个方法为核心方法:

@Override
public void onSurfaceCreated(GL10 gl1, EGLConfig config) {//surfaceview创建好调用,绘制工作准备阶段处理一些数据设置相关的工作
    GL11 gl = (GL11) gl1;
    if (mGL != null) {
        // The GL Object has changed
        Log.i(TAG, "GLObject has changed from " + mGL + " to " + gl);
    }
    mRenderLock.lock();
    try {
        mGL = gl;
        mCanvas = ApiHelper.HAS_GLES20_REQUIRED ? new GLES20Canvas() : new GLES11Canvas(gl);
        BasicTexture.invalidateAllTextures();
    } finally {
        mRenderLock.unlock();
    }

    if (DEBUG_FPS || DEBUG_PROFILE) {
        setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    } else {
        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
    }
}

/**
 * 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) {//surfaceview改变时回调此方法,比如横竖屏转换等,这里面一般是重新设置界面size等
    Log.i(TAG, "onSurfaceChanged: " + width + "x" + height
            + ", gl10: " + gl1.toString());
    Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY);
    GalleryUtils.setRenderThread();
    if (DEBUG_PROFILE) {
        Log.d(TAG, "Start profiling");
        Profile.enable(20);  // take a sample every 20ms
    }
    GL11 gl = (GL11) gl1;
    Utils.assertTrue(mGL == gl);

    mCanvas.setSize(width, height);
}
@Override
public void onDrawFrame(GL10 gl) {///每绘制一帧都会回调此方法,也就是说你想绘制三角形还是纹理贴图等都是在这方法里面实现
    AnimationTime.update();
    long t0;
    if (DEBUG_PROFILE_SLOW_ONLY) {
        Profile.hold();
        t0 = System.nanoTime();
    }
    mRenderLock.lock();

    while (mFreeze) {
        mFreezeCondition.awaitUninterruptibly();
    }

    try {//绘制方法
        onDrawFrameLocked(gl);
    }
    catch (NullPointerException e){
        //e.printStackTrace(); 
    }
    finally {
        mRenderLock.unlock();
    }

    // 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.
    if (mFirstDraw) {
        mFirstDraw = false;
        post(new Runnable() {
                @Override
                public void run() {
                    View root = getRootView();
                    View cover = root.findViewById(R.id.gl_root_cover);
                    cover.setVisibility(GONE);
                }
            });
    }

    if (DEBUG_PROFILE_SLOW_ONLY) {
        long t = System.nanoTime();
        long durationInMs = (t - mLastDrawFinishTime) / 1000000;
        long durationDrawInMs = (t - t0) / 1000000;
        mLastDrawFinishTime = t;

        if (durationInMs > 34) {  // 34ms -> we skipped at least 2 frames
            Log.v(TAG, "----- SLOW (" + durationDrawInMs + "/" +
                    durationInMs + ") -----");
            Profile.commit();
        } else {
            Profile.drop();
        }
    }
}

查看onDrawFrameLocked绘制方法

private void onDrawFrameLocked(GL10 gl) {
    if (DEBUG_FPS) outputFps();

    // release the unbound textures and deleted buffers.
    mCanvas.deleteRecycledResources();

    // reset texture upload limit
    UploadedTexture.resetUploadLimit();

    mRenderRequested = false;

    /*if ((mOrientationSource != null
            && mDisplayRotation != mOrientationSource.getDisplayRotation())
            || (mFlags & FLAG_NEED_LAYOUT) != 0) {
        layoutContentPane();
    }*/
    if ((mFlags & FLAG_NEED_LAYOUT) != 0) layoutContentPane();

    mCanvas.save(GLCanvas.SAVE_FLAG_ALL);
    rotateCanvas(-mCompensation);
    if (mContentView != null) {
       mContentView.render(mCanvas);//mContentView通过canvas渲染定义的view
    } else {
        // Make sure we always draw something to prevent displaying garbage
        mCanvas.clearBuffer();
    }
    mCanvas.restore();

    if (!mAnimations.isEmpty()) {
        long now = AnimationTime.get();
        for (int i = 0, n = mAnimations.size(); i < n; i++) {
            mAnimations.get(i).setStartTime(now);
        }
        mAnimations.clear();
    }

    if (UploadedTexture.uploadLimitReached()) {
        requestRender();
    }

    synchronized (mIdleListeners) {
        if (!mIdleListeners.isEmpty()) mIdleRunner.enable();
    }

    if (DEBUG_INVALIDATE) {
        mCanvas.fillRect(10, 10, 5, 5, mInvalidateColor);
        mInvalidateColor = ~mInvalidateColor;
    }

    if (DEBUG_DRAWING_STAT) {
        mCanvas.dumpStatisticsAndClear();
    }
}

GLView是界面显示的UI组件,图库界面是有很多个控件组成的,GLView就是这些控件的基类,它可以渲染到GLCanvas上,并且接受触摸事件。

内部通过 protected void render(GLCanvas canvas) 方法 以及protected void renderChild(GLCanvas canvas, GLView component) 方法实现当前view组件以及子view

组件 在GLCanvas上绘制。

GLCanvas就是一个画布,GLCanvas是一个接口,它最终是使用OpenGL ES的GLES20.glDrawArrays(type, 0, count)来绘制每个GLView,它可以绘制直线、矩形等形状。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值