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

// 获得摄像头的数量,前置和后置getPreferredCameraId();// 获得对焦设置eg:连续对焦或者其它String[] defaultFocusModes = getResources().getStringArray(R.array.pref_camera_focusmode_default_array);//实例化Focus管理对象mFocusManager = new FocusManager(mPreferences, defaultFocusModes);// 开启线程来启动摄像头mCameraOpenThread.start();// 是否是第三方应用启动拍照功能mIsImageCaptureIntent = isImageCaptureIntent();// 设置UI布局文件setContentView(R.layout.camera);if (mIsImageCaptureIntent) {       // 当第三方其送拍照,需要显示不同的UI,比如取消键盘       mReviewDoneButton = (Rotatable) findViewById(R.id.btn_done);       mReviewCancelButton = (Rotatable) findViewById(R.id.btn_cancel);       findViewById(R.id.btn_cancel).setVisibility(View.VISIBLE);} else {       // 反之显示缩略图       mThumbnailView = (RotateImageView) findViewById(R.id.thumbnail);       mThumbnailView.enableFilter(false);       mThumbnailView.setVisibility(View.VISIBLE);}// 一个能旋转的dialog.比如相机设置的dialog,这个类实现了旋转的父类mRotateDialog = new RotateDialogController(this, R.layout.rotate_dialog);// 设置camera的ID,写道SharedPreference中mPreferences.setLocalId(this, mCameraId);// 更新preferenceCameraSettings.upgradeLocalPreferences(mPreferences.getLocal());// 获得相机数mNumberOfCameras = CameraHolder.instance().getNumberOfCameras();//  貌似是获得是否是快速拍照mQuickCapture = getIntent().getBooleanExtra(EXTRA_QUICK_CAPTURE, false);// 为当前的preview重置曝光值resetExposureCompensation();// 隐藏系统导航栏等Util.enterLightsOutMode(getWindow());//SurfaceView SurfaceView preview = (SurfaceView) findViewById(R.id.camera_preview);SurfaceHolder holder = preview.getHolder();holder.addCallback(this);holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);try {       // 这个join语句就是为了保证openCamera的线程执行完后,当前的线程才开始运行。主要是为了确保camera设备被打开了        mCameraOpenThread.join();        // 线程执行完后置为空来让系统回收资源        mCameraOpenThread = null;        if (mOpenCameraFail) {            // 打开camera失败,显示“无法连接到相机”            Util.showErrorAndFinish(this, R.string.cannot_connect_camera);            return;        } else if (mCameraDisabled) {            // 由于安全政策限制,相机已被停用            Util.showErrorAndFinish(this, R.string.camera_disabled);            return;        }} catch (InterruptedException ex) {           // ignore}//开启显示的子线程mCameraPreviewThread.start();if (mIsImageCaptureIntent) {    //如果是第三方开启的 ,setupCaptureParams 设置拍照的参数       setupCaptureParams();} else {      //设置ModePicker        mModePicker = (ModePicker) findViewById(R.id.mode_picker);      mModePicker.setVisibility(View.VISIBLE);      mModePicker.setOnModeChangeListener(this);      mModePicker.setCurrentMode(ModePicker.MODE_CAMERA);}mZoomControl = (ZoomControl) findViewById(R.id.zoom_control);mOnScreenIndicators = (Rotatable) findViewById(R.id.on_screen_indicators);mLocationManager = new LocationManager(this, this);//摄像头IDmBackCameraId = CameraHolder.instance().getBackCameraId();mFrontCameraId = CameraHolder.instance().getFrontCameraId();// 在startPreview里面有notify方法synchronized (mCameraPreviewThread) {      try {          mCameraPreviewThread.wait();       } catch (InterruptedException ex) {            // ignore       }}// 初始化各种控制按钮initializeIndicatorControl();//初始化拍照声音mCameraSound = new CameraSound();try {       //确保显示       mCameraPreviewThread.join();} catch (InterruptedException ex) {        // ignore}mCameraPreviewThread = null;

2、surfaceCreated

啥都没做

3、surfaceChanged

// 确保在holder中有surface if (holder.getSurface() == null) {       Log.d(TAG, "holder.getSurface() == null");        return;}// We need to save the holder for later use, even when the mCameraDevice// is null. This could happen if onResume() is invoked after this// function.mSurfaceHolder = holder;if (mCameraDevice == null) return;if (mPausing || isFinishing()) return;// Set preview display if the surface is being created. Preview was// already started. Also restart the preview if display rotation has// changed. Sometimes this happens when the device is held in portrait// and camera app is opened. Rotation animation takes some time and// display rotation in onCreate may not be what we want.if (mCameraState == PREVIEW_STOPPED) {        startPreview();        startFaceDetection();} else {        if (Util.getDisplayRotation(this) != mDisplayRotation) {            setDisplayOrientation();}        if (holder.isCreating()) {            // Set preview display if the surface is being created and preview            // was already started. That means preview display was set to null            // and we need to set it now.            setPreviewDisplay(holder);        }}// If first time initialization is not finished, send a message to do// it later. We want to finish surfaceChanged as soon as possible to let// user see preview first.if (!mFirstTimeInitialized) {       mHandler.sendEmptyMessage(FIRST_TIME_INIT);} else {      initializeSecondTime(); }

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

