设计模式的Builder模式[结合使用Android中的MediaRecorder来浅析]


##摘要:
java23种设计模式之一,英文叫Builder Pattern。其核心思想是将一个“复杂对象的构建算法”与它的“部件及组装方式”分离,使得构件算法和组装方式可以独立应对变化;复用同样的构建算法可以创建不同的表示,不同的构建过程可以复用相同的部件组装方式。

##友情提示:
本文为笔者自己理解,如有写的不对的地方,欢迎指出

版权申明
本文原创作者:章飞_906285288
作者的博客:http://blog.csdn.net/qq_29924041
转载请注明出处


##使用Builder模式来构建我们的MediaRecorder的参数对象
简述:

在Android的开发过程中,无处不见的builder模式,如系统的Dialog的时候采用的就是Builder模式,ImageLoader的初始化的过程中,同样也是。那什么是Builder模式呢?Builder模式又叫做构建者模式。举个最简单的例子:车子是由轮胎,底盘,发动机,方向盘,座椅等组成的。车子是一个类class,具体这些可以组装成奔驰车子,宝马车子等等。不同的参数可以组装成不同的车子。这就是Builder组装的对象。其核心思想是将一个“复杂对象的构建算法”与它的“部件及组装方式”分离,使得构件算法和组装方式可以独立应对变化;复用同样的构建算法可以创建不同的表示,不同的构建过程可以复用相同的部件组装方式。

以下代码是写的是一个Test代码。格式上面没有单独抽出来,MediaRecorder是通过构造一个Params的对象来进行实现的

