您的位置:首页 > 移动开发 > Android开发

Camera安卓源码剖析-源码中的设计模式实例

2017-07-06 16:10 393 查看
环境:Android 7.1.1 Source Code —— Camera2

一.策略模式

在CameraActivity.java中,将Camera2OneCameraOpener&Camera2OneCameraManager的实例化放到OneCameraModule.java中,运用了取变封装原则,自身仅提供interface OneCameraOpener和interface OneCameraManager,将OneCameraOpener&OneCameraManager的实例化分离出去,降低耦合性与依赖度,采用与OneCameraModule组合的方式,增加了系统的弹性。



CameraActivity.java

public class CameraActivity extends QuickActivity
implements AppController, CameraAgent.CameraOpenCallback,
ShareActionProvider.OnShareTargetSelectedListener {

...
mOneCameraOpener = OneCameraModule.provideOneCameraOpener(
mFeatureConfig,
mAppContext,
mActiveCameraDeviceTracker,
ResolutionUtil.getDisplayMetrics(this));
mOneCameraManager = OneCameraModule.provideOneCameraManager();
...
}


OneCameraModule.java
public final class OneCameraModule {
private OneCameraModule(){}

public static OneCameraOpener provideOneCameraOpener(
OneCameraFeatureConfig featureConfig,
Context context,
ActiveCameraDeviceTracker activeCameraDeviceTracker,
DisplayMetrics displayMetrics) throws OneCameraException {
Optional<OneCameraOpener> 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();
}

public static OneCameraManager provideOneCameraManager() throws OneCameraException {
Optional<Camera2OneCameraManagerImpl> camera2HwManager = Camera2OneCameraManagerImpl
.create();
if (camera2HwManager.isPresent()) {
return camera2HwManager.get();
}

Optional<LegacyOneCameraManagerImpl> legacyHwManager = LegacyOneCameraManagerImpl.instance();
if (legacyHwManager.isPresent()) {
return legacyHwManager.get();
}

throw new OneCameraException("No hardware manager is available.");
}
}


二.观察者模式

在以下的代码中,mAppController作为一个Subject(主题),而PreviewStatusListener作为一个Observer(观察者)。mPreviewStatusListener实现了interface PreviewStatusListener, 并且保有一个Subject的实例。 而在Subject中有一个观察这个注册方法叫做
setPreviewStatusListener()
。 Observer会利用自身保有的Subject实例的注册方法将自己注册为观察者。在此观察者例子中,Subject采用“推”的方式向已注册的观察者发送信息。

观察者模式做到了subject与observer之间的松耦合原则,只要两者的接口不变,我们可以随意改动两者而不影响使用。



CaptureModule.java

public class CaptureModule extends CameraModule {

...
private final PreviewStatusListener mPreviewStatusListener = new PreviewStatusListener() {};
...
mAppController.setPreviewStatusListener(mPreviewStatusListener);
...
}


三. 抽象工厂模式

抽象工厂模式提供了一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。“针对接口编程,不针对实现编程”



Camera2OneCameraOpenerImpl.java

...
try {
CameraCharacteristics characteristics = mCameraManager
.getCameraCharacteristics(device.getId());
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();
}
...


OneCameraCreator.java

public class OneCameraCreator {

public static OneCamera create(){

switch (captureSupportLevel) {
case LIMITED_JPEG:
case LEGACY_JPEG:
cameraFactory = new SimpleOneCameraFactory(ImageFormat.JPEG,
featureConfig.getMaxAllowedImageReaderCount(),
imageRotationCalculator);
break;
...
case ZSL:
cameraFactory = new ZslOneCameraFactory(ImageFormat.YUV_420_888,
featureConfig.getMaxAllowedImageReaderCount());
...
break;
}
}

}


SimpleOneCameraFactory.java

