想要理解API2的Session机制,不能简单的只从Camera看,而是要结和Sesion本身的概念来看。
一、Session机制
1、Web应用中的Session
计算机领域的Session概念主要来自于Web通信,在网络应用中,称为会话控制。
“Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web页时,如果该用户还没有会话,则Web服务器将自动创建一个 Session对象。当会话过期或被放弃后,服务器将终止该会话。”
以上描述来自百度百科。我们通过这段描述,可以看出Session的几个特点
- Session由服务器创建,由服务器终止,期间始终存在,除非过期或被放弃;
- Sesion存储的变量始终不会丢失;
2、Caemra API2中的Session
如前所述,我们已经知道了Web应用中Session的几个特点,现在我们来对比一下Camera2下的Session概念是否也具有类似的特征。
1.如上一节介绍CameraDevice的主要作用就是创建Session;在session中存在一个closeByDevice()方法,这个方法会在device创建session调用关闭已存在会话;会在error时调用;以及在device关闭调用disconnected时调用。
也就是说Session的创建和销毁完全由device管理。
2.Camera2的Request全部由Session下发,除非修改,否则将始终保持之前的状态。
从上面的分析可以看到,Camera2的Session与Web应用的Session行为上是一致的。所以,我们可以理解Caemra 2的Session具备了Web应用Session的优点。
3、Camera1与Camera2的区别
二者除了API接口本身的区别,最大的区别还是在实现逻辑上的。
Camera1的逻辑是面向Camera对象的,所有的行为都是基于这个对象的方法的,如果这个对象本身就存在问题是无法感知的,只能在调用方法时抛出异常;
Camera2的逻辑则是面向状态的,无论device还是session,任何状态的改变可以做出相应的处理。
正是这样的逻辑不同,导致了MetaData在传递上的区别。
Camera1的Parameter根据TAG直接绑定MetaData Request,经过Capture_Request转为camera3_capture_request中的camera_metadata_t settings完成参数从Java到native到HAL3的传递。
Camera2则直接封装为CaputureRequest,统一了Framework和HAL层的数据,没有复杂的数据转换过程。
二、Session传递的属性
在1.2节中我们介绍Preview时,我们提到了session创建连续捕获的方法setRepeatingRequest(),其中第一个参数是一个CaptureRequest对象,这个类采用了创建者模式,即request对象需要由builder创建
Kotlin代码:
mPreviewRequest = mPreviewRequestBuilder!!.build()
CaptureRequest类中只提供了一些get方法和比较方法,真正的功能性方法set是在builder中,所以为了让相机达到我们想要的效果,我们需要对builder进行操作。
Kotlin代码:
mPreviewRequest = mPreviewRequestBuilder!!.build()
CaptureRequest类中只提供了一些get方法和比较方法,真正的功能性方法set是在builder中,所以为了让相机达到我们想要的效果,我们需要对builder进行操作。
Kotlin代码:
//构建Request Builder
mPreviewRequestBuilder = mCameraDevice!!.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
//设置自动对焦
mPreviewRequestBuilder!!.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE)
这里我们以设置自动对焦的连续对焦模式为例,可以看到对于Metadata而言就是设置key-value键值对即可。
最后将构建好的builder赋值到Request
Kotlin代码:
mPreviewRequest = mPreviewRequestBuilder!!.build()
这样Request对象就已经完成了初始化和设置参数,通过session就可以下发到HAL层了。
在这里我们需要注意到CaptureRequest类、CaptureResult类都是继承自CameraMetadata<CaptureResult.Key<?>>类,也就是说所有可设置的参数,实际上都是在Metadata的设置范围内进行的。
下一章节,我们将详细讲解CameraMetadata<TKey>类。