package com.zzf.cit;import android.hardware.Camera;import android.media.MediaRecorder;import android.view.SurfaceHolder;import com.eques.cit.util.ELog;import java.io.File;import java.io.IOException;import java.util.Timer;import java.util.TimerTask;public class VideoRecorder {public static final String TAG = "VideoRecorder";public static final String ROOT_PATH = "/mnt/sdcard/zzf/record";private static VideoRecorder instance;private Params mParams;private MediaRecorder mMediaRecorder;private boolean isRecording = false;public static VideoRecorder getInstance(){if (instance == null) {synchronized (VideoRecorder.class) {if (instance == null) {instance = new VideoRecorder();}}}return instance;}public void setParams(Params mParams){this.mParams = mParams;}/** * 创建一个私有的无参的构造函数 */private VideoRecorder(){File file = new File(ROOT_PATH);if (!file.exists()) {file.mkdir();}}/** * 开始进行录像 */public void startRecord(){if (!isRecording){mMediaRecorder = new MediaRecorder();mMediaRecorder.reset();if (mParams.mCamera != null) {mParams.mCamera.unlock();}mMediaRecorder.setCamera(mParams.mCamera);mMediaRecorder.setAudioSource(mParams.audioSource);ELog.i(TAG,"mMediaRecorder.getMaxAmplitude:"+mMediaRecorder.getMaxAmplitude());mMediaRecorder.setVideoSource(mParams.videoSource);mMediaRecorder.setOutputFormat(mParams.outputFormat);mMediaRecorder.setAudioEncoder(mParams.audioEncoderType);mMediaRecorder.setVideoEncoder(mParams.videoEncoderType);mMediaRecorder.setVideoFrameRate(mParams.videoFrameRate);mMediaRecorder.setPreviewDisplay(mParams.mSurfaceHolder.getSurface());mMediaRecorder.setVideoSize(mParams.mVideoSize.width, mParams.mVideoSize.height);mMediaRecorder.setOutputFile(mParams.recorderPath);mMediaRecorder.setVideoEncodingBitRate(300 * 1024 * 5);mMediaRecorder.setMaxDuration(60 * 1000);mMediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {@Overridepublic void onInfo(MediaRecorder mr, int what, int extra) {}});Timer timer = new Timer();TimerTask timerTask = new TimerTask() {@Overridepublic void run() {if (isRecording){isRecording = false;}}};timer.schedule(timerTask,60 * 1000);try {mMediaRecorder.prepare();} catch (IllegalStateException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}mMediaRecorder.start();isRecording = true;}}/** * 停止录像 */public void stopRecord(){if (isRecording) {isRecording = false;if (mMediaRecorder != null) {if (mParams.mCamera != null) {mParams.mCamera.lock();}mMediaRecorder.stop();mMediaRecorder.release();mMediaRecorder = null;}}}}class Params{//录像的具体路径public String recorderPath;//音频音源public int audioSource;//视频源public int videoSource;//输出的格式public int outputFormat;//音频的编码类型public int audioEncoderType;//视频的编码类型public int videoEncoderType;public SurfaceHolder mSurfaceHolder;//视频的帧率public int videoFrameRate;//视频的大小public VideoSize mVideoSize;//public Camera mCamera;static class VideoSize{public int width;public int height;public VideoSize(int width,int height){this.width = width;this.height = height;}}public Params(Builder mBuilder){this.recorderPath = mBuilder.recorderPath;this.audioSource = mBuilder.audioSource;this.videoSource = mBuilder.videoSource;this.outputFormat = mBuilder.outputFormat;this.audioEncoderType = mBuilder.audioEncoderType;this.videoEncoderType = mBuilder.videoEncoderType;this.mSurfaceHolder = mBuilder.mSurfaceHolder;this.videoFrameRate = mBuilder.videoFrameRate;this.mVideoSize =mBuilder.mVideoSize;this.mCamera = mBuilder.mCamera;}static class Builder{//录像的具体路径public String recorderPath;//音频音源public int audioSource = MediaRecorder.AudioSource.MIC ;//视频源public int videoSource = MediaRecorder.VideoSource.CAMERA;//输出的格式public int outputFormat = MediaRecorder.OutputFormat.MPEG_4;//音频的编码类型public int audioEncoderType = MediaRecorder.AudioEncoder.AMR_NB;//视频的编码类型public int videoEncoderType = MediaRecorder.VideoEncoder.H264;public SurfaceHolder mSurfaceHolder;//视频的帧率public int videoFrameRate;//视频的大小public VideoSize mVideoSize;public Camera mCamera;public Builder(){}public Builder recorderPath(String recorderPath){this.recorderPath = recorderPath;return this;}public Builder audioSource(int audioSource){this.audioSource = audioSource;return this;}public Builder videoSource(int videoSource){this.videoSource = videoSource;return this;}public Builder outputFormat(int outputFormat){this.outputFormat = outputFormat;return this;}public Builder audioEncoderType(int audioEncoderType){this.audioEncoderType = audioEncoderType;return this;}public Builder videoEncoderType(int videoEncoderType){this.videoEncoderType = videoEncoderType;return this;}public Builder mSurfaceHolder(SurfaceHolder mSurfaceHolder){this.mSurfaceHolder = mSurfaceHolder;return this;}public Builder videoFrameRate(int videoFrameRate){this.videoFrameRate = videoFrameRate;return this;}public Builder mCamera(Camera mCamera){this.mCamera = mCamera;return this;}public Builder mVideoSize(VideoSize mVideoSize){if (mVideoSize != null) {this.mVideoSize = mVideoSize;}else{this.mVideoSize  = new VideoSize(854, 480);}return this;}public Params build(){return new Params(this);}}@Overridepublic String toString() {return "Params{" +"recorderPath='" + recorderPath + '\'' +", audioSource=" + audioSource +", videoSource=" + videoSource +", outputFormat=" + outputFormat +", audioEncoderType=" + audioEncoderType +", videoEncoderType=" + videoEncoderType +", mSurfaceHolder=" + mSurfaceHolder +", videoFrameRate=" + videoFrameRate +", mVideoSize=" + mVideoSize +", mCamera=" + mCamera +'}';}}

调用部分的代码,只截取部分的代码。

if (mVideoRecorder != null) {Params mParams = new Params.Builder().recorderPath(VideoRecorder.ROOT_PATH + File.separator + new SimpleDateFormat("yyyyMMddHHmmssSSS").format(System.currentTimeMillis())+".3gp").mSurfaceHolder(mSurfaceView.getHolder()).audioSource(MediaRecorder.AudioSource.CAMCORDER).audioEncoderType(MediaRecorder.AudioEncoder.AAC).videoSource(MediaRecorder.VideoSource.CAMERA).videoEncoderType(MediaRecorder.VideoEncoder.H263).mVideoSize(new VideoSize(854, 480)).videoFrameRate(30).outputFormat(MediaRecorder.OutputFormat.MPEG_4).mCamera(mCamera).build();Log.i(TAG,"PARAMS:"+mParams.toString());mVideoRecorder.setParams(mParams);mVideoRecorder.startRecord();}

当然在使用MediaRecorder时候,在Android中是要有权限限制的

        

Builder模式好处和优点

使用Builder模式必然会导致写两遍相关属性的代码和SETTER方法,看起来有点吃力不讨好。然而需要看到的是,客户端代码的可用性和可读性得到了大大提高。与此同时,构造函数的参数数量明显减少调用起来非常直观。

Builder方法另外一个优势在于,单个builder构建多个对象时Builder参数可在创建期间进行调整,还可以根据对象不同而进行改变。这就像我越来越推崇的以“不变”应“万变”。Builder模式特别适合那些属性个数很多的类,我认为没有必要给那些本不需要设置值传递参数(设置null)。

更多相关文章

  1. android没有告诉你的usr模式和eng模式的区别
  2. Android实现竖着的滑动刻度尺效果,选择身高(竖向的)Android实现滑动
  3. Android开发之模板模式初探
  4. Android(安卓)基础知识点
  5. Android(安卓)内功心法(1)——设计模式的原则和android中常用的
  6. Android中MVP模式实战版(一)
  7. Android(安卓)MVP+RXJava+Retrofit框架的初步构建
  8. 牛B的Android(安卓)UI--第18章 与用户交互相关的设计模式 (上)
  9. Anroid Wear OS 手表应用开发 - 微光模式 AmbientMode

随机推荐

  1. android中http访问总结
  2. 状态栏透明
  3. 2019-11-07 Android谷歌支付SDK集成问题
  4. Android自动化测试初探(二): Hierarchyview
  5. android 检查能否上网
  6. Android APK权限提升到System
  7. 基于Paho Android Service 实现MQTT协议
  8. ActivityGroup返回键获取焦点处理
  9. Android(安卓)BroadcastReceiver常见监听
  10. Android Studio第一次启动的Fetching and