/**     * 初始化,第一次初始化     *  // Snapshots can only be taken after this is called. It should be called     *  // once only. We could have done these things in onCreate() but we want to     *  // make preview screen appear as soon as possible.     */    private void initializeFirstTime() {        if (mFirstTimeInitialized) return;        // Create orientation listenter. This should be done first because it        // takes some time to get first orientation.        mOrientationListener = new MyOrientationEventListener(Camera.this);        mOrientationListener.enable();        // Initialize location sevice.        boolean recordLocation = RecordLocationPreference.get(                mPreferences, getContentResolver());        // 初始化屏幕最上方的标志,比如开启了曝光值啊,什么的        initOnScreenIndicator();        // 位置服务        mLocationManager.recordLocation(recordLocation);        keepMediaProviderInstance();        // 检查存储空间和初始化储存目录        checkStorage();        // Initialize last picture button.        mContentResolver = getContentResolver();        if (!mIsImageCaptureIntent) {  // no thumbnail in image capture intent            // 初始化缩略图            initThumbnailButton();        }        // Initialize shutter button.        // 初始化拍照按钮并设置监听事件        mShutterButton = (ShutterButton) findViewById(R.id.shutter_button);        mShutterButton.setOnShutterButtonListener(this);        mShutterButton.setVisibility(View.VISIBLE);        // Initialize focus UI.        mPreviewFrame = findViewById(R.id.camera_preview);        mPreviewFrame.setOnTouchListener(this);        // 聚焦框        mFocusAreaIndicator = (RotateLayout) findViewById(R.id.focus_indicator_rotate_layout);        CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];        boolean mirror = (info.facing == CameraInfo.CAMERA_FACING_FRONT);        mFocusManager.initialize(mFocusAreaIndicator, mPreviewFrame, mFaceView, this,                mirror, mDisplayOrientation);        // 初始化一个图片的保存线程        mImageSaver = new ImageSaver();        // 设置屏幕亮度        Util.initializeScreenBrightness(getWindow(), getContentResolver());        // 注册SD卡相关的广播,比如拔出存储卡什么的        installIntentFilter();        // 初始化缩放UI        initializeZoom();        // 更新屏幕上的闪光灯什么的标记        updateOnScreenIndicators();        // 开始面部检测        startFaceDetection();        // Show the tap to focus toast if this is the first start.        // 假如是第一次启动,提示用户“触摸对焦”        if (mFocusAreaSupported &&                mPreferences.getBoolean(CameraSettings.KEY_CAMERA_FIRST_USE_HINT_SHOWN, true)) {            // Delay the toast for one second to wait for orientation.            mHandler.sendEmptyMessageDelayed(SHOW_TAP_TO_FOCUS_TOAST, 1000);        }        mFirstTimeInitialized = true;        addIdleHandler();    }

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

/**     *  // If the activity is paused and resumed, this method will be called in     *  // onResume.     */    private void initializeSecondTime() {        // Start orientation listener as soon as possible because it takes        // some time to get first orientation.        //方向翻转设置enable,其中包括翻转的时候的动画        mOrientationListener.enable();        // Start location update if needed.        boolean recordLocation = RecordLocationPreference.get(                mPreferences, getContentResolver());        mLocationManager.recordLocation(recordLocation);        //设置SD卡广播        installIntentFilter();        mImageSaver = new ImageSaver();        //初始化Zoom        initializeZoom();        //mMediaProviderClient=媒体Provider对象        keepMediaProviderInstance();        //检查硬盘        checkStorage();        //淡出retake和done的Button        hidePostCaptureAlert();        if (!mIsImageCaptureIntent) {            //如果不是第三方开启,则更新缩略图            updateThumbnailButton();            mModePicker.setCurrentMode(ModePicker.MODE_CAMERA);        }    }

4、surfaceDestroyed

stopPreview();mSurfaceHolder = null;

我是天王盖地虎的分割线

更多相关文章

  1. 自定义view-制作一个加载中的圆形
  2. Android底部导航栏实现(一)之BottomNavigationBar
  3. android 开启关闭wifi服务
  4. Android(安卓)调用系统相机并加时间水印
  5. android 学习笔记4——post请求+线程控制
  6. Android中的HandlerThread和IntentService
  7. AndroidO Camera 分析(一): (API 2)openCamera 流程
  8. Android(安卓)从缓存中读取图片并异步加载的类[转]
  9. Android延时执行方法

随机推荐

  1. 将要改变IT世界的的docker技术是什么?
  2. 应对 Docker 网络功能难题的挑战与思考
  3. 如何实现 Docker 与分布式数据库结合
  4. docker 使用入门
  5. mysql新增纪录中某设有默认值的字段为nul
  6. 用 Docker 无脑备份数据库
  7. HBase 入门笔记-数据落地篇
  8. Docker 常用命令梳理
  9. 只要一小时,零基础入门Docker
  10. 浅谈 Docker 容器与镜像