com.android.camera.Camera.java,主要的实现Activity,继承于ActivityBase。

ActivityBase

在ActivityBase中执行流程:

  1. onCreate中进行判断是否是平板;
  2. onResume中判断是否锁屏,锁屏&camera不存在时候,mOnResumePending置为true,否则置为false并执行doOnResume;
  3. onWindowFocusChanged中判断是否获取到焦点&mOnResumePending,满足的话执行doOnResume;
  4. onPause中将mOnResumePending置为false;

Camera.java

接下来分析Camera.java,执行流程:

1、onCreate

  1. // 获得摄像头的数量,前置和后置
  2. getPreferredCameraId();
  3. // 获得对焦设置eg:连续对焦或者其它
  4. String[] defaultFocusModes = getResources().getStringArray(R.array.pref_camera_focusmode_default_array);
  5. //实例化Focus管理对象
  6. mFocusManager = new FocusManager(mPreferences, defaultFocusModes);
  7. // 开启线程来启动摄像头
  8. mCameraOpenThread.start();
  9. // 是否是第三方应用启动拍照功能
  10. mIsImageCaptureIntent = isImageCaptureIntent();
  11. // 设置UI布局文件
  12. setContentView(R.layout.camera);
  13. if (mIsImageCaptureIntent) {
  14. // 当第三方其送拍照,需要显示不同的UI,比如取消键盘
  15. mReviewDoneButton = (Rotatable) findViewById(R.id.btn_done);
  16. mReviewCancelButton = (Rotatable) findViewById(R.id.btn_cancel);
  17. findViewById(R.id.btn_cancel).setVisibility(View.VISIBLE);
  18. } else {
  19. // 反之显示缩略图
  20. mThumbnailView = (RotateImageView) findViewById(R.id.thumbnail);
  21. mThumbnailView.enableFilter(false);
  22. mThumbnailView.setVisibility(View.VISIBLE);
  23. }
  24. // 一个能旋转的dialog.比如相机设置的dialog,这个类实现了旋转的父类
  25. mRotateDialog = new RotateDialogController(this, R.layout.rotate_dialog);
  26. // 设置camera的ID,写道SharedPreference中
  27. mPreferences.setLocalId(this, mCameraId);
  28. // 更新preference
  29. CameraSettings.upgradeLocalPreferences(mPreferences.getLocal());
  30. // 获得相机数
  31. mNumberOfCameras = CameraHolder.instance().getNumberOfCameras();
  32. // 貌似是获得是否是快速拍照
  33. mQuickCapture = getIntent().getBooleanExtra(EXTRA_QUICK_CAPTURE, false);
  34. // 为当前的preview重置曝光值
  35. resetExposureCompensation();
  36. // 隐藏系统导航栏等
  37. Util.enterLightsOutMode(getWindow());
  38. //SurfaceView
  39. SurfaceView preview = (SurfaceView) findViewById(R.id.camera_preview);
  40. SurfaceHolder holder = preview.getHolder();
  41. holder.addCallback(this);
  42. holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  43. try {
  44. // 这个join语句就是为了保证openCamera的线程执行完后,当前的线程才开始运行。主要是为了确保camera设备被打开了
  45. mCameraOpenThread.join();
  46. // 线程执行完后置为空来让系统回收资源
  47. mCameraOpenThread = null;
  48. if (mOpenCameraFail) {
  49. // 打开camera失败,显示“无法连接到相机”
  50. Util.showErrorAndFinish(this, R.string.cannot_connect_camera);
  51. return;
  52. } else if (mCameraDisabled) {
  53. // 由于安全政策限制,相机已被停用
  54. Util.showErrorAndFinish(this, R.string.camera_disabled);
  55. return;
  56. }
  57. } catch (InterruptedException ex) {
  58. // ignore
  59. }
  60. //开启显示的子线程
  61. mCameraPreviewThread.start();
  62. if (mIsImageCaptureIntent) {
  63. //如果是第三方开启的 ,setupCaptureParams 设置拍照的参数
  64. setupCaptureParams();
  65. } else {
  66. //设置ModePicker
  67. mModePicker = (ModePicker) findViewById(R.id.mode_picker);
  68. mModePicker.setVisibility(View.VISIBLE);
  69. mModePicker.setOnModeChangeListener(this);
  70. mModePicker.setCurrentMode(ModePicker.MODE_CAMERA);
  71. }
  72. mZoomControl = (ZoomControl) findViewById(R.id.zoom_control);
  73. mOnScreenIndicators = (Rotatable) findViewById(R.id.on_screen_indicators);
  74. mLocationManager = new LocationManager(this, this);
  75. //摄像头ID
  76. mBackCameraId = CameraHolder.instance().getBackCameraId();
  77. mFrontCameraId = CameraHolder.instance().getFrontCameraId();
  78. // 在startPreview里面有notify方法
  79. synchronized (mCameraPreviewThread) {
  80. try {
  81. mCameraPreviewThread.wait();
  82. } catch (InterruptedException ex) {
  83. // ignore
  84. }
  85. }
  86. // 初始化各种控制按钮
  87. initializeIndicatorControl();
  88. //初始化拍照声音
  89. mCameraSound = new CameraSound();
  90. try {
  91. //确保显示
  92. mCameraPreviewThread.join();
  93. } catch (InterruptedException ex) {
  94. // ignore
  95. }
  96. mCameraPreviewThread = null;

