
8种机械键盘轴体对比
本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?
转载请注明出处。
前言
今天开始来梳理Camera模块的整体流程,代码基于Android O上Camera2模块来分析。
Camera模块是比较复杂的,贯穿整个Android上下层,需要分多篇来整理。这篇只涉及app层的初始化逻辑。
流程
依惯例,先上图。

下面根据此流程图来一步步细化。
CameraActivity的初始化
Camera模块的launcher入口即是CameraActivity,其继承自QuickActivity,QuickActivity的作用是解决两次onResume的bug,所以我们不必关心,直接来看CameraActivity中的onCreateTasks方法(调用自QuickActivity中的onCreate方法)。
1.onCreateTasks
文件位置:Camera2/src/com/android/camera/CameraActivity.java
public void onCreateTasks(Bundle state) {
//一些初始化配置和检查
......
//初始化mOneCameraOpener,后面打开相机时会用到,需留意
try {
mOneCameraOpener = OneCameraModule.provideOneCameraOpener(
mFeatureConfig,
mAppContext,
mActiveCameraDeviceTracker,
ResolutionUtil.getDisplayMetrics(this));
mOneCameraManager = OneCameraModule.provideOneCameraManager();
} catch (OneCameraException e) {
// Log error and continue start process while showing error dialog..
Log.e(TAG, "Creating camera manager failed.", e);
mFatalErrorHandler.onGenericCameraAccessFailure();
}
profile.mark("OneCameraManager.get");
try {
mCameraController = new CameraController(mAppContext, this, mMainHandler,
CameraAgentFactory.getAndroidCameraAgent(mAppContext,
CameraAgentFactory.CameraApi.API_1),
CameraAgentFactory.getAndroidCameraAgent(mAppContext,
CameraAgentFactory.CameraApi.AUTO),
mActiveCameraDeviceTracker);
mCameraController.setCameraExceptionHandler(
new CameraExceptionHandler(mCameraExceptionCallback, mMainHandler));
} catch (AssertionError e) {
Log.e(TAG, "Creating camera controller failed.", e);
mFatalErrorHandler.onGenericCameraAccessFailure();
}
// TODO: Try to move all the resources allocation to happen as soon as
// possible so we can call module.init() at the earliest time.
mModuleManager = new ModuleManagerImpl();
ModulesInfo.setupModules(mAppContext, mModuleManager, mFeatureConfig);
//一些配置和界面显示的准备
......
//camera module的初始化配置
setModuleFromModeIndex(getModeIndex());
profile.mark();
mCameraAppUI.prepareModuleUI();
profile.mark("Init Current Module UI");
mCurrentModule.init(this, isSecureCamera(), isCaptureIntent());
profile.mark("Init CurrentModule");
......
}
我们先不去关心mOneCameraOpener和mCameraController,先继续来看module的初始化。
2.ModulesInfo.setupModules
文件位置:Camera2/src/com/android/camera/module/ModulesInfo.java
public static void setupModules(Context context, ModuleManager moduleManager,
OneCameraFeatureConfig config) {
Resources res = context.getResources();
int photoModuleId = context.getResources().getInteger(R.integer.camera_mode_photo);
registerPhotoModule(moduleManager, photoModuleId, SettingsScopeNamespaces.PHOTO,
config.isUsingCaptureModule());
moduleManager.setDefaultModuleIndex(photoModuleId);
registerVideoModule(moduleManager, res.getInteger(R.integer.camera_mode_video),
SettingsScopeNamespaces.VIDEO);
if (PhotoSphereHelper.hasLightCycleCapture(context)) {
registerWideAngleModule(moduleManager, res.getInteger(R.integer.camera_mode_panorama),
SettingsScopeNamespaces.PANORAMA);
registerPhotoSphereModule(moduleManager,
res.getInteger(R.integer.camera_mode_photosphere),
SettingsScopeNamespaces.PANORAMA);
}
if (RefocusHelper.hasRefocusCapture(context)) {
registerRefocusModule(moduleManager, res.getInteger(R.integer.camera_mode_refocus),
SettingsScopeNamespaces.REFOCUS);
}
if (GcamHelper.hasGcamAsSeparateModule(config)) {
registerGcamModule(moduleManager, res.getInteger(R.integer.camera_mode_gcam),
SettingsScopeNamespaces.PHOTO,
config.getHdrPlusSupportLevel(OneCamera.Facing.BACK));
}
int imageCaptureIntentModuleId = res.getInteger(R.integer.camera_mode_capture_intent);
registerCaptureIntentModule(moduleManager, imageCaptureIntentModuleId,
SettingsScopeNamespaces.PHOTO, config.isUsingCaptureModule());
}
可以看到,这个方法用来注册所用可用的module,默认的module则是从R.integer.camera_mode_photo中读取。这里对应的是registerPhotoModule。来看ModulesInfo的registerPhotoModule方法:
private static void registerPhotoModule(ModuleManager moduleManager, final int moduleId,
final String namespace, final boolean enableCaptureModule) {
moduleManager.registerModule(new ModuleManager.ModuleAgent() {
@Override
public int getModuleId() {
return moduleId;
}
@Override
public boolean requestAppForCamera() {
// The PhotoModule requests the old app camere, while the new
// capture module is using OneCamera. At some point we'll
// refactor all modules to use OneCamera, then the new module
// doesn't have to manage it itself.
return !enableCaptureModule;
}
@Override
public String getScopeNamespace() {
return namespace;
}
@Override
public ModuleController createModule(AppController app, Intent intent) {
Log.v(TAG, "EnableCaptureModule = " + enableCaptureModule);
return enableCaptureModule ? new CaptureModule(app) : new PhotoModule(app);
}
});
}
可以看到,这里调用ModuleManager的registerModule方法,传入ModuleAgent对象作为参数,在createModule中,会根据enableCaptureModule值来判断,返回不同的module对象,这里对应的是CaptureModule。
回到CameraActivity中,继续。
3.setModuleFromModeIndex
文件位置:Camera2/src/com/android/camera/CameraActivity.java
private void setModuleFromModeIndex(int modeIndex) {
//这里使用mModuleManager根据modeIndex来getModuleAgent,也就是拿到了上面步骤中注册的ModuleAgent对象,这里对应的即是registerPhotoModule中的匿名ModuleAgent对象
ModuleManagerImpl.ModuleAgent agent = mModuleManager.getModuleAgent(modeIndex);
if (agent == null) {
return;
}
if (!agent.requestAppForCamera()) {
mCameraController.closeCamera(true);
}
//这里根据ModuleAgent对象,初始化mCurrentModeIndex和mCurrentModule
//那么,也就是说,这里的mCurrentModule对应的是一个CaptureModule对象
mCurrentModeIndex = agent.getModuleId();
mCurrentModule = (CameraModule) agent.createModule(this, getIntent());
}
到了这里,就已经将CaptureModule创建关联完毕。Camera中,使用不同的module来处理不同的功能模式,其他的module也是类似的。
继续看CameraActivity中的mCameraAppUI.prepareModuleUI()调用。
4.mCameraAppUI.prepareModuleUI
文件位置:Camera2/src/com/android/camera/app/CameraAppUI.java
public void prepareModuleUI() {
......
mTextureView = (TextureView) mCameraRootView.findViewById(R.id.preview_content);
//构造mTextureViewHelper并配置
mTextureViewHelper = new TextureViewHelper(mTextureView, mCaptureLayoutHelper,
mController.getCameraProvider(), mController);
mTextureViewHelper.setSurfaceTextureListener(this);
mTextureViewHelper.setOnLayoutChangeListener(mPreviewLayoutChangeListener);
......
}
在此方法中,构造了mTextureViewHelper,并调用其setSurfaceTextureListener方法,传入this。先来看TextureViewHelper构造方法。
public TextureViewHelper(TextureView preview, CaptureLayoutHelper helper,
CameraProvider cameraProvider, AppController appController) {
mPreview = preview;
mCameraProvider = cameraProvider;
//传入的mTextureView先与自身关联
mPreview.addOnLayoutChangeListener(this);
mPreview.setSurfaceTextureListener(this);
mCaptureLayoutHelper = helper;
mAppController = appController;
}
在这构造方法中,又调用了mPreview.setSurfaceTextureListener.
5.TextureViewHelper.setSurfaceTextureListener
文件位置:Camera2/src/com/android/camera/TextureViewHelper.java
public void setSurfaceTextureListener(TextureView.SurfaceTextureListener listener) {
mSurfaceTextureListener = listener;
}
来看看mSurfaceTextureListener的使用位置:
......
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
......
if (mSurfaceTextureListener != null) {
mSurfaceTextureListener.onSurfaceTextureAvailable(surface, width, height);
}
}
......
到了这时,CameraAppUI做了些什么呢,整理下。
1.new了一个mTextureViewHelper,在mTextureViewHelper中,为mTextureView配置了setSurfaceTextureListener。
2.紧接着,调用了mTextureViewHelper.setSurfaceTextureListener,传入this,会在mTextureView的SurfaceTextureListener回调时,回调到this中的对应接口,即回调到CameraAppUI中。
好,那么继续看下CameraAppUI中的SurfaceTextureListener:
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mSurface = surface;
mSurfaceWidth = width;
mSurfaceHeight = height;
Log.v(TAG, "SurfaceTexture is available");
//可以看到,这一步又会调用mPreviewStatusListener的onSurfaceTextureAvailable
if (mPreviewStatusListener != null) {
mPreviewStatusListener.onSurfaceTextureAvailable(surface, width, height);
}
enableModeOptions();
}
3.那么也就是说,在回调到CameraAppUI中后,又会回调到mPreviewStatusListener中。那么mPreviewStatusListener是什么?
查看CameraAppUI.java的代码,可以发现,mPreviewStatusListener是通过setPreviewStatusListener方法配置的:
public void setPreviewStatusListener(PreviewStatusListener previewStatusListener) {
mPreviewStatusListener = previewStatusListener;
if (mPreviewStatusListener != null) {
onPreviewListenerChanged();
}
}
至此,也就是说,CameraAppUI中的mTextureView的SurfaceTextureListener,最终会回调到CameraAppUI中的mPreviewStatusListener对象中,而这一对象,是通过调用CameraAppUI的setPreviewStatusListener方法来设置的。
这里暂时放下,我们继续回到CameraActivity中。
6.mCurrentModule.init
回到CameraActivity的onCreateTasks中。
第3步中,mCurrentModule已经是CaptureModule对象了,所以这里会调用当前module的init方法,这里即CaptureModule的init方法。
文件位置:Camera2/src/com/android/camera/CaptureModule.java
public void init(CameraActivity activity, boolean isSecureCamera, boolean isCaptureIntent) {
......
//这里通过mAppController拿到了mOneCameraOpener
mOneCameraOpener = mAppController.getCameraOpener();
try {
mOneCameraManager = OneCameraModule.provideOneCameraManager();
} catch (OneCameraException e) {
Log.e(TAG, "Unable to provide a OneCameraManager. ", e);
}
......
//构造了CaptureModuleUI,并调用了mAppController的setPreviewStatusListener
mUI = new CaptureModuleUI(activity, mAppController.getModuleLayoutRoot(), mUIListener);
mAppController.setPreviewStatusListener(mPreviewStatusListener);
synchronized (mSurfaceTextureLock) {
mPreviewSurfaceTexture = mAppController.getCameraAppUI().getSurfaceTexture();
}
......
}
那么我们首先想要知道的是,mAppController是个什么呢?
public CaptureModule(AppController appController, boolean stickyHdr) {
super(appController);
Profile guard = mProfiler.create("new CaptureModule").start();
mPaused = true;
mMainThread = MainThread.create();
mAppController = appController;
......
}
可以发现,mAppController是在构造CaptureModule是传入的,而CaptureModule是在第3步,即CameraActivity中的setModuleFromModeIndex方法中构造的。
mCurrentModule = (CameraModule) agent.createModule(this, getIntent());
那么也就是说,CaptureModule中的mAppController对象,其实就是CameraActivity。
而在此init方法中,通过此mAppController拿到mOneCameraOpener,并调用了mAppController的setPreviewStatusListener,传入了mPreviewStatusListener对象。
那么我们接着来看CameraActivity的setPreviewStatusListener。
7.mAppController.setPreviewStatusListener
文件位置:Camera2/src/com/android/camera/CameraActivity.java
public void setPreviewStatusListener(PreviewStatusListener previewStatusListener) {
mCameraAppUI.setPreviewStatusListener(previewStatusListener);
}
这一步很简单,直接调用mCameraAppUI的setPreviewStatusListener方法。
而这正是第5步中,最终给CameraAppUI中mTextureView设置setPreviewStatusListener的源头。
8.mCameraAppUI.setPreviewStatusListener
文件位置:Camera2/src/com/android/camera/app/CameraAppUI.java
public void setPreviewStatusListener(PreviewStatusListener previewStatusListener) {
mPreviewStatusListener = previewStatusListener;
if (mPreviewStatusListener != null) {
onPreviewListenerChanged();
}
}
到了这时,也就是说,经过了多次中转,最终响应CameraAppUI中mTextureView中PreviewStatusListener回调的,是CaptureModule中的mPreviewStatusListener对象。
打开相机
9/10.onSurfaceTextureAvailable
这两步也就不再赘述了,最终会回调的CaptureModule中的mPreviewStatusListener对象。
private final PreviewStatusListener mPreviewStatusListener = new PreviewStatusListener() {
......
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
Log.d(TAG, "onSurfaceTextureAvailable");
// Force to re-apply transform matrix here as a workaround for
// b/11168275
updatePreviewTransform(width, height, true);
synchronized (mSurfaceTextureLock) {
mPreviewSurfaceTexture = surface;
}
//这里去打开相机
reopenCamera();
}
......
};
其他回调方法先不做关注,这里可以发喜,在onSurfaceTextureAvailable后,就会去打开相机。
11.reopenCamera
文件位置:Camera2/src/com/android/camera/CaptureModule.java
private void reopenCamera() {
if (mPaused) {
return;
}
AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
@Override
public void run() {
closeCamera();
if(!mAppController.isPaused()) {
openCameraAndStartPreview();
}
}
});
}
可以看到,这里主要是去调用openCameraAndStartPreview方法。
12.openCameraAndStartPreview
文件位置:Camera2/src/com/android/camera/CaptureModule.java
private void openCameraAndStartPreview() {
......
CameraId cameraId = mOneCameraManager.findFirstCameraFacing(mCameraFacing);
//留意一下这里open方法传入的诸多参数,这些参数比较重要
mOneCameraOpener.open(cameraId, captureSetting, mCameraHandler, mainThread,
imageRotationCalculator, mBurstController, mSoundPlayer,
new OpenCallback() {
......
@Override
public void onCameraOpened(@Nonnull final OneCamera camera) {
Log.d(TAG, "onCameraOpened: " + camera);
mCamera = camera;
.......
// TODO: Consider rolling these two calls into one.
camera.startPreview(new Surface(getPreviewSurfaceTexture()),
new CaptureReadyCallback() {
......
@Override
public void onReadyForCapture() {
// We must release this lock here,
// before posting to the main handler
// since we may be blocked in pause(),
// getting ready to close the camera.
mCameraOpenCloseLock.release();
mMainThread.execute(new Runnable() {
@Override
public void run() {
Log.d(TAG, "Ready for capture.");
if (mCamera == null) {
Log.d(TAG, "Camera closed, aborting.");
return;
}
onPreviewStarted();
......
}
});
}
});
}
}, mAppController.getFatalErrorHandler());
}
可以看到,主要通过mOneCameraOpener的open方法来打开相机,并且设置了OpenCallback回调。
而mOneCameraOpener是在第6步中,即CaptureModule init时,从CameraActivity,通过getCameraOpener方法拿到的。
而CameraActivity中的getCameraOpener方法如下:
public OneCameraOpener getCameraOpener() {
return mOneCameraOpener;
}
CameraActivity中的mOneCameraOpener,则是在第1步中,即CameraActivity中onCreateTasks中创建的。
也就是说,实际的打开相机操作,是CameraActivity中的mOneCameraOpener对象来操作的。
mOneCameraOpener = OneCameraModule.provideOneCameraOpener(
mFeatureConfig,
mAppContext,
mActiveCameraDeviceTracker,
ResolutionUtil.getDisplayMetrics(this));
mOneCameraManager = OneCameraModule.provideOneCameraManager();
那我们继续来看OneCameraModule。
文件位置:Camera2/src/com/android/camera/one/OneCameraModule.java
public static OneCameraOpener provideOneCameraOpener(
OneCameraFeatureConfig featureConfig,
Context context,
ActiveCameraDeviceTracker activeCameraDeviceTracker,
DisplayMetrics displayMetrics) throws OneCameraException {
//使用Camera2OneCameraOpenerImpl生成
Optional manager = Camera2OneCameraOpenerImpl.create(
featureConfig, context, activeCameraDeviceTracker, displayMetrics);
if (!manager.isPresent()) {
manager = LegacyOneCameraOpenerImpl.create();
}
if (!manager.isPresent()) {
throw new OneCameraException("No camera manager is available.");
}
return manager.get();
}
那么我们继续看Camera2OneCameraOpenerImpl。
文件位置:Camera2/src/com/android/camera/one/v2/Camera2OneCameraOpenerImpl.java
public static Optional create(
OneCameraFeatureConfig featureConfig,
Context context,
ActiveCameraDeviceTracker activeCameraDeviceTracker,
DisplayMetrics displayMetrics) {
if (!ApiHelper.HAS_CAMERA_2_API) {
return Optional.absent();
}
CameraManager cameraManager;
try {
cameraManager = AndroidServices.instance().provideCameraManager();
} catch (IllegalStateException ex) {
Log.e(TAG, "camera2.CameraManager is not available.");
return Optional.absent();
}
OneCameraOpener oneCameraOpener = new Camera2OneCameraOpenerImpl(
featureConfig,
context,
cameraManager,
activeCameraDeviceTracker,
displayMetrics);
return Optional.of(oneCameraOpener);
}
可以看到,最终返回的就是Camera2OneCameraOpenerImpl对象。
也就是说,调用的是Camera2OneCameraOpenerImpl的open方法。
13/14.openCamera
文件位置:Camera2/src/com/android/camera/one/v2/Camera2OneCameraOpenerImpl.java
public void open(
final CameraId cameraKey,
final OneCameraCaptureSetting captureSetting,
final Handler handler,
final MainThread mainThread,
final ImageRotationCalculator imageRotationCalculator,
final BurstFacade burstController,
final SoundPlayer soundPlayer,
final OpenCallback openCallback,
final FatalErrorHandler fatalErrorHandler) {
try {
Log.i(TAG, "Opening Camera: " + cameraKey);
mActiveCameraDeviceTracker.onCameraOpening(cameraKey);
//mCameraManager.openCamera时只用到3个参数。cameraKey、StateCallback、handler
//cameraKey即是CaptureModule.java中mOneCameraOpener.open调用时传入的cameraId
//handler即是CaptureModule.java中mOneCameraOpener.open调用时传入的mCameraHandler
mCameraManager.openCamera(cameraKey.getValue(), new CameraDevice.StateCallback() {
// We may get multiple calls to StateCallback, but only the
// first callback indicates the status of the camera-opening
// operation. For example, we may receive onOpened() and later
// onClosed(), but only the first should be relayed to
// openCallback.
private boolean isFirstCallback = true;
@Override
public void onDisconnected(CameraDevice device) {
......
}
@Override
public void onClosed(CameraDevice device) {
......
}
@Override
public void onError(CameraDevice device, int error) {
......
}
//需要注意下,在camera打开后,framework回调StateCallback时,会传回一个CameraDevice参数
@Override
public void onOpened(CameraDevice device) {
if (isFirstCallback) {
isFirstCallback = false;
try {
CameraCharacteristics characteristics = mCameraManager
.getCameraCharacteristics(device.getId());
// TODO: Set boolean based on whether HDR+ is
// enabled.
//这里的大部分参数,即是在mOneCameraOpener.open时传入的
//也就是说,传入的参数中,有很多都是在camera open之后使用的
OneCamera oneCamera = OneCameraCreator.create(
device,
characteristics,
mFeatureConfig,
captureSetting,
mDisplayMetrics,
mContext,
mainThread,
imageRotationCalculator,
burstController,
soundPlayer, fatalErrorHandler);
if (oneCamera != null) {
openCallback.onCameraOpened(oneCamera);
} else {
Log.d(TAG, "Could not construct a OneCamera object!");
openCallback.onFailure();
}
} catch (CameraAccessException e) {
Log.d(TAG, "Could not get camera characteristics", e);
openCallback.onFailure();
} catch (OneCameraAccessException e) {
Log.d(TAG, "Could not create OneCamera", e);
openCallback.onFailure();
}
}
}
}, handler);
} catch (CameraAccessException ex) {
......
} catch (UnsupportedOperationException ex) {
......
} catch (SecurityException ex) {
......
}
}
可以看到,这里主要是通过调用mCameraManager.openCamera方法来打开相机,并设置了CameraDevice.StateCallback回调。
camera的具体open还有很多,这里先跳过,只关注app初始化逻辑。
那么接下来,在camera成功打开后,回调到onOpened方法。
相机预览
15/16/17.startPreview
在onOpened后,创建一个OneCamera对象,并回调openCallback.onCameraOpened(oneCamera);
而这里的openCallback对象,正是第12步,openCameraAndStartPreview时设置的。
文件位置:Camera2/src/com/android/camera/CaptureModule.java
public void onCameraOpened(@Nonnull final OneCamera camera) {
Log.d(TAG, "onCameraOpened: " + camera);
mCamera = camera;
.......
// TODO: Consider rolling these two calls into one.
camera.startPreview(new Surface(getPreviewSurfaceTexture()),
new CaptureReadyCallback() {
......
@Override
public void onReadyForCapture() {
// We must release this lock here,
// before posting to the main handler
// since we may be blocked in pause(),
// getting ready to close the camera.
mCameraOpenCloseLock.release();
mMainThread.execute(new Runnable() {
@Override
public void run() {
Log.d(TAG, "Ready for capture.");
if (mCamera == null) {
Log.d(TAG, "Camera closed, aborting.");
return;
}
onPreviewStarted();
......
}
});
}
});
}
这里,即调用了传入的OneCamera的startPreview方法。
我们再来看下OneCamera是什么,它在Camera2OneCameraOpenerImpl.java中new CameraDevice.StateCallback()的onOpened回调中被构造。
OneCamera oneCamera = OneCameraCreator.create(
device,
characteristics,
mFeatureConfig,
captureSetting,
mDisplayMetrics,
mContext,
mainThread,
imageRotationCalculator,
burstController,
soundPlayer, fatalErrorHandler);
那么来看看OneCameraCreator。
文件位置:Camera2/src_pd/com/android/camera/one/v2/OneCameraCreator.java
public static OneCamera create(
CameraDevice device,
CameraCharacteristics characteristics,
OneCameraFeatureConfig featureConfig,
OneCameraCaptureSetting captureSetting,
DisplayMetrics displayMetrics,
Context context,
MainThread mainThread,
ImageRotationCalculator imageRotationCalculator,
BurstFacade burstController,
SoundPlayer soundPlayer,
FatalErrorHandler fatalErrorHandler) throws OneCameraAccessException {
// TODO: Might want to switch current camera to vendor HDR.
CaptureSupportLevel captureSupportLevel = featureConfig
.getCaptureSupportLevel(characteristics);
Log.i(TAG, "Camera support level: " + captureSupportLevel.name());
OneCameraCharacteristics oneCharacteristics =
new OneCameraCharacteristicsImpl(characteristics);
PictureSizeCalculator pictureSizeCalculator =
new PictureSizeCalculator(oneCharacteristics);
PictureSizeCalculator.Configuration configuration = null;
OneCameraFactory cameraFactory = null;
ImageSaver.Builder imageSaverBuilder = null;
ImageBackend imageBackend = ProcessingServiceManager.instance().getImageBackend();
// Depending on the support level of the camera, choose the right
// configuration.
switch (captureSupportLevel) {
case LIMITED_JPEG:
case LEGACY_JPEG:
// LIMITED and LEGACY have different picture takers which will
// be selected by the support level that is passes into
// #createOneCamera below - otherwise they use the same OneCamera and image backend.
cameraFactory = new SimpleOneCameraFactory(ImageFormat.JPEG,
featureConfig.getMaxAllowedImageReaderCount(),
imageRotationCalculator);
configuration = pictureSizeCalculator.computeConfiguration(
captureSetting.getCaptureSize(),
ImageFormat.JPEG);
imageSaverBuilder = new JpegImageBackendImageSaver(imageRotationCalculator,
imageBackend, configuration.getPostCaptureCrop());
break;
case LIMITED_YUV:
// Same as above, but we're using YUV images.
......
break;
case ZSL:
// ZSL has its own OneCamera and produces YUV images.
......
break;
}
Log.i(TAG, "Picture Size Configuration: " + configuration);
return cameraFactory.createOneCamera(new AndroidCameraDeviceProxy(device),
new OneCameraCharacteristicsImpl(characteristics),
captureSupportLevel,
mainThread,
configuration.getNativeOutputSize(),
imageSaverBuilder,
captureSetting.getFlashSetting(),
captureSetting.getExposureSetting(),
captureSetting.getHdrSceneSetting(),
burstController,
fatalErrorHandler);
}
可以看到,这里是根据不同的格式,选取不同的cameraFactory来处理。
这里我们继续看SimpleOneCameraFactory,在SimpleOneCameraFactory的createOneCamera方法中,最终返回了InitializedOneCameraFactory对象。而在InitializedOneCameraFactory的构造方法中,最终返回的是GenericOneCameraImpl对象。也就是说,这里的OneCamera,最终是一个GenericOneCameraImpl对象。
也就是说,这里接下来调用的是GenericOneCameraImpl对象的startPreview方法。
这部分内容这里不展开了,相机预览绘制流程应该还得单独来梳理下。
18/19/20/21/22.onPreviewStarted
文件位置:Camera2/src/com/android/camera/one/v2/initialization/GenericOneCameraImpl.java
public void startPreview(Surface surface, final CaptureReadyCallback listener) {
ListenableFuture result = mPreviewStarter.startPreview(surface);
Futures.addCallback(result, new FutureCallback() {
@Override
public void onSuccess(@Nonnull Void aVoid) {
listener.onReadyForCapture();
}
@Override
public void onFailure(@Nonnull Throwable throwable) {
listener.onSetupFailed();
}
});
}
在上述startPreview方法中,主要是调用mPreviewStarter对象的startPreview方法,并设置了回调。
这里的listener对象,即是在15/16/17.startPreview步中,设置的CaptureReadyCallback对象。
mMainThread.execute(new Runnable() {
@Override
public void run() {
Log.d(TAG, "Ready for capture.");
if (mCamera == null) {
Log.d(TAG, "Camera closed, aborting.");
return;
}
onPreviewStarted();
......
}
});
即,会去调用CaptureModule.java中的onPreviewStarted。
private void onPreviewStarted() {
if (mState == ModuleState.WATCH_FOR_NEXT_FRAME_AFTER_PREVIEW_STARTED) {
mState = ModuleState.UPDATE_TRANSFORM_ON_NEXT_SURFACE_TEXTURE_UPDATE;
}
mAppController.onPreviewStarted();
}
继续去调用CameraActivity中的onPreviewStarted。
public void onPreviewStarted() {
mCameraAppUI.onPreviewStarted();
}
CameraActivity又去调用CameraAppUI的onPreviewStarted。
public void onPreviewStarted() {
......
enableModeOptions();
}
至此,相机已经打开并且显示成功了。大体流程上,app层的启动过程基本完成。
小结
相机的具体打开过程,以及相机图像的预览过程。还需要进一步梳理。

赞个赏呗 ~
本文基于Android O上Camera2模块,梳理app层初始化逻辑。从CameraActivity的onCreateTasks方法开始,介绍了模块初始化、注册可用模块等步骤,还涉及OneCamera的创建及预览启动,最终完成相机打开与显示,后续还需梳理相机打开和图像预览具体过程。

被折叠的 条评论
为什么被折叠?



