EGL--键盘类头文件 KEY.H

此博客展示了KEY.H代码,由王家宝编写,最后更新于2000.04.01。代码用途是获取键盘输入,对一般字符键与特殊按键加以识别,定义了各类按键的宏,还声明了获取按键、状态键等相关函数。

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

/*
 KEY.H
 代码编写: 王家宝
 最后更新日期: 2000.04.01

 用途: 获取键盘输入,对一般字符键与特殊按键加以识别
*/

#define BACKSPACE  8
#define TAB  9
#define ENTER   13
#define ESC   27
#define UP   7200
#define DOWN   8000
#define LEFT   7500
#define RIGHT   7700
#define HOME   7100
#define END   7900
#define INS   8200
#define DEL   8300
#define PGUP   7300
#define PGDN   8100
#define F1   5900
#define F2   6000
#define F3   6100
#define F4   6200
#define F5   6300
#define F6   6400
#define F7   6500
#define F8   6600
#define F9   6700
#define F10   6800
#define F11   13300
#define F12   13400

#define R_SHIFT  0x01
#define L_SHIFT  0x02
#define CTRL  0x04
#define ALT  0x08

int GetKey();
int GetStatusKey(int cmd);
int KbHit();
void ClearKeyBuffer(void);

Process pipe failed 2025-06-05 21:00:33.745 22340-22371 ConfigStore com.example.diaryapp I android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0 2025-06-05 21:00:33.745 22340-22371 ConfigStore com.example.diaryapp I android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0 2025-06-05 21:00:33.745 22340-22371 OpenGLRenderer com.example.diaryapp I Initialized EGL, version 1.4 2025-06-05 21:00:33.745 22340-22371 OpenGLRenderer com.example.diaryapp D Swap behavior 1 2025-06-05 21:00:33.746 22340-22371 EGL_adreno com.example.diaryapp E CreateContext rcMajorVersion:3, minorVersion:2 2025-06-05 21:00:33.754 22340-22371 EGL_adreno com.example.diaryapp D eglCreateContext: 0x7f2e2da30120: maj 3 min 2 rcv 3 2025-06-05 21:00:33.754 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:00:33.754 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:00:33.781 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:00:33.781 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:00:33.782 22340-22371 vndksupport com.example.diaryapp D Loading /vendor/lib64/hw/android.hardware.graphics.mapper@2.0-impl.so from current namespace instead of sphal namespace. 2025-06-05 21:00:33.782 22340-22371 vndksupport com.example.diaryapp D Loading /vendor/lib64/hw/gralloc.gmin.so from current namespace instead of sphal namespace. 2025-06-05 21:00:33.786 22340-22371 EGL_adreno com.example.diaryapp E tid 22371: eglSurfaceAttrib(1615): error 0x3009 (EGL_BAD_MATCH) 2025-06-05 21:00:33.786 22340-22371 OpenGLRenderer com.example.diaryapp W Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f2e2da27e00, error=EGL_BAD_MATCH 2025-06-05 21:00:34.214 22340-22340 xample.diaryap com.example.diaryapp W Accessing hidden method Landroid/os/Trace;->asyncTraceBegin(JLjava/lang/String;I)V (light greylist, reflection) 2025-06-05 21:00:34.214 22340-22340 xample.diaryap com.example.diaryapp W Accessing hidden method Landroid/os/Trace;->asyncTraceEnd(JLjava/lang/String;I)V (light greylist, reflection) 2025-06-05 21:00:34.214 22340-22340 xample.diaryap com.example.diaryapp W Accessing hidden method Landroid/os/Trace;->traceCounter(JLjava/lang/String;I)V (light greylist, reflection) 2025-06-05 21:00:39.439 22340-22401 ProfileInstaller com.example.diaryapp D Installing profile for com.example.diaryapp 2025-06-05 21:00:40.016 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:00:40.016 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:00:40.023 22340-22371 EGL_adreno com.example.diaryapp E tid 22371: eglSurfaceAttrib(1615): error 0x3009 (EGL_BAD_MATCH) 2025-06-05 21:00:40.023 22340-22371 OpenGLRenderer com.example.diaryapp W Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f2e2db3cb80, error=EGL_BAD_MATCH 2025-06-05 21:00:40.026 22340-22340 ActivityThread com.example.diaryapp W handleWindowVisibility: no activity for token android.os.BinderProxy@b266666 2025-06-05 21:00:40.267 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:00:40.267 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:00:40.283 22340-22371 EGL_adreno com.example.diaryapp E tid 22371: eglSurfaceAttrib(1615): error 0x3009 (EGL_BAD_MATCH) 2025-06-05 21:00:40.283 22340-22371 OpenGLRenderer com.example.diaryapp W Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f2e2db3cc80, error=EGL_BAD_MATCH 2025-06-05 21:00:40.292 22340-22340 Glide com.example.diaryapp W Failed to find GeneratedAppGlideModule. You should include an annotationProcessor compile dependency on com.github.bumptech.glide:compiler in your application and a @GlideModule annotated AppGlideModule implementation or LibraryGlideModules will be silently ignored 2025-06-05 21:00:42.727 22340-22340 ActivityThread com.example.diaryapp W handleWindowVisibility: no activity for token android.os.BinderProxy@7575cb3 2025-06-05 21:00:42.763 22340-22345 xample.diaryap com.example.diaryapp I Compiler allocated 4MB to compile void android.widget.TextView.<init>(android.content.Context, android.util.AttributeSet, int, int) 2025-06-05 21:00:42.780 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:00:42.780 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:00:42.794 22340-22371 EGL_adreno com.example.diaryapp E tid 22371: eglSurfaceAttrib(1615): error 0x3009 (EGL_BAD_MATCH) 2025-06-05 21:00:42.794 22340-22371 OpenGLRenderer com.example.diaryapp W Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f2e2dbdb280, error=EGL_BAD_MATCH 2025-06-05 21:00:50.659 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:00:50.659 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:00:50.673 22340-22340 xample.diaryap com.example.diaryapp W Accessing hidden field Landroid/view/View;->mAccessibilityDelegate:Landroid/view/View$AccessibilityDelegate; (light greylist, reflection) 2025-06-05 21:00:50.675 22340-22371 EGL_adreno com.example.diaryapp E tid 22371: eglSurfaceAttrib(1615): error 0x3009 (EGL_BAD_MATCH) 2025-06-05 21:00:50.675 22340-22371 OpenGLRenderer com.example.diaryapp W Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f2e2dbdb300, error=EGL_BAD_MATCH 2025-06-05 21:00:52.086 22340-22340 ActivityThread com.example.diaryapp W handleWindowVisibility: no activity for token android.os.BinderProxy@d5d171c 2025-06-05 21:00:52.186 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:00:52.186 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:00:52.204 22340-22371 EGL_adreno com.example.diaryapp E tid 22371: eglSurfaceAttrib(1615): error 0x3009 (EGL_BAD_MATCH) 2025-06-05 21:00:52.204 22340-22371 OpenGLRenderer com.example.diaryapp W Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f2e1d0afd00, error=EGL_BAD_MATCH 2025-06-05 21:00:53.766 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:00:53.766 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:00:53.776 22340-22371 EGL_adreno com.example.diaryapp E tid 22371: eglSurfaceAttrib(1615): error 0x3009 (EGL_BAD_MATCH) 2025-06-05 21:00:53.776 22340-22371 OpenGLRenderer com.example.diaryapp W Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f2e1d337180, error=EGL_BAD_MATCH 2025-06-05 21:00:58.199 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:00:58.199 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:00:58.220 22340-22371 EGL_adreno com.example.diaryapp E tid 22371: eglSurfaceAttrib(1615): error 0x3009 (EGL_BAD_MATCH) 2025-06-05 21:00:58.220 22340-22371 OpenGLRenderer com.example.diaryapp W Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f2e2dbdb300, error=EGL_BAD_MATCH 2025-06-05 21:01:01.788 22340-22340 ActivityThread com.example.diaryapp W handleWindowVisibility: no activity for token android.os.BinderProxy@bf7a046 2025-06-05 21:01:01.863 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:01:01.863 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:01:01.880 22340-22371 EGL_adreno com.example.diaryapp E tid 22371: eglSurfaceAttrib(1615): error 0x3009 (EGL_BAD_MATCH) 2025-06-05 21:01:01.880 22340-22371 OpenGLRenderer com.example.diaryapp W Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f2e1d222f00, error=EGL_BAD_MATCH 2025-06-05 21:01:04.247 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:01:04.247 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:01:04.268 22340-22371 EGL_adreno com.example.diaryapp E tid 22371: eglSurfaceAttrib(1615): error 0x3009 (EGL_BAD_MATCH) 2025-06-05 21:01:04.268 22340-22371 OpenGLRenderer com.example.diaryapp W Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f2e2dbdb300, error=EGL_BAD_MATCH 2025-06-05 21:01:06.508 22340-22340 ActivityThread com.example.diaryapp W handleWindowVisibility: no activity for token android.os.BinderProxy@58e8cd8 2025-06-05 21:01:06.613 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:01:06.613 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:01:06.633 22340-22371 EGL_adreno com.example.diaryapp E tid 22371: eglSurfaceAttrib(1615): error 0x3009 (EGL_BAD_MATCH) 2025-06-05 21:01:06.633 22340-22371 OpenGLRenderer com.example.diaryapp W Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f2e1d222f00, error=EGL_BAD_MATCH 2025-06-05 21:01:07.985 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:01:07.985 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:01:07.993 22340-22371 EGL_adreno com.example.diaryapp E tid 22371: eglSurfaceAttrib(1615): error 0x3009 (EGL_BAD_MATCH) 2025-06-05 21:01:07.993 22340-22371 OpenGLRenderer com.example.diaryapp W Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f2e2db3c000, error=EGL_BAD_MATCH 2025-06-05 21:01:07.996 22340-22340 ActivityThread com.example.diaryapp W handleWindowVisibility: no activity for token android.os.BinderProxy@d24a3e0 2025-06-05 21:01:08.020 22340-22349 System com.example.diaryapp W A resource failed to call close. 2025-06-05 21:01:08.021 22340-22349 chatty com.example.diaryapp I uid=10062(com.example.diaryapp) FinalizerDaemon identical 2 lines 2025-06-05 21:01:08.021 22340-22349 System com.example.diaryapp W A resource failed to call close. 2025-06-05 21:01:08.038 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:01:08.038 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:01:08.057 22340-22371 EGL_adreno com.example.diaryapp E tid 22371: eglSurfaceAttrib(1615): error 0x3009 (EGL_BAD_MATCH) 2025-06-05 21:01:08.057 22340-22371 OpenGLRenderer com.example.diaryapp W Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f2e2c09d580, error=EGL_BAD_MATCH 2025-06-05 21:01:09.873 22340-22340 ActivityThread com.example.diaryapp W handleWindowVisibility: no activity for token android.os.BinderProxy@4e83cf6 2025-06-05 21:01:09.914 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:01:09.914 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:01:09.934 22340-22371 EGL_adreno com.example.diaryapp E tid 22371: eglSurfaceAttrib(1615): error 0x3009 (EGL_BAD_MATCH) 2025-06-05 21:01:09.934 22340-22371 OpenGLRenderer com.example.diaryapp W Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f2e1d9c8580, error=EGL_BAD_MATCH 2025-06-05 21:01:11.614 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:01:11.614 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:01:11.629 22340-22371 EGL_adreno com.example.diaryapp E tid 22371: eglSurfaceAttrib(1615): error 0x3009 (EGL_BAD_MATCH) 2025-06-05 21:01:11.629 22340-22371 OpenGLRenderer com.example.diaryapp W Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f2e1d95f280, error=EGL_BAD_MATCH 2025-06-05 21:01:13.193 22340-22371 OpenGLRenderer com.example.diaryapp D endAllActiveAnimators on 0x7f2e1d16d900 (RippleDrawable) with handle 0x7f2e2db44560 2025-06-05 21:01:13.213 22340-22371 EGL_adreno com.example.diaryapp E [getAttribValue] Bad attribute idx 2025-06-05 21:01:13.213 22340-22371 EGL_adreno com.example.diaryapp D eglGetConfigAttrib: bad attrib 0x3339 2025-06-05 21:01:13.231 22340-22371 EGL_adreno com.example.diaryapp E tid 22371: eglSurfaceAttrib(1615): error 0x3009 (EGL_BAD_MATCH) 2025-06-05 21:01:13.231 22340-22371 OpenGLRenderer com.example.diaryapp W Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f2e2db3c680, error=EGL_BAD_MATCH
最新发布
06-06
<think>我们分析日志发现几个关键问题:1.EGL_BAD_MATCH错误频繁出现,尤其是在设置EGL_SWAP_BEHAVIOR时。2.主线程跳帧(Skipped32frames)的警告,表明UI线程负担过重。3.Glide配置缺失的警告。4.资源未能正确关闭(Aresourcefailedtocallclose)。针对这些问题,我们采取以下措施:###1.解决EGL_BAD_MATCH错误这个错误通常与EGL配置和Surface设置有关。我们尝试以下方法:-禁用硬件加速:在某些设备上,硬件加速可能导致问题,我们可以尝试在Activity或Application级别禁用硬件加速。-更新OpenGL渲染代码:确保在创建EGLContext时使用正确的配置,并避免设置不受支持的属性。###2.主线程跳帧优化-将耗时的操作(如数据库访问、网络请求、图片处理)移至后台线程。-使用AsyncTask、HandlerThread、ExecutorService或协程(Kotlin)来执行后台任务。###3.Glide配置按照Glide的要求添加AppGlideModule。###4.资源关闭确保所有打开的Cursor、数据库连接、文件流等在使用完毕后关闭。##解决方案###1.禁用硬件加速(针对特定View或Activity)在AndroidManifest.xml中为Activity禁用硬件加速:```xml<activityandroid:name=".YourActivity"android:hardwareAccelerated="false"/>```或者在View级别禁用:```javapublicclassCustomViewextendsView{publicCustomView(Contextcontext){super(context);setLayerType(View.LAYER_TYPE_SOFTWARE,null);}}```###2.使用AsyncTask处理数据库操作(优化主线程)例如,在加载日记列表时:```javapublicclassLoadDiariesTaskextendsAsyncTask<Integer,Void,List<Diary>>{privateWeakReference<Context>contextRef;privateDatabaseHelperdbHelper;publicLoadDiariesTask(Contextcontext){this.contextRef=newWeakReference<>(context);this.dbHelper=newDatabaseHelper(context);}@OverrideprotectedList<Diary>doInBackground(Integer...userIds){returndbHelper.getDiariesByUserId(userIds[0]);}@OverrideprotectedvoidonPostExecute(List<Diary>diaries){Contextcontext=contextRef.get();if(contextinstanceofActivity&&!((Activity)context).isFinishing()){//更新UIDiaryListActivityactivity=(DiaryListActivity)context;activity.updateDiaryList(diaries);}//关闭数据库dbHelper.close();}}```在Activity中启动任务:```javanewLoadDiariesTask(this).execute(userId);```###3.配置Glide模块添加一个AppGlideModule:```javaimportcom.bumptech.glide.annotation.GlideModule;importcom.bumptech.glide.module.AppGlideModule;@GlideModulepublicclassMyAppGlideModuleextendsAppGlideModule{//默认空实现即可}```在app/build.gradle中添加依赖:```groovydependencies{implementation'com.github.bumptech.glide:glide:4.12.0'annotationProcessor'com.github.bumptech.glide:compiler:4.12.0'}```###4.资源关闭管理确保在finally块中关闭所有资源:```javaCursorcursor=null;try{cursor=db.query(...);//...}finally{if(cursor!=null){cursor.close();}}```对于数据库连接,在不需要时关闭。特别是每次调用getReadableDatabase或getWritableDatabase后,在finally块中关闭数据库(注意:同一个实例多次调用getWritableDatabase并不会创建多个连接,所以需要根据情况在不再需要时关闭)。##详细优化代码示例###优化资源关闭的DatabaseHelper方法以getDiariesByUserId为例:```javapublicList<Diary>getDiariesByUserId(intuserId){List<Diary>diaries=newArrayList<>();SQLiteDatabasedb=null;Cursorcursor=null;try{db=this.getReadableDatabase();cursor=db.rawQuery("SELECT*FROM"+TABLE_DIARY+"WHERE"+COLUMN_DIARY_USER_ID+"=?ORDERBY"+COLUMN_DIARY_DATE+"DESC",newString[]{String.valueOf(userId)});while(cursor.moveToNext()){Diarydiary=extractDiaryFromCursor(cursor);diaries.add(diary);}}catch(Exceptione){Log.e("DB","Errorgettingdiaries",e);}finally{if(cursor!=null)cursor.close();if(db!=null)db.close();//注意:实际应用中,如果频繁操作数据库,不建议每次都关闭,因为打开和关闭开销大。可以使用一个数据库连接,并在应用生命周期中管理。或者使用单例模式管理DatabaseHelper。}returndiaries;}```注意:每次操作都打开和关闭数据库连接可能会影响性能,所以对于频繁的数据库操作,建议保持数据库连接打开,并在合适的时机(例如Activity的onDestroy)关闭整个DatabaseHelper。###关于主线程优化除了使用AsyncTask,还可以考虑使用Loader(特别是结合Room数据库)或者ViewModel和LiveData(架构组件)来异步加载数据。##结论通过禁用硬件加速、异步处理数据库操作、正确配置Glide以及确保资源关闭,应该能解决日志中的大部分问题。§§相关问题§§:1.在Android中,除了AsyncTask,还有哪些方式可以在后台线程执行任务?2.如何全局管理SQLiteDatabase连接以避免频繁打开和关闭?3.Glide的磁盘缓存策略有哪些,如何配置?4.如何检测Android应用中的内存泄漏?</think> ### 诊断与解决方案分析 日志显示您的Android应用存在严重的渲染管线问题(EGL_BAD_MATCH错误),资源泄漏和UI性能问题。主要问题集中在三个领域: 1. **OpenGL渲染管线错误**("Process pipe failed" 和 "Failed to set EGL_SWAP_BEHAVIOR") 表明图形渲染系统出现兼容性问题 在多个EGL表面设置操作中反复出现EGL_BAD_MATCH错误 2. **资源泄漏问题**("A resource failed to call close") 文件描述符或资源未正确释放导致内存泄漏 3. **UI性能问题**(硬件加速配置问题) "Accessing hidden method" 警告表明使用了私有API Glide配置缺失导致图片加载效率低下 --- ### 完整的优化解决方案 #### 1. OpenGL渲染管线修复 ```java // 创建兼容性渲染器 public class SafeGLRenderer implements GLSurfaceView.Renderer { private final static String TAG = "SafeGLRenderer"; @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // 设置安全的默认值 gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.glDisable(GL10.GL_DITHER); gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); // 禁用可能引发问题的扩展 if (gl instanceof GL11ExtensionPack) { ((GL11ExtensionPack)gl).glDisable(GL11ExtensionPack.GL_DEBUG_OUTPUT_SYNCHRONOUS); } } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { // 简化的视口设置 gl.glViewport(0, 0, width, height); } @Override public void onDrawFrame(GL10 gl) { // 最小化的渲染逻辑 gl.glClear(GL10.GL_COLOR_BUFFER_BIT); } } // 在Activity中使用 public class DiaryActivity extends AppCompatActivity { private GLSurfaceView glSurfaceView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 检查设备OpenGL ES版本 ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); ConfigurationInfo info = am.getDeviceConfigurationInfo(); final boolean supportsEs2 = info.reqGlEsVersion >= 0x20000; if (supportsEs2) { glSurfaceView = new GLSurfaceView(this); glSurfaceView.setEGLContextClientVersion(2); glSurfaceView.setRenderer(new SafeGLRenderer()); setContentView(glSurfaceView); } else { // 回退到软件渲染 Log.w(TAG, "Device does not support OpenGL ES 2.0, using software rendering"); setContentView(R.layout.activity_fallback); } } @Override protected void onPause() { super.onPause(); if (glSurfaceView != null) { glSurfaceView.onPause(); } } @Override protected void onResume() { super.onResume(); if (glSurfaceView != null) { glSurfaceView.onResume(); } } } ``` **优化点解释**: 1. **兼容性检查**:运行时检测设备OpenGL ES支持版本 2. **安全默认配置**: - 禁用GL_DITHER减少计算开销 - 关闭可能导致问题的扩展功能 3. **资源生命周期管理**: - 在onPause/onResume正确处理GLSurfaceView 4. **最小化渲染逻辑**: - 只进行必要的清屏操作 - 避免复杂的光照和材质处理 #### 2. 资源泄漏修复方案 ```java public class ResourceUtils { // 安全关闭资源的三级防护 public static void closeSilently(Closeable closeable) { if (closeable != null) { try { closeable.close(); } catch (IOException e) { Log.e("Resource", "Close failed", e); } } } // Cursor专用关闭方法 public static void closeCursor(Cursor cursor) { if (cursor != null && !cursor.isClosed()) { try { cursor.close(); } catch (Exception e) { Log.e("DB", "Cursor close failed", e); } } } // SQLiteDatabase专用关闭 public static void closeDatabase(SQLiteDatabase db) { if (db != null && db.isOpen()) { try { if (db.inTransaction()) db.endTransaction(); db.close(); } catch (Exception e) { Log.e("DB", "Database close failed", e); } } } } // 在DatabaseHelper中使用 public Cursor safeQuery(SQLiteDatabase db, String sql, String[] args) { Cursor cursor = null; try { cursor = db.rawQuery(sql, args); return cursor; } catch (Exception e) { ResourceUtils.closeCursor(cursor); // 异常时立即关闭 throw e; } } // 在Activity中管理资源 protected void onDestroy() { super.onDestroy(); cleanupResources(); } private void cleanupResources() { // 关闭所有可能泄漏的资源 ResourceUtils.closeCursor(currentCursor); ResourceUtils.closeDatabase(currentDb); closeOpenGLResources(); } private void closeOpenGLResources() { if (glSurfaceView != null) { glSurfaceView.queueEvent(() -> { GL10 gl = (GL10) EGLContext.getEGL().getGL(); // 手动删除纹理 int[] textures = new int[1]; gl.glDeleteTextures(1, textures, 0); // 删除缓冲区 int[] buffers = new int[1]; gl.glDeleteBuffers(1, buffers, 0); }); } } ``` **优化点解释**: 1. **三级关闭保护**: - 通用Closeable资源关闭 - Cursor专用关闭方法 - SQLiteDatabase专用关闭逻辑 2. **异常安全处理**: - 在异常处理中也确保资源释放 3. **生命周期管理**: - Activity销毁时的集中清理 4. **OpenGL资源管理**: - 手动删除纹理和缓冲区对象 - 防止GPU内存泄漏 #### 3. Glide配置与图片优化 ```java // Glide全局配置模块 @GlideModule public class DiaryGlideModule extends AppGlideModule { private static final int MAX_CACHE_SIZE = 100 * 1024 * 1024; // 100MB @Override public void applyOptions(Context context, GlideBuilder builder) { // 内存优化 builder.setDefaultRequestOptions( new RequestOptions() .format(DecodeFormat.PREFER_RGB_565) .disallowHardwareConfig() .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC) ); // 定制内存缓存 MemorySizeCalculator calculator = new MemorySizeCalculator.Builder(context) .setMemoryCacheScreens(2) .build(); builder.setMemoryCache(new LruResourceCache(calculator.getMemoryCacheSize())); // 磁盘缓存 builder.setDiskCache(new InternalCacheDiskCacheFactory(context, MAX_CACHE_SIZE)); // 后台线程优化 builder.setSourceExecutor(GlideExecutor.newSourceExecutor()); } } // 安全加载图片的方法 public static void safeLoadImage(Context context, String path, ImageView imageView) { // 添加硬件加速兼容性处理 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && imageView.isHardwareAccelerated()) { imageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } GlideApp.with(context) .load(path) .apply(new RequestOptions() .error(R.drawable.default_diary_image) .override(800, 600) // 控制尺寸 .signature(new MediaStoreSignature("image/jpeg", System.currentTimeMillis(), 0)) ) .transition(DrawableTransitionOptions.withCrossFade()) .into(imageView); } ``` **优化点解释**: 1. **全局配置**: - 限制内存缓存大小 - 使用RGB_565节省内存 - 禁用硬件加速配置避免冲突 2. **安全加载机制**: - 自动降级到软件渲染 - 尺寸控制保护低端设备 - 缓存签名防止错误显示 3. **错误处理**: - 提供默认错误图片 - 带淡入淡出效果的过渡动画 --- ### 深度性能优化建议 #### 1. 图形渲染性能检测工具 ```java // 在Debug版本中启用OpenGL跟踪 if (BuildConfig.DEBUG) { glSurfaceView.setDebugFlags( GLSurfaceView.DEBUG_LOG_GL_CALLS | GLSurfaceView.DEBUG_CHECK_GL_ERROR ); } // 创建帧率监视器 public class FrameRateMonitor implements GLSurfaceView.Renderer { private static final int REFRESH_RATE_MS = 1000; private long lastFrameTime = SystemClock.elapsedRealtime(); private int frameCount; private TextView fpsView; public FrameRateMonitor(TextView fpsView) { this.fpsView = fpsView; } @Override public void onDrawFrame(GL10 gl) { frameCount++; long now = SystemClock.elapsedRealtime(); if (now - lastFrameTime > REFRESH_RATE_MS) { final float fps = frameCount * 1000f / (now - lastFrameTime); fpsView.post(() -> fpsView.setText(String.format("%.1f fps", fps))); frameCount = 0; lastFrameTime = now; } } // 其他方法实现... } ``` #### 2. 内存泄漏检测强化 ```gradle dependencies { debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7' } ``` ```java public class DiaryApplication extends Application { @Override public void onCreate() { super.onCreate(); if (BuildConfig.DEBUG) { LeakCanary.Config config = LeakCanary.getConfig().newBuilder() .dumpHeapWhenDebugging(false) .build(); LeakCanary.setConfig(config); } } } ``` #### 3. 多线程渲染优化 ```java public class ParallelRenderThread extends Thread { private final BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<>(); private volatile boolean running = true; @Override public void run() { EGLContext sharedContext = null; // 从主渲染器获取 while (running) { try { Runnable task = taskQueue.take(); // 在共享上下文中执行 task.run(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } public void addTask(Runnable task) { if (running) { taskQueue.offer(task); } } public void shutdown() { running = false; interrupt(); } } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值