2、surfaceCreated

啥都没做

3、surfaceChanged

  1. // 确保在holder中有surface
  2. if (holder.getSurface() == null) {
  3. Log.d(TAG, "holder.getSurface() == null");
  4. return;
  5. }
  6. // We need to save the holder for later use, even when the mCameraDevice
  7. // is null. This could happen if onResume() is invoked after this
  8. // function.
  9. mSurfaceHolder = holder;
  10. if (mCameraDevice == null) return;
  11. if (mPausing || isFinishing()) return;
  12. // Set preview display if the surface is being created. Preview was
  13. // already started. Also restart the preview if display rotation has
  14. // changed. Sometimes this happens when the device is held in portrait
  15. // and camera app is opened. Rotation animation takes some time and
  16. // display rotation in onCreate may not be what we want.
  17. if (mCameraState == PREVIEW_STOPPED) {
  18. startPreview();
  19. startFaceDetection();
  20. } else {
  21. if (Util.getDisplayRotation(this) != mDisplayRotation) {
  22. setDisplayOrientation();
  23. }
  24. if (holder.isCreating()) {
  25. // Set preview display if the surface is being created and preview
  26. // was already started. That means preview display was set to null
  27. // and we need to set it now.
  28. setPreviewDisplay(holder);
  29. }
  30. }
  31. // If first time initialization is not finished, send a message to do
  32. // it later. We want to finish surfaceChanged as soon as possible to let
  33. // user see preview first.
  34. if (!mFirstTimeInitialized) {
  35. mHandler.sendEmptyMessage(FIRST_TIME_INIT);
  36. } else {
  37. initializeSecondTime();
  38. }

