Android -- Camera源碼簡(jiǎn)析,啟動(dòng)流程
com.android.camera.Camera.java,主要的實(shí)現(xiàn)Activity,繼承于ActivityBase。
本文引用地址:http://www.ex-cimer.com/article/201609/304303.htmActivityBase
在ActivityBase中執(zhí)行流程:
onCreate中進(jìn)行判斷是否是平板;
onResume中判斷是否鎖屏,鎖屏camera不存在時(shí)候,mOnResumePending置為true,否則置為false并執(zhí)行doOnResume;
onWindowFocusChanged中判斷是否獲取到焦點(diǎn)mOnResumePending,滿足的話執(zhí)行doOnResume;
onPause中將mOnResumePending置為false;
Camera.java
接下來(lái)分析Camera.java,執(zhí)行流程:
1、onCreate
復(fù)制代碼
// 獲得攝像頭的數(shù)量,前置和后置
getPreferredCameraId();
// 獲得對(duì)焦設(shè)置eg:連續(xù)對(duì)焦或者其它
String[] defaultFocusModes = getResources().getStringArray(R.array.pref_camera_focusmode_default_array);
//實(shí)例化Focus管理對(duì)象
mFocusManager = new FocusManager(mPreferences, defaultFocusModes);
// 開啟線程來(lái)啟動(dòng)攝像頭
mCameraOpenThread.start();
// 是否是第三方應(yīng)用啟動(dòng)拍照功能
mIsImageCaptureIntent = isImageCaptureIntent();
// 設(shè)置UI布局文件
setContentView(R.layout.camera);
if (mIsImageCaptureIntent) {
// 當(dāng)?shù)谌狡渌团恼?,需要顯示不同的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);
}
// 一個(gè)能旋轉(zhuǎn)的dialog.比如相機(jī)設(shè)置的dialog,這個(gè)類實(shí)現(xiàn)了旋轉(zhuǎn)的父類
mRotateDialog = new RotateDialogController(this, R.layout.rotate_dialog);
// 設(shè)置camera的ID,寫道SharedPreference中
mPreferences.setLocalId(this, mCameraId);
// 更新preference
CameraSettings.upgradeLocalPreferences(mPreferences.getLocal());
// 獲得相機(jī)數(shù)
mNumberOfCameras = CameraHolder.instance().getNumberOfCameras();
// 貌似是獲得是否是快速拍照
mQuickCapture = getIntent().getBooleanExtra(EXTRA_QUICK_CAPTURE, false);
// 為當(dāng)前的preview重置曝光值
resetExposureCompensation();
// 隱藏系統(tǒng)導(dǎo)航欄等
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 {
// 這個(gè)join語(yǔ)句就是為了保證openCamera的線程執(zhí)行完后,當(dāng)前的線程才開始運(yùn)行。主要是為了確保camera設(shè)備被打開了
mCameraOpenThread.join();
// 線程執(zhí)行完后置為空來(lái)讓系統(tǒng)回收資源
mCameraOpenThread = null;
if (mOpenCameraFail) {
// 打開camera失敗,顯示“無(wú)法連接到相機(jī)”
Util.showErrorAndFinish(this, R.string.cannot_connect_camera);
return;
} else if (mCameraDisabled) {
// 由于安全政策限制,相機(jī)已被停用
Util.showErrorAndFinish(this, R.string.camera_disabled);
return;
}
} catch (InterruptedException ex) {
// ignore
}
//開啟顯示的子線程
mCameraPreviewThread.start();
if (mIsImageCaptureIntent) {
//如果是第三方開啟的 ,setupCaptureParams 設(shè)置拍照的參數(shù)
setupCaptureParams();
} else {
//設(shè)置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);
//攝像頭ID
mBackCameraId = 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;
復(fù)制代碼
2、surfaceCreated
啥都沒(méi)做
3、surfaceChanged
復(fù)制代碼
// 確保在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
評(píng)論