Java开发Android App后台恢复时无法打开相机且闪退求助
问题原因
- 第一个空指针异常:
MultiBoxTracker实例在App切后台时被置空释放,从后台恢复时onRestart生命周期的执行顺序早于onResume,你当前的初始化逻辑仅在onResume中执行,导致onRestart调用trackResults时MultiBoxTracker还未完成初始化。 - 第二个空指针异常:相机属于系统独占资源,App退到后台时系统会回收相机权限,你在
onPause/onStop中释放了Camera实例,但onResume中没有补充相机重新打开、初始化的逻辑,调用startPreview时Camera对象为空。 - 现有
onResume逻辑不完整,仅初始化了推理线程,没有覆盖人脸识别依赖的追踪器、相机实例的初始化逻辑,生命周期回调顺序和资源初始化时机不匹配。
解决方案
- 调整
MultiBoxTracker初始化时机,在onRestart调用相关方法前完成初始化,同时增加空校验:
@Override protected void onRestart() { super.onRestart(); // 先初始化追踪器再执行业务逻辑 if (multiBoxTracker == null) { multiBoxTracker = new MultiBoxTracker(this); } // 原有updateResults调用逻辑放在初始化之后 } // 同时在updateResults方法入口增加空校验,避免偶发空指针 private void updateResults(List<Recognition> results, long timestamp) { if (multiBoxTracker == null) return; multiBoxTracker.trackResults(results, timestamp); }
- 补全
onResume中的相机初始化逻辑,确保每次从后台恢复时相机实例正常创建:
@Override public synchronized void onResume() { super.onResume(); // 原有推理线程初始化逻辑 handlerThread = new HandlerThread("inference"); handlerThread.start(); handler = new Handler(handlerThread.getLooper()); // 新增相机初始化逻辑 if (mCamera == null) { try { // 可根据需求传入指定cameraId打开前置/后置相机 mCamera = Camera.open(); Camera.Parameters params = mCamera.getParameters(); // 配置预览尺寸、对焦模式等业务需要的参数 mCamera.setParameters(params); // 绑定布局中SurfaceView的SurfaceHolder mCamera.setPreviewDisplay(surfaceView.getHolder()); mCamera.startPreview(); } catch (Exception e) { e.printStackTrace(); // 补充相机打开失败的异常处理,如权限提示、错误弹窗 } } }
- 规范
onPause阶段的资源释放逻辑,避免内存泄漏和相机资源占用:
@Override protected void onPause() { super.onPause(); // 释放推理线程 handlerThread.quitSafely(); try { handlerThread.join(); handlerThread = null; handler = null; } catch (InterruptedException e) { e.printStackTrace(); } // 释放相机资源 if (mCamera != null) { mCamera.stopPreview(); mCamera.release(); mCamera = null; } // 释放追踪器 multiBoxTracker = null; }
- 所有调用
Camera.startPreview()的位置提前做空校验,避免偶发异常:
if (mCamera != null) { mCamera.startPreview(); }
内容的提问来源于stack exchange,提问作者Kevin Seab
相关产品推荐
相关产品推荐