如果是第一次加载,则执行mHandler.sendEmptyMessage(FIRST_TIME_INIT); 对应处理的是initializeFirstTime();

  1. /**
  2. * 初始化,第一次初始化
  3. * // Snapshots can only be taken after this is called. It should be called
  4. * // once only. We could have done these things in onCreate() but we want to
  5. * // make preview screen appear as soon as possible.
  6. */
  7. private void initializeFirstTime() {
  8. if (mFirstTimeInitialized) return;
  9.  
  10. // Create orientation listenter. This should be done first because it
  11. // takes some time to get first orientation.
  12. mOrientationListener = new MyOrientationEventListener(Camera.this);
  13. mOrientationListener.enable();
  14.  
  15. // Initialize location sevice.
  16. boolean recordLocation = RecordLocationPreference.get(
  17. mPreferences, getContentResolver());
  18. // 初始化屏幕最上方的标志,比如开启了曝光值啊,什么的
  19. initOnScreenIndicator();
  20. // 位置服务
  21. mLocationManager.recordLocation(recordLocation);
  22.  
  23. keepMediaProviderInstance();
  24. // 检查存储空间和初始化储存目录
  25. checkStorage();
  26. // Initialize last picture button.
  27. mContentResolver = getContentResolver();
  28. if (!mIsImageCaptureIntent) { // no thumbnail in image capture intent
  29. // 初始化缩略图
  30. initThumbnailButton();
  31. }
  32. // Initialize shutter button.
  33. // 初始化拍照按钮并设置监听事件
  34. mShutterButton = (ShutterButton) findViewById(R.id.shutter_button);
  35. mShutterButton.setOnShutterButtonListener(this);
  36. mShutterButton.setVisibility(View.VISIBLE);
  37. // Initialize focus UI.
  38. mPreviewFrame = findViewById(R.id.camera_preview);
  39. mPreviewFrame.setOnTouchListener(this);
  40. // 聚焦框
  41. mFocusAreaIndicator = (RotateLayout) findViewById(R.id.focus_indicator_rotate_layout);
  42. CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
  43. boolean mirror = (info.facing == CameraInfo.CAMERA_FACING_FRONT);
  44. mFocusManager.initialize(mFocusAreaIndicator, mPreviewFrame, mFaceView, this,
  45. mirror, mDisplayOrientation);
  46. // 初始化一个图片的保存线程
  47. mImageSaver = new ImageSaver();
  48. // 设置屏幕亮度
  49. Util.initializeScreenBrightness(getWindow(), getContentResolver());
  50. // 注册SD卡相关的广播,比如拔出存储卡什么的
  51. installIntentFilter();
  52. // 初始化缩放UI
  53. initializeZoom();
  54. // 更新屏幕上的闪光灯什么的标记
  55. updateOnScreenIndicators();
  56. // 开始面部检测
  57. startFaceDetection();
  58. // Show the tap to focus toast if this is the first start.
  59. // 假如是第一次启动,提示用户“触摸对焦”
  60. if (mFocusAreaSupported &&
  61. mPreferences.getBoolean(CameraSettings.KEY_CAMERA_FIRST_USE_HINT_SHOWN, true)) {
  62. // Delay the toast for one second to wait for orientation.
  63. mHandler.sendEmptyMessageDelayed(SHOW_TAP_TO_FOCUS_TOAST, 1000);
  64. }
  65. mFirstTimeInitialized = true;
  66. addIdleHandler();
  67. }

如果不是,则执行initializeSecondTime();

  1. /**
  2. * // If the activity is paused and resumed, this method will be called in
  3. * // onResume.
  4. */
  5. private void initializeSecondTime() {
  6. // Start orientation listener as soon as possible because it takes
  7. // some time to get first orientation.
  8. //方向翻转设置enable,其中包括翻转的时候的动画
  9. mOrientationListener.enable();
  10.  
  11. // Start location update if needed.
  12. boolean recordLocation = RecordLocationPreference.get(
  13. mPreferences, getContentResolver());
  14. mLocationManager.recordLocation(recordLocation);
  15. //设置SD卡广播
  16. installIntentFilter();
  17. mImageSaver = new ImageSaver();
  18. //初始化Zoom
  19. initializeZoom();
  20. //mMediaProviderClient=媒体Provider对象
  21. keepMediaProviderInstance();
  22. //检查硬盘
  23. checkStorage();
  24. //淡出retake和done的Button
  25. hidePostCaptureAlert();
  26. if (!mIsImageCaptureIntent) {
  27. //如果不是第三方开启,则更新缩略图
  28. updateThumbnailButton();
  29. mModePicker.setCurrentMode(ModePicker.MODE_CAMERA);
  30. }
  31. }

4、surfaceDestroyed

  1. stopPreview();
  2. mSurfaceHolder = null;

我是天王盖地虎的分割线

