在Android Studio中复现AOSP原生GL2JNI图形渲染应用

在Android Studio中复现AOSP原生GL2JNI图形渲染应用

引言

在Android系统底层开发中,图形渲染是核心能力之一。AOSP(Android开源项目)中内置了许多图形测试工具,其中GL2JNI是一个典型的OpenGL ES 2.0渲染测试应用,用于验证GPU的基础渲染能力(如三角形绘制、颜色渐变等)。本文将以​​从零开始在Android Studio中复现GL2JNI应用​​为目标,详细讲解如何将AOSP的原生代码迁移到AS项目(Android14 SDK=33),并实现图形渲染功能。


一、背景知识:GL2JNI的核心作用

GL2JNI(全称GL2 JNI Test)是AOSP中用于测试OpenGL ES 2.0接口的基础应用。它通过JNI(Java Native Interface)桥接Java层与C++层,调用底层图形API完成渲染逻辑。其核心功能包括:

  • 初始化OpenGL上下文;
  • 绘制带颜色渐变的三角形;
  • 验证GPU对OpenGL ES 2.0的支持能力。

在AOSP中,GL2JNI的源码位于frameworks/native/opengl/tests/gl2_jni目录,包含Java层逻辑(GL2JNIActivity、GL2JNILib)和C++层渲染代码(gl_code.cpp)。我们的目标是将这些代码迁移到Android Studio项目中,并实现相同效果。

AOSP原生GL2JNI目录为frameworks/native/opengl/tests/gl2_jni

c 复制代码
gl2_jni/
├── src/
│   ├── com.android.gl2jni/
│   │   ├── GL2JNIActivity.java         
│   │   ├── GL2JNILib.java      
│   │   └── GL2JNIView.java  
├── jni/
│   ├── gl_code.cpp
├── res/
│   ├── string,xml
├── Android.bp        
└── AndroidManifest.xml        

二、环境准备与项目初始化

1. 创建Android Studio项目

新建一个​​Empty Activity​ ​ C++项目,包名保持与AOSP一致(com.android.gl2jni),确保后续JNI接口的兼容性。

2. 关键目录结构规划

最终项目需要以下核心目录:

bash 复制代码
app/
├── src/
│   ├── main/com.android.gl2jni/
│   │   ├── java/           # Java层代码(Activity、View)
│   │   ├── jniLibs/        # 存放不同ABI的SO库(arm64-v8a、armeabi-v7a等)
│   │   └── res/            # 资源文件(可选,本文未使用)
│   └── cpp/                # C++层代码(原gl_code.cpp)
│   │   └── CMakeLists.txt  # CMake构建脚本(链接OpenGL库) 
│   │   └── native-lib.cpp  # gl_code.cpp复制的内容
└── build.gradle            # Gradle配置(指定SO库路径)

三、Java层代码迁移与调整

1. 复制AOSP的Java代码

从AOSP的frameworks/native/opengl/tests/gl2_jni/src目录复制以下文件到AS项目的src/main/java/com/android/gl2jni目录:

  • GL2JNIActivity.java(主Activity)
  • GL2JNILib.java(JNI接口封装类)
  • GL2JNIView.java(自定义View,用于承载OpenGL渲染)

2. 修改启动Activity

AOSP中默认启动的是MainActivity,需在AndroidManifest.xml中将启动Activity改为GL2JNIActivity:

xml 复制代码
xml
复制
<application
    ...>
    <activity android:name=".GL2JNIActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

四、JNI接口适配:从对象到类的调用

1. JNI接口的变化

AOSP中的JNI接口定义在GL2JNILib.java中,通过native方法声明:

arduino 复制代码
java
复制
public class GL2JNILib {
    static {
        System.loadLibrary("gl2jni");
    }
    public native void init(int width, int height);
    public native void step();
}

但在AS项目中,由于JNI接口需与C++函数签名严格匹配,需注意以下两点:

  • ​参数类型调整​ :Java的jobject(对象引用)在C++中需改为jclass(类引用),因为静态方法通过类调用。
  • ​函数签名修正​ :AOSP的JNI接口最初设计为静态方法(static),但实际调用时需通过类名而非对象实例。

2. 修改C++接口声明

将AOSP的gl_code.cpp中的全部内容复制到AS C++项目自动创建的native-lib.cpp中,然后将JNI函数签名调整为适配AS项目的形式:

arduino 复制代码
cpp
// 原AOSP接口(对象引用)
extern "C" {
    JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height);
    JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj);
};

// 修改后(类引用)
extern "C" {
    JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jclass clazz, jint width, jint height);
    JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jclass clazz);
};

五、CMake配置:链接OpenGL库

1. 编写CMakeLists.txt

AS项目通过CMake构建原生代码,需在app目录下创建CMakeLists.txt,并添加以下内容:

scss 复制代码
cmake
复制
cmake_minimum_required(VERSION 3.18.1)
project("gl2jni")

# 查找OpenGL ES 2.0库(GLESv2)
find_library(
    GLESv2_LIB
    GLESv2
)

# 目标库配置(libgl2jni.so)
add_library(
    gl2jni
    SHARED
    native-lib.cpp  # 自动创建的   并且是gl_code.cpp的内容
)

# 链接系统库(Android运行时、EGL、GLESv2、日志)
target_link_libraries(
    gl2jni
    android
    GLESv2_LIB
    EGL
    log
    atomic
)

2. 关键参数说明

  • find_library:定位系统提供的OpenGL ES 2.0库(GLESv2)。
  • target_link_libraries:将gl2jni库与系统库链接,确保OpenGL API可用。

六、SO库打包:适配多ABI

1. 准备SO文件

AOSP编译后会生成libgl2jni.so(位于out/target/product/<设备名>/system/lib/或lib64/)。需将该文件复制 到AS项目的app/src/main/jniLibs目录下(没有jniLibs手动创建一个package),并按ABI分类,创建下面的目录格式:

css 复制代码
app/src/main/
└── jniLibs/
    ├── arm64-v8a/
    │   └── libgl2jni.so
    ├── armeabi-v7a/
    │   └── libgl2jni.so
    ├── x86/
    │   └── libgl2jni.so
    └── x86_64/
        └── libgl2jni.so

2. 配置Gradle识别SO库

在app/build.gradle中添加以下配置,告知Gradle将jniLibs目录下的SO文件打包到APK中:

ini 复制代码
groovy
复制
android {
    ...
    sourceSets {
        main {
            jniLibs.srcDirs = ['src/main/jniLibs']  # 指定SO库路径
        }
    }
}

七、构建与运行验证

1. 同步项目

点击Android Studio的Sync Project with Gradle Files按钮,确保CMake和Gradle配置生效。

2. 运行应用

选择一台支持OpenGL ES 2.0的设备(或模拟器),运行应用。若看到一个​​渐变绿色的三角形​​,则说明渲染成功。


最后如果喜欢这篇文章的话,还请点个赞多多支持!

如果存在任何问题欢迎评论区或者私信,感谢各位大佬的阅读!

相关推荐
千里马学框架3 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc3 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone3 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen3 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone3 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui