# Android View武器库
**Repository Path**: toolfox/android-view-utils
## Basic Information
- **Project Name**: Android View武器库
- **Description**: Android平台的View控件集合
- **Primary Language**: Android
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-06-25
- **Last Updated**: 2025-07-08
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# EGLSurfaceView
EGLSurfaceView 是一个专为 Android 平台设计的轻量级 OpenGL ES 渲染视图。它提供了一个简单的接口,用于在 Android 应用中进行 EGL 初始化、渲染和资源管理。
## 演示效果
## 特性
- 支持 EGL 初始化与销毁
- 支持设置渲染模式(连续渲染或按需渲染)
- 提供线程安全的渲染机制
- 简单易用的接口设计,方便快速集成到 Android 项目中
- 提供示例渲染器,便于学习与使用
## 构成
项目主要分为以下部分:
- **Java 层**:定义了 EGLSurfaceView 类和渲染器接口,负责与 Android SDK 交互。
- **C++ 层**:实现了 EGL 的具体逻辑,包括显示初始化、上下文创建、表面管理、渲染线程等。
- **构建文件**:支持使用 CMake 或 Android.mk 构建。
## 快速开始
### 1. 在 Android 项目中集成
确保你已将 `EGLSurfaceView` 作为模块引入到你的 Android 项目中。你可以通过以下方式集成:
- 将项目作为子模块添加到你的 Git 仓库
- 直接复制 `library` 模块到你的项目中
### 2. 在布局中使用
在你的 XML 布局文件中添加 `EGLSurfaceView`:
```xml
```
### 3. 在 Activity 中设置渲染器
在你的 `Activity` 中初始化 `EGLSurfaceView` 并设置渲染器:
```java
public class MainActivity extends AppCompatActivity {
private EGLSurfaceView eglSurfaceView;
private CppGLRendererSample renderer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化EGLSurfaceView
eglSurfaceView = findViewById(R.id.egl_surface_view);
renderer = new CppGLRendererSample();
// 设置渲染器
eglSurfaceView.setRenderer(renderer.getNativePtr());
// 设置渲染模式为连续渲染
eglSurfaceView.setRenderMode(EGLSurfaceView.RENDERMODE_CONTINUOUSLY);
// 设置目标帧率为60FPS
eglSurfaceView.setTargetFPS(60);
// 添加Touch事件监听器
eglSurfaceView.addOnTouchListener(new EGLSurfaceView.OnTouchListener() {
@Override
public boolean onTouch(EGLSurfaceView view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i("Touch", "Touch DOWN at (" + event.getX() + ", " + event.getY() + ")");
break;
case MotionEvent.ACTION_MOVE:
Log.d("Touch", "Touch MOVE to (" + event.getX() + ", " + event.getY() + ")");
break;
case MotionEvent.ACTION_UP:
Log.i("Touch", "Touch UP at (" + event.getX() + ", " + event.getY() + ")");
break;
}
return true; // 表示事件已处理
}
});
// 示例:获取当前FPS
new Thread(() -> {
while (!isFinishing()) {
try {
Thread.sleep(1000);
float currentFPS = eglSurfaceView.getCurrentFPS();
Log.i("MainActivity", "SurfaceView FPS: " + currentFPS);
} catch (InterruptedException e) {
break;
}
}
}).start();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (renderer != null) {
renderer.onDestroy();
}
if (eglSurfaceView != null) {
eglSurfaceView.onPause();
}
}
@Override
protected void onResume() {
super.onResume();
if (eglSurfaceView != null) {
eglSurfaceView.onResume();
}
}
@Override
protected void onPause() {
super.onPause();
if (eglSurfaceView != null) {
eglSurfaceView.onPause();
}
}
}
```
## API 文档
### Java API
#### `EGLSurfaceView` 类
`EGLSurfaceView` 是一个继承自 `SurfaceView` 的自定义视图,用于进行 EGL 渲染。
##### 方法
- `setRenderer(long renderer)`:设置本地渲染器对象
- `setRenderMode(int mode)`:设置渲染模式(`RENDERMODE_CONTINUOUSLY` 或 `RENDERMODE_WHEN_DIRTY`)
- `getRenderMode()`:获取当前的渲染模式
- `requestRender()`:请求渲染
- `setTargetFPS(int targetFPS)`:设置目标帧率(0表示不限制帧率)
- `getCurrentFPS()`:获取当前帧率
- `addOnTouchListener(OnTouchListener listener)`:添加Touch事件监听器
- `removeOnTouchListener(OnTouchListener listener)`:移除Touch事件监听器
- `clearOnTouchListeners()`:清除所有Touch事件监听器
- `onResume()`:恢复渲染
- `onPause()`:暂停渲染
##### Touch事件接口
- `OnTouchListener`:Touch事件监听器接口
- `boolean onTouch(EGLSurfaceView view, MotionEvent event)`:Touch事件回调方法,返回true表示事件已处理
#### `Renderer` 接口
`Renderer` 是一个接口,用于实现渲染逻辑。示例渲染器为 `CppGLRendererSample`。
### EGLTextureView
`EGLTextureView` 是基于 `TextureView` 的 EGL 渲染视图,提供与 `EGLSurfaceView` 类似的功能,但支持变换、动画等操作。
#### 在布局中使用
在你的 XML 布局文件中添加 `EGLTextureView`:
```xml
```
#### 在 Activity 中设置渲染器
```java
public class MainActivity extends AppCompatActivity {
private EGLTextureView eglTextureView;
private CppGLRendererSample renderer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化EGLTextureView
eglTextureView = findViewById(R.id.egl_texture_view);
renderer = new CppGLRendererSample();
// 设置渲染器
eglTextureView.setRenderer(renderer.getNativePtr());
// 设置渲染模式为连续渲染
eglTextureView.setRenderMode(EGLTextureView.RENDERMODE_CONTINUOUSLY);
// 设置目标帧率为60FPS
eglTextureView.setTargetFPS(60);
// 添加Touch事件监听器
eglTextureView.addOnTouchListener(new EGLTextureView.OnTouchListener() {
@Override
public boolean onTouch(EGLTextureView view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i("Touch", "Touch DOWN at (" + event.getX() + ", " + event.getY() + ")");
break;
case MotionEvent.ACTION_MOVE:
Log.d("Touch", "Touch MOVE to (" + event.getX() + ", " + event.getY() + ")");
break;
case MotionEvent.ACTION_UP:
Log.i("Touch", "Touch UP at (" + event.getX() + ", " + event.getY() + ")");
break;
}
return true; // 表示事件已处理
}
});
// 示例:获取当前FPS
new Thread(() -> {
while (!isFinishing()) {
try {
Thread.sleep(1000);
float currentFPS = eglTextureView.getCurrentFPS();
Log.i("MainActivity", "TextureView FPS: " + currentFPS);
} catch (InterruptedException e) {
break;
}
}
}).start();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (renderer != null) {
renderer.onDestroy();
}
if (eglTextureView != null) {
eglTextureView.onPause();
}
}
@Override
protected void onResume() {
super.onResume();
if (eglTextureView != null) {
eglTextureView.onResume();
}
}
@Override
protected void onPause() {
super.onPause();
if (eglTextureView != null) {
eglTextureView.onPause();
}
}
}
```
#### Java API
##### 主要方法
- `setRenderer(long renderer)`:设置渲染器
- `setRenderMode(int renderMode)`:设置渲染模式(连续渲染或按需渲染)
- `getRenderMode()`:获取当前渲染模式
- `requestRender()`:请求渲染
- `setTargetFPS(int targetFPS)`:设置目标帧率(0表示不限制帧率)
- `getCurrentFPS()`:获取当前帧率
- `addOnTouchListener(OnTouchListener listener)`:添加Touch事件监听器
- `removeOnTouchListener(OnTouchListener listener)`:移除Touch事件监听器
- `clearOnTouchListeners()`:清除所有Touch事件监听器
- `onResume()`:恢复渲染
- `onPause()`:暂停渲染
##### Touch事件接口
- `OnTouchListener`:Touch事件监听器接口
- `boolean onTouch(EGLTextureView view, MotionEvent event)`:Touch事件回调方法,返回true表示事件已处理
##### 与EGLSurfaceView的区别
- **变换支持**:`EGLTextureView` 支持缩放、旋转、平移等变换操作
- **动画支持**:可以应用属性动画(如透明度、位置变化等)
- **合成性能**:在某些情况下可能有更好的合成性能
- **内存使用**:相比 `SurfaceView` 可能使用更多内存
- **渲染目标**:使用 `SurfaceTexture` 而不是直接的 `Surface`
#### 变换和动画示例
`EGLTextureView` 支持标准的 View 变换操作:
```java
// 缩放
eglTextureView.setScaleX(1.5f);
eglTextureView.setScaleY(1.5f);
// 旋转
eglTextureView.setRotation(45f);
// 平移
eglTextureView.setTranslationX(100f);
eglTextureView.setTranslationY(100f);
// 透明度
eglTextureView.setAlpha(0.8f);
// 属性动画
ObjectAnimator rotationAnimator = ObjectAnimator.ofFloat(eglTextureView, "rotation", 0f, 360f);
rotationAnimator.setDuration(2000);
rotationAnimator.setRepeatCount(ObjectAnimator.INFINITE);
rotationAnimator.start();
```
## EGLSurfaceView vs EGLTextureView 选择指南
### 何时使用 EGLSurfaceView
**推荐场景:**
- 游戏开发或高性能图形应用
- 需要最佳渲染性能的场景
- 全屏或大部分屏幕的渲染内容
- 不需要复杂UI变换的应用
**优势:**
- 更好的渲染性能
- 更低的内存使用
- 硬件加速支持更好
- 适合高帧率渲染
**限制:**
- 不支持View变换(缩放、旋转、平移)
- 不支持属性动画
- 在某些布局中可能有Z-order问题
### 何时使用 EGLTextureView
**推荐场景:**
- 需要应用View变换的场景
- 需要属性动画效果
- 复杂UI布局中的嵌入式渲染
- 需要与其他View进行复杂交互
**优势:**
- 支持所有标准View变换
- 支持属性动画
- 更好的UI集成
- 更灵活的布局选项
**限制:**
- 相对较高的内存使用
- 可能的性能开销
- 在某些设备上可能有兼容性问题
### 性能对比
| 特性 | EGLSurfaceView | EGLTextureView |
|------|----------------|----------------|
| 渲染性能 | 优秀 | 良好 |
| 内存使用 | 低 | 中等 |
| 变换支持 | 无 | 完整 |
| 动画支持 | 无 | 完整 |
| UI集成 | 基础 | 优秀 |
| 兼容性 | 优秀 | 良好 |
### C++ API
#### `EGLSurfaceView` 类
`EGLSurfaceView` 是一个 C++ 类,负责 EGL 的初始化、销毁、渲染管理。
##### 方法
- `setRenderer(std::shared_ptr)`:设置渲染器
- `setRenderMode(RenderMode)`:设置渲染模式(连续渲染或按需渲染)
- `requestRender()`:请求渲染
- `setTargetFPS(int targetFPS)`:设置目标帧率(0表示不限制帧率)
- `getCurrentFPS()`:获取当前帧率
- `surfaceCreated(ANativeWindow*)`:创建 EGL 表面
- `surfaceChanged(int width, int height)`:调整视图尺寸
- `surfaceDestroyed()`:销毁 EGL 表面
- `pause()`:暂停渲染线程
- `resume()`:恢复渲染线程
- `initEGL()`:初始化 EGL
- `createEGLSurface()`:创建 EGL 渲染表面
- `destroyEGLSurface()`:销毁 EGL 渲染表面
- `renderThreadFunc()`:渲染线程的主函数
- `doRender()`:执行一帧的渲染
## 示例渲染器
示例渲染器 `CppGLRendererSample` 是一个简单的 OpenGL ES 渲染器,用于演示如何使用 EGLSurfaceView。
### 使用示例渲染器
`CppGLRendererSample` 提供了基本的 OpenGL 初始化、着色器编译与渲染逻辑。你可以通过继承此类或使用其方法来构建你自己的渲染器。
## 构建说明
### 使用 CMake 构建
确保你已配置 `CMakeLists.txt` 文件,并正确设置所有依赖项。使用以下命令进行构建:
```bash
cmake .
make
```
### 使用 Android.mk 构建
你也可以使用 `Android.mk` 构建项目:
```bash
ndk-build -C jni
```
## 依赖库
- Android NDK
- OpenGL ES 2.0 或以上
- C++ STL 支持
## 注意事项
- 确保在主线程中创建 EGLSurfaceView
- 在 Activity 的生命周期中正确调用 `onResume()` 和 `onPause()`
- 使用 `requestRender()` 时确保渲染模式为 `RENDERMODE_WHEN_DIRTY`
## 性能优化建议
- 尽量减少频繁的 `requestRender()` 调用
- 合理管理 OpenGL 资源的创建与销毁
- 避免在渲染线程中执行耗时操作
## 故障排除
### 常见问题
1. **EGL 初始化失败**:请检查设备是否支持 OpenGL ES 2.0 或以上版本
2. **渲染线程卡死**:确保没有阻塞渲染线程的操作
3. **Surface 创建失败**:请检查 `ANativeWindow` 是否有效
### 调试技巧
- 使用 `checkEGLError()` 检查 EGL 错误
- 使用 `checkShaderCompileStatus()` 和 `checkProgramLinkStatus()` 检查着色器编译与链接状态
- 使用日志记录关键函数的调用流程
## 许可证
本项目基于 [MIT License](LICENSE) 开源。
## 贡献
欢迎贡献代码!请提交 PR 或 Issue 到项目仓库。