Android,androidadt
com.android.camera.Camera.java,主要的實現Activity,繼承於ActivityBase。
ActivityBase
在ActivityBase中執行流程:
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;
我是天王蓋地虎的分割線