Android -- Camera源码简析,启动流程的更多相关文章

  1. Flink源码阅读(一)——Flink on Yarn的Per-job模式源码简析

    一.前言 个人感觉学习Flink其实最不应该错过的博文是Flink社区的博文系列,里面的文章是不会让人失望的.强烈安利:https://ververica.cn/developers-resource ...

  2. SpringMVC学习(一)——概念、流程图、源码简析

    学习资料:开涛的<跟我学SpringMVC.pdf> 众所周知,springMVC是比较常用的web框架,通常整合spring使用.这里抛开spring,单纯的对springMVC做一下总 ...

  3. django-jwt token校验源码简析

    一. jwt token校验源码简析 1.1 前言 之前使用jwt签发了token,里面的头部包含了加密的方式.是否有签名等,而载荷中包含用户名.用户主键.过期时间等信息,最后的签名还使用了摘要算法进 ...

  4. Appium Android Bootstrap源码分析之启动运行

    通过前面的两篇文章<Appium Android Bootstrap源码分析之控件AndroidElement>和<Appium Android Bootstrap源码分析之命令解析 ...

  5. 0002 - Spring MVC 拦截器源码简析:拦截器加载与执行

    1.概述 Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理.例如通过拦截器可以进行权限验证.记录请求信息的日 ...

  6. Python Web Flask源码解读(一)——启动流程

    关于我 一个有思想的程序猿,终身学习实践者,目前在一个创业团队任team lead,技术栈涉及Android.Python.Java和Go,这个也是我们团队的主要技术栈. Github:https:/ ...

  7. Flume-ng源码解析之启动流程

    今天我们通过阅读Flume-NG的源码来看看Flume的整个启动流程,废话不多说,翠花,上源码!! 1 主类也是启动类 在这里我贴出Application中跟启动有关的方法,其他你们可以自己看源码,毕 ...

  8. AFNetworking源码简析

    AFNetworking基本是苹果开发中网络请求库的标配,它是一个轻量级的网络库,专门针对iOS和OS X的网络应用设计,具有模块化的架构和丰富的APIs接口,功能强大并且使用简单,深受苹果应用开发人 ...

  9. SpringMVC源码解析-DispatcherServlet启动流程和初始化

    在使用springmvc框架,会在web.xml文件配置一个DispatcherServlet,这正是web容器开始初始化,同时会在建立自己的上下文来持有SpringMVC的bean对象. 先从Dis ...

随机推荐

  1. scrapy爬虫,爬取图片

    一.scrapy的安装: 本文基于Anacoda3, Anacoda2和3如何同时安装? 将Anacoda3安装在C:\ProgramData\Anaconda2\envs文件夹中即可. 如何用con ...

  2. windows下thrift的使用(C++)

    thrift cpp环境搭建: 1.  安装boost_1_53_0,注意,使用vs2010版本时,使用二进制的boost安装版本,生成的lib有可能是,在后续操作会出问题.在源码目录中,运行boot ...

  3. BeautifulSoup与Xpath解析库总结

    一.BeautifulSoup解析库 1.快速开始 html_doc = """ <html><head><title>The Dor ...

  4. 学好js,这些js函数概念一定要知道

    函数创建方式 1.声明方式 例如:function consoleTip (){ console.log("tip!"); } 2.表达式方式 例如:var consoleTip ...

  5. md 添加 图片

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 1.在github上的仓库建立一个存放图片的文件夹,文件夹名字随意.如:img-fold ...

  6. 1316 文化之旅 2012年NOIP全国联赛普及组

      题目描述 Description 有一位使者要游历各国,他每到一个国家,都能学到一种文化,但他不愿意学习任何一种文化超过一次(即如果他学习了某种文化,则他就不能到达其他有这种文化的国家).不同的国 ...

  7. POJ 2987 Firing 网络流 最大权闭合图

    http://poj.org/problem?id=2987 https://blog.csdn.net/u014686462/article/details/48533253 给一个闭合图,要求输出 ...

  8. Codeforces Round #357 (Div. 2) B. Economy Game 水题

    B. Economy Game 题目连接: http://www.codeforces.com/contest/681/problem/B Description Kolya is developin ...

  9. Git_管理修改

    现在,假定你已经完全掌握了暂存区的概念.下面,我们要讨论的就是,为什么Git比其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件. 你会问,什么是修改?比如你新增了一行,这就是一个修改 ...

  10. C#程序集系列08,设置程序集版本

    区别一个程序集,不仅仅是程序集名称,还包括程序集版本.程序集公匙.程序集文化等,本篇体验通过界面和编码设置程序集版本. □ 通过Visual Studio设置程序集版本 →右键项目,选择"属 ...