public class SimpleOneCameraFactory implements OneCameraFactory {

public SimpleOneCameraFactory(int imageFormat, int maxImageCount,
ImageRotationCalculator imageRotationCalculator) {
mImageFormat = imageFormat;
mMaxImageCount = maxImageCount;
mImageRotationCalculator = imageRotationCalculator;
}

@Override
public OneCamera createOneCamera() {...}


四. 装饰者模式

装饰者模式,动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。 对扩展开放,对修改关闭

在以下的代码中,我们在SimpleOneCameraFactory创建了一个rootTemplate,他是一个RequestTemplate类,并传入了一个CameraDeviceRequestBuilderFactory。

而后,将此rootTemplate传入了BasicCameraFactory中,在BasicCameraFactory中执行
RequestTemplate requestTemplate = new RequestTemplate(rootTemplate);
,也就是说用一个新的RequestTemplate将原始的rootTemplate包装起来。 之后执行一个set操作。

SimpleOneCameraFactory.java

...
RequestTemplate rootBuilder = new RequestTemplate(new CameraDeviceRequestBuilderFactory(device));
// The shared image reader must be wired to receive every
// timestamp for every image (including the preview).
rootBuilder.addResponseListener(
ResponseListeners.forTimestamps(globalTimestampCallback));
rootBuilder.addStream(new SimpleCaptureStream(previewSurface));
rootBuilder.addResponseListener(ResponseListeners.forFinalMetadata(
metadataCallback));

FrameServer ephemeralFrameServer =
frameServerComponent.provideEphemeralFrameServer();

// Create basic functionality (zoom, AE, AF).
BasicCameraFactory basicCameraFactory = new BasicCameraFactory(new Lifetime(cameraLifetime),characteristics,
ephemeralFrameServer,
rootBuilder,
cameraCommandExecutor,
new BasicPreviewCommandFactory(ephemeralFrameServer),
flashSetting,
exposureSetting,
zoomState,
hdrSceneSetting,
CameraDevice.TEMPLATE_PREVIEW);
...


BasicCameraFactory.java

public class BasicCameraFactory {

...
public BasicCameraFactory(Lifetime lifetime,
OneCameraCharacteristics cameraCharacteristics,
FrameServer frameServer,
RequestBuilder.Factory rootTemplate,
CameraCommandExecutor cameraCommandExecutor,
PreviewCommandFactory previewCommandFactory,
Observable<OneCamera.PhotoCaptureParameters.Flash> flash,
Observable<Integer> exposure,
Observable<Float> zoom,
Observable<Boolean> hdrSceneSetting,
int templateType) {
RequestTemplate requestTemplate = new RequestTemplate(rootTemplate);
requestTemplate.setParam(
CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
requestTemplate.setParam(
CaptureRequest.CONTROL_AE_MODE, new FlashBasedAEMode(flash, hdrSceneSetting));
requestTemplate.setParam(
CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, exposure);
...
}
}


RequestTemplate.java

public class RequestTemplate implements RequestBuilder.Factory, ResponseManager {

...
private final RequestBuilder.Factory mRequestBuilderFactory;
private final Set<ResponseListener> mResponseListeners;
private final List<Parameter<?>> mParameters;
private final List<CaptureStream> mCaptureStreams;

public RequestTemplate(RequestBuilder.Factory requestBuilderFactory) {
mRequestBuilderFactory = requestBuilderFactory;
mResponseListeners = new HashSet<>();
mParameters = new ArrayList<>();
mCaptureStreams = new ArrayList<>();
}
...
@Override
public RequestBuilder create(int templateType) throws CameraAccessException {
RequestBuilder builder = mRequestBuilderFactory.create(templateType);
for (Parameter param : mParameters) {
param.addToBuilder(builder);
}
for (ResponseListener listener : mResponseListeners) {
builder.addResponseListener(listener);
}
for (CaptureStream stream : mCaptureStreams) {
builder.addStream(stream);
}
return builder;
}
}


之后当我们对BasicCameraFactory中新建的RequestTemplate执行
create()
操作时,就会出现如下的调用情形:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息