想做个相机的DEMO,简单地打开相机,然后捕捉画面到手机屏幕上。结果在创建会话的时候遇到了个麻烦。

搜遍了CSDN和博客园等等,关于关键方法createCaptureSession全是用过时的参数配置,自己查看源码和API文档,慢慢地给试出来了~感觉真是第一篇关于createCaptureSession方法的讲解。

2021年前的这样的参数配置都过时了~

 @Deprecated
    public abstract void createCaptureSession(@NonNull List<Surface> outputs,
            @NonNull CameraCaptureSession.StateCallback callback, @Nullable Handler handler)
            throws CameraAccessException;

得用这样的方式去创建会话了:

public void createCaptureSession(
            SessionConfiguration config) throws CameraAccessException {
        throw new UnsupportedOperationException("No default implementation");
    }

那么问题来了,SessionConfiguration 是啥,怎么来的?继续看源码:

/**
 * A helper class that aggregates all supported arguments for capture session initialization.
 * 就是把所有支持的参数配置到捕捉会话初始化中的帮助类,说白了就是这台相机支持的所有参数的属性集合
 */

其中第一个构造方法是这样的:

    public SessionConfiguration(@SessionMode int sessionType,
            @NonNull List<OutputConfiguration> outputs,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull CameraCaptureSession.StateCallback cb) {
        mSessionType = sessionType;
        mOutputConfigurations = Collections.unmodifiableList(new ArrayList<>(outputs));
        mStateCallback = cb;
        mExecutor = executor;
    }

要实例化一个SessionConfiguration,看来我们还需要配置四个参数:

     * @param sessionType--The session type.会话的类型(SessionConfiguration.SESSION_REGULAR,和SESSION_HIGH_SPEED)顾名思义就是常规和高帧率的
     * @param outputs-- A list of output configurations for the capture session.输出属性集合
     * @param executor-- The executor which should be used to invoke the callback. In general it is
     *                 recommended that camera operations are not done on the main (UI) thread.执行回调线程
     * @param cb-- A state callback interface implementation.会话的回调,就是说如果相机捕捉到了画面,接下来呈现在手机上

outputs,是List ,是OutputConfiguration的集合,我们来看OutputConfiguration是什么:

 * A class for describing camera output, which contains a {@link Surface} and its specific
 * configuration for creating capture session.就是相机的一些属性参数

构造方法很简单:

public OutputConfiguration(@NonNull Surface surface) {
        this(SURFACE_GROUP_ID_NONE, surface, ROTATION_0);
    }

这样,我们创建捕捉会话的第二个参数就解决了,只需转换成集合就行了:Collections.singletonList(new OutputConfiguration(surface))

executor,源码说的是建议不要在主线程执行相机操作,这里我有点不懂,我要怎样自己开个分线程呢,最后我还是在主线程执行的,因为在开发者文档中是这么说的:

Executor: The executor which should be used to invoke the callback. In general it is recommended that camera operations are not
 done on the main (UI) thread. This value cannot be null. Callback and listener events are dispatched through this Executor, 
 providing an easy way to control which thread is used. To dispatch events through the main thread of your application, you can 
 use Context.getMainExecutor(). To dispatch events through a shared thread pool, you can use AsyncTask#THREAD_POOL_EXECUTOR.

所以第三个参数也解决了,Context.getMainExecutor()
cb,是一个回调方法,需要自己实现CameraCaptureSession.StateCallback里的onConfigured方法,这个过时的方法也有,就不赘述了

至此,所有参数都有了,可以进行创建了!

 SessionConfiguration sessionConfiguration=new SessionConfiguration(SessionConfiguration.SESSION_REGULAR,
                                Collections.singletonList(new OutputConfiguration(surface)),
                                mContext.getMainExecutor(),
                                 sessionStateCallback);
                        camera.createCaptureSession(sessionConfiguration);

其他代码就不贴了,主要是解决这个过时方法的问题,需要的可以私信我~最后在真机上测试,因为没有对相机和预览画面surface进行过多设置,画面会被拉长,不过画质还是不错的,这取决于手机摄像头咯!

更多推荐