Android Camera App启动流程解析

前言:做了7年的camera app开发,给自己一个总结,算是对camera的一次告白吧。Camera被大家誉为手机的眼睛,是现在各大手机厂商的卖点,也是各大厂商重点发力的地方。Camera的重要性我就不在这里赘述了,让我们进入正题。

先来一张官方的流程图,让我们更加清晰的了解Camera的架构。


一、申请权限

Manifest.permission.CAMERA

如果只要拍照功能,不需要录像的功能,只申请Camera的权限就可以了。

参考代码:参考Camera2 原码

Manifest.permission.RECORD_AUDIO

如果camera app中需要有录像的功能

参考代码:参考Camera2 原码

Manifest.permission.ACCESS_COARSE_LOCATION

Manifest.permission.ACCESS_FINE_LOCATION

如果需要拍照生成的照片带gps的信息,需要申请这两个权限。

参考代码:参考Camera2 原码

二、准备SurfaceView或者SurfaceTexture 或 TextureView

在Camera app启动的时候,onCreate的时候创建surface,可以选择SurfaceView或者SurfaceTexture,这里是根据业务选择的,各有优缺点。

  • SurfaceView:SurfaceView的核心在于提供了两个线程:UI线程和渲染线程,两个线程通过"双缓冲"机制来达到高效的界面刷新效果。
  • SurfaceTexture: 和SurfaceView不同的是,它对图像流的处理并不直接显示,而是转为GL外部纹理,因此可用于图像流数据的二次处理(如Camera滤镜,桌面特效等)。比如Camera的预览数据,变成纹理后可以交给GLSurfaceView直接显示,也可以通过SurfaceTexture交给TextureView作为View heirachy中的一个硬件加速层来显示。
  • TextureView: 它可以将内容流直接投影到View中,可以用于实现Live preview等功能。和SurfaceView不同,它不会在WMS中单独创建窗口,而是作为View hierachy中的一个普通View,因此可以和其它普通View一样进行移动,旋转,缩放,动画等变化。
  • SurfaceView和TextureView对比:

    参考代码:Camera2 代码中用的是SurefaceTexture

三、准备打开camera和预览

Surface准备好了,收到onSurfaceTextureAvailable后,app就可以打开camera和预览了。

参考代码:reopenCamera

获取camera id

首先要确定app要打开的是哪个Camera id,把这个id确定好,app就可以通过openCamera来打开正确的camera sensor了。

参见camera2代码:获取cameraid

openCamera

CameraManager调用openCamera方法打开camera,参见api文档:openCamera

对应到Camera2 的原码位置:open ---> 真正调用openCamera的位置 -->framework中CameraManager调用openCamera的位置-->openCameraForUid -->openCameraDeviceUserAsync-->connectDevice-->connectHelper-->CameraService.cpp中的方法connectHelper-->[makeClient ]

(http://aospxref.com/android-13.0.0_r3/xref/frameworks/av/services/camera/libcameraservice/CameraService.cpp#940)

cpp 复制代码
1060      if (effectiveApiLevel == API_1) { // Camera1 API route
1061          sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
1062          *client = new Camera2Client(cameraService, tmp, cameraService->mCameraServiceProxyWrapper,
1063                  packageName, featureId, cameraId, api1CameraId, facing, sensorOrientation,
1064                  clientPid, clientUid, servicePid, overrideForPerfClass, overrideToPortrait,
1065                  forceSlowJpegMode);
1066          ALOGI("%s: Camera1 API (legacy), override to portrait %d, forceSlowJpegMode %d",
1067                  __FUNCTION__, overrideToPortrait, forceSlowJpegMode);
1068      } else { // Camera2 API route
1069          sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
1070                  static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
1071          *client = new CameraDeviceClient(cameraService, tmp,
1072                  cameraService->mCameraServiceProxyWrapper, packageName, systemNativeClient,
1073                  featureId, cameraId, facing, sensorOrientation, clientPid, clientUid, servicePid,
1074                  overrideForPerfClass, overrideToPortrait);
1075          ALOGI("%s: Camera2 API, override to portrait %d", __FUNCTION__, overrideToPortrait);
1076      }

-->调用camera2的CameraDeviceClient -->Camera2ClientBase.

cpp 复制代码
switch (providerTransport) {
116          case IPCTransport::HIDL:
117              mDevice =
118                      new HidlCamera3Device(TClientBase::mCameraIdStr, mOverrideForPerfClass,
119                              mLegacyClient);
120              break;
121          case IPCTransport::AIDL:
122              mDevice =
123                      new AidlCamera3Device(TClientBase::mCameraIdStr, mOverrideForPerfClass,
124                              mLegacyClient);
125               break;
126          default:
127              ALOGE("%s Invalid transport for camera id %s", __FUNCTION__,
128                      TClientBase::mCameraIdStr.string());
129              return NO_INIT;
130      }

-->Camera2ClientBase.cpp 中的方法 initialize --> HidlCamera3Device.cpp 中的方法initialize -->
openHidlSession -->

相关推荐
- 羊羊不超越 -12 分钟前
App渠道来源追踪方案全面分析(iOS/Android/鸿蒙)
android·ios·harmonyos
wk灬丨1 小时前
Android Kotlin Flow 冷流 热流
android·kotlin·flow
千雅爸爸1 小时前
Android MVVM demo(使用DataBinding,LiveData,Fresco,RecyclerView,Room,ViewModel 完成)
android
晨曦_子画1 小时前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
孤客网络科技工作室2 小时前
AJAX 全面教程:从基础到高级
android·ajax·okhttp
Mr Lee_3 小时前
android 配置鼠标右键快捷对apk进行反编译
android
顾北川_野4 小时前
Android CALL关于电话音频和紧急电话设置和获取
android·音视频
&岁月不待人&4 小时前
Kotlin by lazy和lateinit的使用及区别
android·开发语言·kotlin
Winston Wood6 小时前
Android Parcelable和Serializable的区别与联系
android·序列化
清风徐来辽6 小时前
Android 项目模型配置管理
android