修正Android摄像头API

2015-05-12 17:41:20 724浏览


      Android关于摄像头的API非常糟糕,如果你没有用过,那么自己花点时间看看去吧。使用这个Camera API的时候,经常会使开发者使用错误,会导致开发者忽略很多重要的东西,然后出问题了也很难发现,甚至在StackOverFlow上也很不乐观。换句话说,如果有API需要你读完十个步骤(还有几个标记为重要的),那么,其实它是有问题的,怎么会写出这么麻烦的API呢?我们要改进它。




      所以打算重新构造它。我把重构后的代码放在GitHub( EasyCamera),以下列出了我改的地方,还有修改的理由:

     在使用startPreview()方法之前,需要先调用setPreviewDisplay(..)方法,然后再进行拍照的时候又需要调用它。为什么不改进一下呢?如果不执行这个方法的话就会出问题,我们可以简单地抛出一个异常“Preview display not set”,但是这样终究不太好。所以,这个setPreviewDisplay(..)可以不要了,我们直接让startPreview(..)带上surface作参数,然后还可以重载它让SurfaceTexture也作为参数传递进去。
     在改进了预览设置后,现在开始改进预览操作。如果在拍照的时候,没有调用startPreview这个方法,那也会出问题,这里也可以简单抛出一个异常“Preview not started”,但是要知道,这个异常是在运行时抛出的。所以,takePicture(..)这个方法也要改进,把它移到Camera这个类外面,放到CameraAction类里。其它的需要在preview调用后才能使用的方法也需要这样改进(我暂时不知道有哪一些,当前的API里也没有列出来)。接下来就是怎么获取一个CameraAction类实例了,很简单,直接调用startPreview(..)就可以返回一个CameraAction了。
     目前我们的改进只是让使用方法更加直观,然后减少出错的情况。不过takePicture这个方法好像有点奇怪,可以给它的参数全部传null值,但是里面还有两个重写的方法需要这些参数。理论上说,传null值也可以,但是还有别的法子解决这个问题。其一就是介绍一个接口叫PictureCallback,它有四个可以调用的方法,然后还提供一个默认的实现类,叫BasePictureCallback。当然,你会发现,在这个场景中,好像也不太合适,因为这个例子中你传递这个callback接口的话,什么事都不会发生,但是传递null值的话,就不一样了(会出问题),但是在我的手机上测试的时候,我传递一个shutter callback时,快门声音就会响,而传递null值就不会响。所以,这里主要介绍的就是使用这个callback接口,带有一个实现类,包含所有你需要的所有方法。
      到目前为止,改的还不错,还有就是,在照相完成后,需要restart preview,但是默认让它自动restart也不是很好。目前的情况是,我们只有一个CameraAction类,然后调用startPreview(..)方法需要传递一个surface参数,是不是需要引进一个restartPreview()方法呢?当然不用,这里我们让这个接口类的方法都返回一个布尔值,如果需要restart preview,就可以返回true,这样会比较好,然后又有一个问题,如果这个callback类没有这4个方法调用呢,依赖这4个方法来得出是否需要restart preview终究不好,所以,还需要在callback实现类中加一个restartPreview属性,只有在最后一个方法被调用时这个属性才会被设置成true
      主要的步骤已经改进好了,还有其它的一些小问题需要改进,比如,关闭和打开camera的方法是不对称的,“open”“release”配对感觉不好,应该是“open”“close”或者“acquire”“release”。所以我觉得用“close”更好一些,况且(如果使用java7),可以好好利用AutoClosable接口,还有try-with-resource结构(详情请查看java7新特性)。
      在调用getParameter()方法的时候可以得到一份参数的副本,然后,你可能需要把更改过的这个副本设置回去,也是挺合理的。如果能提供一个camera.setParameter(..)方法,可能使用起来会方便一些,不过Parameter类已经提供了很多方法了,所以在Camera类里面添加不太好。或许这里可以设置可变参数?(当然现在也还没实现)
     这个CameraAPI糟糕的原因之一还有它的错误反馈,基本上可能得到一个报错信息“Came.takePicture failed”,无论什么原因导致的,通过以上的这些步骤,在某些情况下会过滤掉一些我们需要的异常信息,不过最好还是应该得到精确的报错信息。
      我们的目的就是要让Camera使用更加友好(现在还不是),所以EasyCamera是一个容易使用的接口,CameraActions也是一个可造性很好的类。
标签:

热门专区

暂无热门资讯

课程推荐

微信
微博
15311698296

全国免费咨询热线

邮箱:codingke@1000phone.com

官方群:148715490

北京千锋互联科技有限公司版权所有   北京市海淀区宝盛北里西区28号中关村智诚科创大厦4层
京ICP备12003911号-6   Copyright © 2013 - 2019

京公网安备 11010802030908号