扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
Android中怎么加速相机启动,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
创新互联-云计算及IDC服务提供商,涵盖公有云、IDC机房租用、IDC机房托管、等保安全、私有云建设等企业级互联网基础服务,咨询电话:028-86922220
Android手机上良莠不齐的硬件,导致相机启动时间有长有短,很难预期。用户在使用app过程中,过长的等待会产生焦虑。我们要做的就是让用户尽量感知不到相机启动的耗时。
按照网上能搜到的一般相机Sample的说法,从启动相机到实时预览,我们需要做三件事:1.构建一个GlSurfaceView并获取它的SurfaceHolder;2.获取一个Camera device,启动它;3.将Camera device的预览设置为我们准备好的SurfaceHolder。
我们把GlSurfaceView写到xml里如下:
我们可以在CameraActivity的onCreate里获取到这个GlSurfaceView。可是并不是GlSurfaceView创建好了SurfaceHolder就也准备好了。我们还需要给它设置一个HolderListener来等待它生成出来的SurfaceHolder。
private class SurfaceObserver implements SupportCamSurfaceView.SurfaceHolderLisener { public void onSurfaceHolderCreated(SurfaceHolder holder) { mSurfaceHolder = holder; } } vCameraPreview.setHolderListener(new SurfaceObserver());
然后我们来Open一个Camera。
//代码省略掉了检测Camera个数,获取CameraId还有设置CameraPreviewSize的逻辑。那是其他部分的内容了。 mCamera = Camera.open(mCameraId);
最后把SurfaceHolder设置给Camera就可以开启预览了。
mCamera.setPreviewTexture(mSurfaceHolder); mCamera.startPreview();
一般网上搜到的Sample Code会把这三步放到Activity的onCreate里顺序执行。也就是等SurfaceHolderListener获取到了SurfaceHolder再启动Camera。Camera启动完成再把它俩关联上并启动预览。我们来看一下再小米1上这个流程的耗时。
获取SurfaceHolderListener 0.3秒
启动Camera 1秒
如果把Activity创建的时间和其它代码执行的时间都忽略的话,我们一共耗费了1.3秒。而用户对大于1秒的等待都是不耐烦的。更不用说在有的手机上Camera启动时间能够达到反人类的1.5秒以上。
很容易想到的一个优化方案就是让获取SurfaceHolder和启动Camera在两个线程里异步进行。这样应该可以使耗时在小米1上缩短到1秒左右,勉强能接受。
SurfaceHolder的获取本身就是异步的。我们只需要在Activity的onCreate里再启动一个异步线程去启动Camera。在这两个异步线程执行完成后都分别去检测另一个线程是否完成。简化的代码如下。
public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); vCameraPreview.setHolderListener(new SurfaceObserver()); new Handler().post(new Runnable(){ public void run(){ mCamera = Camera.open(mCameraId); checkCamera(); } }); } private class SurfaceObserver implements SupportCamSurfaceView.SurfaceHolderLisener { public void onSurfaceHolderCreated(SurfaceHolder holder) { mSurfaceHolder = holder; checkCamera(); } } private void checkCamera(){ if(mSurfaceHolder != null && mCamera != null{ mCamera.setPreviewTexture(mSurfaceHolder); mCamera.startPreview(); } }
这样就算优化完了吗?让我们想想苹果是怎么做的吧。苹果很喜欢用一些过渡动画来掩饰后台加载的耗时。毕竟相机启动的这1秒时间是由硬件限制的,我们在app层面上没办法把它缩短,所以我们不如加一个动画,并在动画过程中提前启动相机,来一个苹果式的小trick。我给进入相机Activity的按钮加了一个0.5秒的反馈动画,又给相机Activity加了一个0.3秒的Pending动画,在两个动画完成后,只需再有0.2秒的时间小米1的相机就完成启动了,这对用户来说已经是完全可以接受的了。
上面的逻辑实现起来有两个问题。一个是在我们获取到CameraActivity的实例之前就要开始启动相机了,另一个是Camera启动完成后没办法调用Activity实例的checkCamera方法。所以我们只能把Camera和Activity实例分别存放到一个static变量里。写起来不复杂,只是需要注意变量的回收。在Activity的onDestroy里先把Camera release再设为null,Activity实例的引用直接设为null,这样就可以了。
static Camera mCamera; static CameraActivity instance; public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); instance = this; vCameraPreview.setHolderListener(new SurfaceObserver()); } public static void openCamera{ new Handler().post(new Runnable(){ public void run(){ mCamera = Camera.open(mCameraId); if(instance != null){ instance.checkCamera(); } } }); } private class SurfaceObserver implements SupportCamSurfaceView.SurfaceHolderLisener { public void onSurfaceHolderCreated(SurfaceHolder holder) { mSurfaceHolder = holder; checkCamera(); } } private void checkCamera(){ if(mSurfaceHolder != null && mCamera != null{ mCamera.setPreviewTexture(mSurfaceHolder); mCamera.startPreview(); } }
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联行业资讯频道,感谢您对创新互联的支持。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流