HarmonyOS鸿蒙Next中camera.PhotoSession.release()报错,无法释放
HarmonyOS鸿蒙Next中camera.PhotoSession.release()报错,无法释放
camera.PhotoSession.release()释放报错,
7400201 - Camera service fatal error.
完全按照官方建议的关闭相机操作,也关闭不了,造成第二次进来无法拍照,有没有大佬知道到底为啥啊!? 如何实现相机关闭-相机开发(Camera)-拍照和图片-媒体开发-开发 - 华为HarmonyOS开发者
更多关于HarmonyOS鸿蒙Next中camera.PhotoSession.release()报错,无法释放的实战教程也可以访问 https://www.itying.com/category-93-b0.html
可以参考 拉起相机预览图像失败,报错7400201
问题定位
- 搜索createPreviewOutput或者CameraOutputCapability,查看是否获取previewProfiles属性。
- 搜索日志中错误码7400201,查看是否存在分辨率不支持相关日志。
07-01 22:31:45.915 11445-11445 C02B01/com....hm/CAMERA com....hm E {IsPreconfigProfilesLegal():237} VideoSession::IsPreconfigProfilesLegal check video profile fail, no matched video profiles:1003 3840x2160
07-01 22:31:45.915 11445-11445 C02B01/com....hm/CAMERA com....hm E {Preconfig():295} VideoSession::Preconfig preconfigProfile is illegal.
07-01 22:31:45.915 11445-11445 A03D00/com....hm/JSAPP com....hm E initCamera fail: {"code":"7400201"}
更多关于HarmonyOS鸿蒙Next中camera.PhotoSession.release()报错,无法释放的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
✅ 正确的释放顺序(文档推荐)
async function releaseResources(): Promise<void> {
// 1. 停止当前会话(必须第一步)
await photoSession?.stop().catch((e: BusinessError) => {
console.error('停止会话失败:', e);
});
// 2. 释放相机输入流
await cameraInput?.close().catch((e: BusinessError) => {
console.error('关闭相机失败:', e);
});
// 3. 释放预览输出流
await previewOutput?.release().catch((e: BusinessError) => {
console.error('停止预览流失败:', e);
});
// 4. 释放拍照输出流
await photoOutput?.release().catch((e: BusinessError) => {
console.error('停止拍照流失败:', e);
});
// 5. 释放会话(必须最后一步)
await photoSession?.release().catch((e: BusinessError) => {
console.error('释放会话失败:', e);
});
}
🔴 常见错误做法
// 错误1:未先 stop() 就直接 release()
await photoSession.release(); // 会报 7400201
// 错误2:顺序错误,先释放 session 再释放 output
await photoSession.release();
await photoOutput.release(); // session 已释放,output 无法释放
// 错误3:未等待异步完成就执行下一步
photoSession.stop(); // 未 await
photoSession.release(); // stop 未完成就执行 release
完整解决方案
方案一:标准释放流程(推荐)
import { camera } from '[@kit](/user/kit).CameraKit';
import { BusinessError } from '[@kit](/user/kit).BasicServicesKit';
class CameraManager {
private photoSession: camera.PhotoSession | undefined;
private cameraInput: camera.CameraInput | undefined;
private previewOutput: camera.PreviewOutput | undefined;
private photoOutput: camera.PhotoOutput | undefined;
private isReleasing: boolean = false; // 防止重复释放
/**
* 安全释放相机资源
*/
async releaseCamera(): Promise<void> {
// 防止重复释放
if (this.isReleasing) {
console.warn('Camera is already releasing, skip this call');
return;
}
this.isReleasing = true;
try {
// 步骤 1: 停止会话(必须第一步)
if (this.photoSession) {
try {
console.info('Step 1: Stopping photo session...');
await this.photoSession.stop();
console.info('Photo session stopped successfully');
} catch (error) {
let err = error as BusinessError;
console.error(`Failed to stop session: ${err.code}, ${err.message}`);
// 即使 stop 失败也继续执行后续释放
}
}
// 步骤 2: 关闭相机输入
if (this.cameraInput) {
try {
console.info('Step 2: Closing camera input...');
await this.cameraInput.close();
console.info('Camera input closed successfully');
} catch (error) {
let err = error as BusinessError;
console.error(`Failed to close camera input: ${err.code}, ${err.message}`);
}
}
// 步骤 3: 释放预览输出
if (this.previewOutput) {
try {
console.info('Step 3: Releasing preview output...');
await this.previewOutput.release();
console.info('Preview output released successfully');
} catch (error) {
let err = error as BusinessError;
console.error(`Failed to release preview output: ${err.code}, ${err.message}`);
}
}
// 步骤 4: 释放拍照输出
if (this.photoOutput) {
try {
console.info('Step 4: Releasing photo output...');
await this.photoOutput.release();
console.info('Photo output released successfully');
} catch (error) {
let err = error as BusinessError;
console.error(`Failed to release photo output: ${err.code}, ${err.message}`);
}
}
// 步骤 5: 释放会话(必须最后)
if (this.photoSession) {
try {
console.info('Step 5: Releasing photo session...');
await this.photoSession.release();
console.info('Photo session released successfully');
} catch (error) {
let err = error as BusinessError;
console.error(`Failed to release session: ${err.code}, ${err.message}`);
// 如果仍然报 7400201,重置所有引用
if (err.code === 7400201) {
console.warn('Camera service error, force reset all references');
}
}
}
// 步骤 6: 清空所有引用
this.photoSession = undefined;
this.cameraInput = undefined;
this.previewOutput = undefined;
this.photoOutput = undefined;
console.info('All camera resources released successfully');
} finally {
this.isReleasing = false;
}
}
}
方案二:增加释放前检查(推荐)
/**
* 带状态检查的安全释放
*/
async function releaseSessionSafely(session: camera.PhotoSession | undefined): Promise<void> {
if (!session) {
console.warn('Session is undefined, skip release');
return;
}
try {
// 1. 先调用 stop()
console.info('Stopping session...');
await session.stop();
// 2. 等待一小段时间确保 stop 完成
await new Promise(resolve => setTimeout(resolve, 100));
// 3. 再调用 release()
console.info('Releasing session...');
await session.release();
console.info('Session released successfully');
} catch (error) {
let err = error as BusinessError;
if (err.code === 7400201) {
console.error('Camera service fatal error when releasing session');
console.error('This usually means:');
console.error('1. Session was not stopped before release');
console.error('2. Camera service crashed');
console.error('3. Resources were already released');
// 强制清理引用,下次重新创建
session = undefined;
} else {
console.error(`Release failed with error: ${err.code}, ${err.message}`);
}
throw error;
}
}
方案三:页面生命周期集成
import { camera } from '[@kit](/user/kit).CameraKit';
import { BusinessError } from '[@kit](/user/kit).BasicServicesKit';
@Entry
@Component
struct CameraPage {
private photoSession: camera.PhotoSession | undefined;
private cameraInput: camera.CameraInput | undefined;
private previewOutput: camera.PreviewOutput | undefined;
private photoOutput: camera.PhotoOutput | undefined;
// 页面即将销毁时释放资源
aboutToDisappear(): void {
console.info('Page is about to disappear, releasing camera resources');
this.releaseAllResources();
}
// 页面返回前台时重新初始化
onPageShow(): void {
console.info('Page showed, check if need to reinitialize camera');
if (!this.photoSession) {
this.initializeCamera();
}
}
/**
* 初始化相机
*/
async initializeCamera(): Promise<void> {
try {
// 先释放可能存在的旧资源
await this.releaseAllResources();
// 重新创建相机资源
// ... 创建逻辑
console.info('Camera initialized successfully');
} catch (error) {
console.error('Failed to initialize camera:', error);
}
}
/**
* 释放所有资源
*/
async releaseAllResources(): Promise<void> {
try {
// 按照正确顺序释放
if (this.photoSession) {
await this.photoSession.stop();
}
if (this.cameraInput) {
await this.cameraInput.close();
}
if (this.previewOutput) {
await this.previewOutput.release();
}
if (this.photoOutput) {
await this.photoOutput.release();
}
if (this.photoSession) {
await this.photoSession.release();
}
// 清空引用
this.photoSession = undefined;
this.cameraInput = undefined;
this.previewOutput = undefined;
this.photoOutput = undefined;
} catch (error) {
let err = error as BusinessError;
console.error(`Release error: ${err.code}, ${err.message}`);
// 即使释放失败也要清空引用
this.photoSession = undefined;
this.cameraInput = undefined;
this.previewOutput = undefined;
this.photoOutput = undefined;
}
}
build() {
Column() {
// UI 组件
}
}
}
关键要点总结
✅ 必须遵守的规则
- 释放顺序不能错
stop() → cameraInput.close() → previewOutput.release() → photoOutput.release() → session.release()
- 必须使用 await 等待异步完成
await session.stop(); // ✅ 正确 session.stop(); // ❌ 错误:未等待完成
- stop() 和 release() 必须都调用
await session.stop(); // 先停止 await session.release(); // 再释放
- 使用 try-catch 捕获每一步的错误
try { await session.release(); } catch (error) { console.error(‘Release failed:’, error); // 即使失败也要清空引用 session = undefined; }
- 防止重复释放
if (this.isReleasing) return; this.isReleasing = true;
调试建议
- 添加详细日志
async function releaseWithLog(session: camera.PhotoSession): Promise<void> {
console.info(’=== Start releasing camera ===’);
console.info(Session state: ${session ? 'exists' : 'undefined'});
try {
console.info(’[1/5] Calling session.stop()…’);
await session.stop();
console.info(’[1/5] ✓ session.stop() completed’);
console.info(’[2/5] Calling session.release()…’);
await session.release();
console.info(’[2/5] ✓ session.release() completed’);
console.info(’=== Camera released successfully ===’);
} catch (error) {
let err = error as BusinessError;
console.error(=== Release failed at some step ===);
console.error(Error code: ${err.code});
console.error(Error message: ${err.message});
throw error;
}
}
- 检查相机服务状态
import { camera } from ‘@kit.CameraKit’;
// 监听相机状态变化
function monitorCameraStatus(cameraManager: camera.CameraManager): void {
cameraManager.on(‘cameraStatus’, (err: BusinessError, status: camera.CameraStatusInfo) => {
console.info(Camera status changed: ${JSON.stringify(status)});
if (status.status === camera.CameraStatus.UNAVAILABLE) {
console.warn(‘Camera became unavailable, may need to release and reinitialize’);
}
});
}
- 如果问题依然存在
/**
- 终极方案:强制重启相机服务 */ async function forceResetCamera(): Promise<void> { try { // 1. 释放所有相机资源(忽略错误) await photoSession?.stop().catch(() => {}); await cameraInput?.close().catch(() => {}); await previewOutput?.release().catch(() => {}); await photoOutput?.release().catch(() => {}); await photoSession?.release().catch(() => {}); // 2. 清空所有引用 photoSession = undefined; cameraInput = undefined; previewOutput = undefined; photoOutput = undefined; // 3. 等待一段时间让系统清理资源 await new Promise(resolve => setTimeout(resolve, 500)); // 4. 重新初始化相机 await initializeCamera(); console.info(‘Camera force reset completed’); } catch (error) { console.error(‘Force reset failed:’, error); } }
在HarmonyOS Next中,camera.PhotoSession.release()报错通常是由于资源未正确初始化或已被释放导致的。请检查PhotoSession是否已成功创建且未被重复释放。确保在调用release()前,所有相关操作已完成。
在HarmonyOS Next中,camera.PhotoSession.release() 报错 7400201 通常表示相机资源释放时发生了服务端致命错误。这往往不是调用顺序的问题,而是与相机会话的状态管理或底层资源竞争有关。
根据官方文档,释放的正确顺序通常是:先停止捕获会话,再释放PhotoSession。但错误7400201提示问题可能发生在更底层。
建议排查以下几点:
- 检查异步操作:确保所有与相机相关的异步操作(如拍照、对焦)都已完全完成或取消,再调用
release()。未完成的异步任务会持有相机资源。 - 检查生命周期绑定:确认
PhotoSession的释放时机。最佳实践是在页面或组件的aboutToDisappear或onDestroy生命周期回调中释放,并确保释放前UI已完全与相机解耦。 - 检查权限与状态:虽然少见,但请确认相机权限在释放时依然有效。另外,确保没有其他后台进程或模块(如预览的
XComponent)在异常状态下仍持有对相机会话的引用。 - 查看完整日志:错误码
7400201是一个服务端错误。查看设备Logcat的完整错误日志,搜索CameraService或7400201相关的更详细堆栈信息,这能帮助定位是哪个具体操作触发了服务端异常。
一个更稳健的释放模式参考:
// 1. 停止当前捕获会话
try {
await this.photoSession.stop();
} catch (err) {
console.error('Stop photo session failed: ' + err);
}
// 2. 可选:确保所有资源置空
// this.previewOutput = undefined;
// this.photoOutput = undefined;
// 3. 释放PhotoSession
try {
this.photoSession.release();
this.photoSession = undefined; // 释放后置空引用
console.info('PhotoSession released successfully.');
} catch (err) {
console.error('Release photo session failed, error code: ' + err.code);
}
如果上述步骤仍无法解决,问题可能涉及特定设备或场景下的底层兼容性。可以尝试在官方开发者社区搜索错误码7400201,查看是否有已知问题或临时解决方案。

