用心的文章要转

一、在android中开发人员可以做那些工作?
应用程序开发:利用android提供的强大的sdk,开发出各种各样新颖的应用。
系统开发:在android中Google实现了与硬件无关的所有代码,但是与硬件密切相关的硬件抽象层却没有也无法提供,对于移动设备不同的设备提供商底层硬件是千变万化的,不可能提供统一的硬件驱动以及接口实现,只能提供标准的接口,因此硬件提供商需要自个儿开发设备驱动,
并去实现android框架提供的接口。
二、android框架中Camera系统源码分析
在每个android手机中都有一个Camera应用程序用来实现拍照功能,不同硬件提供商可能会对这个应用程序进行改变来适合自己的UI风格,
这里仅仅分析android原生Camera应用以及框架(Android 4.0)
原生Camera应用代码在Camera.java(android4.0\packages\apps\camera\src\com\android\camera),这个应该算是Camera系统最上层,应用层的实现。
下面是Camera类部分代码

[java] view plain copy
  1. publicclassCameraextendsActivityBaseimplementsFocusManager.Listener,
  2. View.OnTouchListener,ShutterButton.OnShutterButtonListener,
  3. SurfaceHolder.Callback,ModePicker.OnModeChangeListener,
  4. FaceDetectionListener,CameraPreference.OnPreferenceChangedListener,
  5. LocationManager.Listener,ShutterButton.OnShutterButtonLongPressListener
从上面可以看出,Camera在继承了很多监听接口,用来监听各种事件(对焦事件、用户触摸事件等)。这个应用时继承ActivityBase,
可以重载OnCreate、OnResume等接口,在这些接口中完成相关初始化的工作,基本就是初始化各种监听对象,以及获取相机参数等相关。
比较关键的在doOnResume这个函数中:
[java] view plain copy
  1. @Override
  2. protectedvoiddoOnResume(){
  3. if(mOpenCameraFail||mCameraDisabled)return;
  4. mPausing=false;
  5. mJpegPictureCallbackTime=0;
  6. mZoomValue=0;
  7. //Startthepreviewifitisnotstarted.
  8. if(mCameraState==PREVIEW_STOPPED){
  9. try{
  10. mCameraDevice=Util.openCamera(this,mCameraId);
  11. initializeCapabilities();
  12. resetExposureCompensation();
  13. startPreview();
  14. if(mFirstTimeInitialized)startFaceDetection();
  15. }catch(CameraHardwareExceptione){
  16. Util.showErrorAndFinish(this,R.string.cannot_connect_camera);
  17. return;
  18. }catch(CameraDisabledExceptione){
  19. Util.showErrorAndFinish(this,R.string.camera_disabled);
  20. return;
  21. }
  22. }
  23. if(mSurfaceHolder!=null){
  24. //Iffirsttimeinitializationisnotfinished,putitinthe
  25. //messagequeue.
  26. if(!mFirstTimeInitialized){
  27. mHandler.sendEmptyMessage(FIRST_TIME_INIT);
  28. }else{
  29. initializeSecondTime();
  30. }
  31. }
  32. keepScreenOnAwhile();
  33. if(mCameraState==IDLE){
  34. mOnResumeTime=SystemClock.uptimeMillis();
  35. mHandler.sendEmptyMessageDelayed(CHECK_DISPLAY_ROTATION,100);
  36. }
  37. }
在这个函数中看到通过这个函数获得Camera底层对象
mCameraDevice = Util.openCamera(this, mCameraId),这里使用Util这个类,这个类的实现在
Util.java (android4.0\packages\apps\camera\src\com\android\camera)中,找到OpenCamera这个函数实现:
[java] view plain copy
  1. publicstaticandroid.hardware.CameraopenCamera(Activityactivity,intcameraId)
  2. throwsCameraHardwareException,CameraDisabledException{
  3. //Checkifdevicepolicyhasdisabledthecamera.
  4. DevicePolicyManagerdpm=(DevicePolicyManager)activity.getSystemService(
  5. Context.DEVICE_POLICY_SERVICE);
  6. if(dpm.getCameraDisabled(null)){
  7. thrownewCameraDisabledException();
  8. }
  9. try{
  10. returnCameraHolder.instance().open(cameraId);
  11. }catch(CameraHardwareExceptione){
  12. //Inengbuild,wethrowtheexceptionsothattesttool
  13. //candetectitandreportit
  14. if("eng".equals(Build.TYPE)){
  15. thrownewRuntimeException("openCamerafailed",e);
  16. }else{
  17. throwe;
  18. }
  19. }
  20. }
从这个函数可以看出,android系统中对下层Camera管理,是通过一个单例模式CameraHolder来管理的,
定位到这个类的实现CameraHolder.java (android4.0\packages\apps\camera\src\com\android\camera)通过调用open函数获取一个Camera硬件设备对象,
因为Camera设备是独享设备,不能同时被两个进程占用,而整个android系统是一个多进程环境,因此需要加入一些进程间互斥同步的方法。
定位到这个类的open函数:
[java] view plain copy
  1. publicsynchronizedandroid.hardware.Cameraopen(intcameraId)
  2. throwsCameraHardwareException{
  3. Assert(mUsers==0);
  4. if(mCameraDevice!=null&&mCameraId!=cameraId){
  5. mCameraDevice.release();
  6. mCameraDevice=null;
  7. mCameraId=-1;
  8. }
  9. if(mCameraDevice==null){
  10. try{
  11. Log.v(TAG,"opencamera"+cameraId);
  12. mCameraDevice=android.hardware.Camera.open(cameraId);
  13. mCameraId=cameraId;
  14. }catch(RuntimeExceptione){
  15. Log.e(TAG,"failtoconnectCamera",e);
  16. thrownewCameraHardwareException(e);
  17. }
  18. mParameters=mCameraDevice.getParameters();
  19. }else{
  20. try{
  21. mCameraDevice.reconnect();
  22. }catch(IOExceptione){
  23. Log.e(TAG,"reconnectfailed.");
  24. thrownewCameraHardwareException(e);
  25. }
  26. mCameraDevice.setParameters(mParameters);
  27. }
  28. ++mUsers;
  29. mHandler.removeMessages(RELEASE_CAMERA);
  30. mKeepBeforeTime=0;
  31. returnmCameraDevice;
  32. }
[java] view plain copy
通过android.hardware.Camera.open(cameraId)调用进入下一层封装,JNI层,这一层是java代码的最下层,对下层CameraC++代码进行JNI封装,封装实现类在Camera.java (android4.0\frameworks\base\core\java\android\hardware) 下面是这个类的部分实现,里面定义了不少回调函数: [java] view plain copy
  1. publicclassCamera{
  2. privatestaticfinalStringTAG="Camera";
  3. //Thesematchtheenumsinframeworks/base/include/camera/Camera.h
  4. privatestaticfinalintCAMERA_MSG_ERROR=0x001;
  5. privatestaticfinalintCAMERA_MSG_SHUTTER=0x002;
  6. privatestaticfinalintCAMERA_MSG_FOCUS=0x004;
  7. privatestaticfinalintCAMERA_MSG_ZOOM=0x008;
  8. privatestaticfinalintCAMERA_MSG_PREVIEW_FRAME=0x010;
  9. privatestaticfinalintCAMERA_MSG_VIDEO_FRAME=0x020;
  10. privatestaticfinalintCAMERA_MSG_POSTVIEW_FRAME=0x040;
  11. privatestaticfinalintCAMERA_MSG_RAW_IMAGE=0x080;
  12. privatestaticfinalintCAMERA_MSG_COMPRESSED_IMAGE=0x100;
  13. privatestaticfinalintCAMERA_MSG_RAW_IMAGE_NOTIFY=0x200;
  14. privatestaticfinalintCAMERA_MSG_PREVIEW_METADATA=0x400;
  15. privatestaticfinalintCAMERA_MSG_ALL_MSGS=0x4FF;
  16. privateintmNativeContext;//accessedbynativemethods
  17. privateEventHandlermEventHandler;
  18. privateShutterCallbackmShutterCallback;
  19. privatePictureCallbackmRawImageCallback;
  20. privatePictureCallbackmJpegCallback;
  21. privatePreviewCallbackmPreviewCallback;
  22. privatePictureCallbackmPostviewCallback;
  23. privateAutoFocusCallbackmAutoFocusCallback;
  24. privateOnZoomChangeListenermZoomListener;
  25. privateFaceDetectionListenermFaceListener;
  26. privateErrorCallbackmErrorCallback;
定位到Open函数:
public static Camera open(int cameraId) {
return new Camera(cameraId);
}
Open函数是一个静态方法,构造一个Camera对象:
[java] view plain copy
  1. Camera(intcameraId){
  2. mShutterCallback=null;
  3. mRawImageCallback=null;
  4. mJpegCallback=null;
  5. mPreviewCallback=null;
  6. mPostviewCallback=null;
  7. mZoomListener=null;
  8. Looperlooper;
  9. if((looper=Looper.myLooper())!=null){
  10. mEventHandler=newEventHandler(this,looper);
  11. }elseif((looper=Looper.getMainLooper())!=null){
  12. mEventHandler=newEventHandler(this,looper);
  13. }else{
  14. mEventHandler=null;
  15. }
  16. native_setup(newWeakReference<Camera>(this),cameraId);
  17. }

在构造函数中调用native_setup方法,此方法对应于C++代码的android_hardware_Camera_native_setup方法,
实现在android_hardware_Camera.cpp (android4.0\frameworks\base\core\jni),具体代码如下:
[cpp] view plain copy
  1. staticvoidandroid_hardware_Camera_native_setup(JNIEnv*env,jobjectthiz,
  2. jobjectweak_this,jintcameraId)
  3. {
  4. sp<Camera>camera=Camera::connect(cameraId);
  5. if(camera==NULL){
  6. jniThrowRuntimeException(env,"Failtoconnecttocameraservice");
  7. return;
  8. }
  9. //makesurecamerahardwareisalive
  10. if(camera->getStatus()!=NO_ERROR){
  11. jniThrowRuntimeException(env,"Camerainitializationfailed");
  12. return;
  13. }
  14. jclassclazz=env->GetObjectClass(thiz);
  15. if(clazz==NULL){
  16. jniThrowRuntimeException(env,"Can'tfindandroid/hardware/Camera");
  17. return;
  18. }
  19. //WeuseaweakreferencesotheCameraobjectcanbegarbagecollected.
  20. //Thereferenceisonlyusedasaproxyforcallbacks.
  21. sp<JNICameraContext>context=newJNICameraContext(env,weak_this,clazz,camera);
  22. context->incStrong(thiz);
  23. camera->setListener(context);
  24. //savecontextinopaquefield
  25. env->SetIntField(thiz,fields.context,(int)context.get());
  26. }
在android_hardware_Camera_native_setup方法中调用了Camera对象的connect方法,这个Camera类的声明在Camera.h (android4.0\frameworks\base\include\camera)
定位到connect方法: [cpp] view plain copy
  1. sp<Camera>Camera::connect(intcameraId)
  2. {
  3. LOGV("connect");
  4. sp<Camera>c=newCamera();
  5. constsp<ICameraService>&cs=getCameraService();
  6. if(cs!=0){
  7. c->mCamera=cs->connect(c,cameraId);
  8. }
  9. if(c->mCamera!=0){
  10. c->mCamera->asBinder()->linkToDeath(c);
  11. c->mStatus=NO_ERROR;
  12. }else{
  13. c.clear();
  14. }
  15. returnc;
  16. }
这里以下的代码就比较关键了,涉及到Camera框架的实现机制,Camera系统使用的是Server-Client机制,Service和Client位于不同的进程中,进程间使用Binder机制进行通信,
Service端实际实现相机相关的操作,Client端通过Binder接口调用Service对应的操作。
继续分析代码,上面函数调用getCameraService方法,获得CameraService的引用,ICameraService有两个子类,BnCameraService和BpCameraService,这两个子类同时也
继承了IBinder接口,这两个子类分别实现了Binder通信的两端,Bnxxx实现ICameraService的具体功能,Bpxxx利用Binder的通信功能封装ICameraService方法,具体如下:
[cpp] view plain copy
  1. classICameraService:publicIInterface
  2. {
  3. public:
  4. enum{
  5. GET_NUMBER_OF_CAMERAS=IBinder::FIRST_CALL_TRANSACTION,
  6. GET_CAMERA_INFO,
  7. CONNECT
  8. };
  9. public:
  10. DECLARE_META_INTERFACE(CameraService);
  11. virtualint32_tgetNumberOfCameras()=0;
  12. virtualstatus_tgetCameraInfo(intcameraId,
  13. structCameraInfo*cameraInfo)=0;
  14. virtualsp<ICamera>connect(constsp<ICameraClient>&cameraClient,
  15. intcameraId)=0;
  16. };
  17. //----------------------------------------------------------------------------
  18. classBnCameraService:publicBnInterface<ICameraService>
  19. {
  20. public:
  21. virtualstatus_tonTransact(uint32_tcode,
  22. constParcel&data,
  23. Parcel*reply,
  24. uint32_tflags=0);
  25. };
  26. };//na
[cpp] view plain copy
  1. classBpCameraService:publicBpInterface<ICameraService>
  2. {
  3. public:
  4. BpCameraService(constsp<IBinder>&impl)
  5. :BpInterface<ICameraService>(impl)
  6. {
  7. }
  8. //getnumberofcamerasavailable
  9. virtualint32_tgetNumberOfCameras()
  10. {
  11. Parceldata,reply;
  12. data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
  13. remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS,data,&reply);
  14. returnreply.readInt32();
  15. }
  16. //getinformationaboutacamera
  17. virtualstatus_tgetCameraInfo(intcameraId,
  18. structCameraInfo*cameraInfo){
  19. Parceldata,reply;
  20. data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
  21. data.writeInt32(cameraId);
  22. remote()->transact(BnCameraService::GET_CAMERA_INFO,data,&reply);
  23. cameraInfo->facing=reply.readInt32();
  24. cameraInfo->orientation=reply.readInt32();
  25. returnreply.readInt32();
  26. }
  27. //connecttocameraservice
  28. virtualsp<ICamera>connect(constsp<ICameraClient>&cameraClient,intcameraId)
  29. {
  30. Parceldata,reply;
  31. data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
  32. data.writeStrongBinder(cameraClient->asBinder());
  33. data.writeInt32(cameraId);
  34. remote()->transact(BnCameraService::CONNECT,data,&reply);
  35. returninterface_cast<ICamera>(reply.readStrongBinder());
  36. }
  37. };
  38. IMPLEMENT_META_INTERFACE(CameraService,"android.hardware.ICameraService");
  39. //----------------------------------------------------------------------
  40. status_tBnCameraService::onTransact(
  41. uint32_tcode,constParcel&data,Parcel*reply,uint32_tflags)
  42. {
  43. switch(code){
  44. caseGET_NUMBER_OF_CAMERAS:{
  45. CHECK_INTERFACE(ICameraService,data,reply);
  46. reply->writeInt32(getNumberOfCameras());
  47. returnNO_ERROR;
  48. }break;
  49. caseGET_CAMERA_INFO:{
  50. CHECK_INTERFACE(ICameraService,data,reply);
  51. CameraInfocameraInfo;
  52. memset(&cameraInfo,0,sizeof(cameraInfo));
  53. status_tresult=getCameraInfo(data.readInt32(),&cameraInfo);
  54. reply->writeInt32(cameraInfo.facing);
  55. reply->writeInt32(cameraInfo.orientation);
  56. reply->writeInt32(result);
  57. returnNO_ERROR;
  58. }break;
  59. caseCONNECT:{
  60. CHECK_INTERFACE(ICameraService,data,reply);
  61. sp<ICameraClient>cameraClient=interface_cast<ICameraClient>(data.readStrongBinder());
  62. sp<ICamera>camera=connect(cameraClient,data.readInt32());
  63. reply->writeStrongBinder(camera->asBinder());
  64. returnNO_ERROR;
  65. }break;
  66. default:
  67. returnBBinder::onTransact(code,data,reply,flags);
  68. }
  69. }
  70. //----------------------------------------------------------------------------
  71. };//namespaceandroid
下面继续分析sp<Camera> Camera::connect(int cameraId)这个方法,,定位到getCameraService这个方法
[cpp] view plain copy
  1. constsp<ICameraService>&Camera::getCameraService()
  2. {
  3. Mutex::Autolock_l(mLock);
  4. if(mCameraService.get()==0){
  5. sp<IServiceManager>sm=defaultServiceManager();
  6. sp<IBinder>binder;
  7. do{
  8. binder=sm->getService(String16("media.camera"));
  9. if(binder!=0)
  10. break;
  11. LOGW("CameraServicenotpublished,waiting...");
  12. usleep(500000);//0.5s
  13. }while(true);
  14. if(mDeathNotifier==NULL){
  15. mDeathNotifier=newDeathNotifier();
  16. }
  17. binder->linkToDeath(mDeathNotifier);
  18. mCameraService=interface_cast<ICameraService>(binder);
  19. }
  20. LOGE_IF(mCameraService==0,"noCameraService!?");
  21. returnmCameraService;
  22. }
定位到mCameraService = interface_cast<ICameraService>(binder); mCameraService是一个ICamerService类型,更加具体具体一点来讲应该是BpCameraService,
因为在这个类中实现了ICameraService的方法。

总结上面Binder机制,仅仅考虑分析Binder用法,对底层实现不进行深究,基本步骤如下:
1.定义进程间通信的接口比如这里的ICameraService;
2.在BnCameraService和BpCamaraService实现这个接口,这两个接口也分别继承于BnInterface和BpInterface;
3.服务端向ServiceManager注册Binder,客户端向ServiceManager获得Binder;
4.然后就可以实现双向进程间通信了;

通过getCameraService得到ICameraService引用后,调用ICameraService的connect方法获得ICamera引用,

[cpp] view plain copy
  1. <prename="code"class="cpp">c->mCamera=cs->connect(c,cameraId);</pre>进一步跟进connect方法,这里就是BpCameraService类中connect方法的具体实现。<br>
  2. <prename="code"class="cpp">virtualsp<ICamera>connect(constsp<ICameraClient>&cameraClient,intcameraId)
  3. {
  4. Parceldata,reply;
  5. data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
  6. data.writeStrongBinder(cameraClient->asBinder());
  7. data.writeInt32(cameraId);
  8. remote()->transact(BnCameraService::CONNECT,data,&reply);
  9. returninterface_cast<ICamera>(reply.readStrongBinder());
  10. }</pre>在这里返回的ICamera对象,实际上应该是BpCamera对象,这里使用的是匿名Binder,前面获取CameraService的使用的有名Binder,有名Binder需要借助于ServiceManager获取Binder,而匿名Binder可以通过已经建立后的通信通道(有名Binder)获得。以上是实现Camera框架部分,具体的实现Camera相关的方法是在ICamera相关的接口,下面是给接口的定义:<prename="code"class="cpp">classICamera:publicIInterface
  11. {
  12. public:
  13. DECLARE_META_INTERFACE(Camera);
  14. virtualvoiddisconnect()=0;
  15. //connectnewclientwithexistingcameraremote
  16. virtualstatus_tconnect(constsp<ICameraClient>&client)=0;
  17. //preventotherprocessesfromusingthisICamerainterface
  18. virtualstatus_tlock()=0;
  19. //allowotherprocessestousethisICamerainterface
  20. virtualstatus_tunlock()=0;
  21. //passthebufferedSurfacetothecameraservice
  22. virtualstatus_tsetPreviewDisplay(constsp<Surface>&surface)=0;
  23. //passthebufferedISurfaceTexturetothecameraservice
  24. virtualstatus_tsetPreviewTexture(
  25. constsp<ISurfaceTexture>&surfaceTexture)=0;
  26. //setthepreviewcallbackflagtoaffecthowthereceivedframesfrom
  27. //previewarehandled.
  28. virtualvoidsetPreviewCallbackFlag(intflag)=0;
  29. //startpreviewmode,mustcallsetPreviewDisplayfirst
  30. virtualstatus_tstartPreview()=0;
  31. //stoppreviewmode
  32. virtualvoidstopPreview()=0;
  33. //getpreviewstate
  34. virtualboolpreviewEnabled()=0;
  35. //startrecordingmode
  36. virtualstatus_tstartRecording()=0;
  37. //stoprecordingmode
  38. virtualvoidstopRecording()=0;
  39. //getrecordingstate
  40. virtualboolrecordingEnabled()=0;
  41. //releasearecordingframe
  42. virtualvoidreleaseRecordingFrame(constsp<IMemory>&mem)=0;
  43. //autofocus
  44. virtualstatus_tautoFocus()=0;
  45. //cancelautofocus
  46. virtualstatus_tcancelAutoFocus()=0;
  47. /*
  48. *takeapicture.
  49. *@parammsgTypethemessagetypeanapplicationselectivelyturnon/off
  50. *onaphoto-by-photobasis.Thesupportedmessagetypesare:
  51. *CAMERA_MSG_SHUTTER,CAMERA_MSG_RAW_IMAGE,CAMERA_MSG_COMPRESSED_IMAGE,
  52. *andCAMERA_MSG_POSTVIEW_FRAME.Anyothermessagetypeswillbeignored.
  53. */
  54. virtualstatus_ttakePicture(intmsgType)=0;
  55. //setpreview/captureparameters-key/valuepairs
  56. virtualstatus_tsetParameters(constString8&params)=0;
  57. //getpreview/captureparameters-key/valuepairs
  58. virtualString8getParameters()const=0;
  59. //sendcommandtocameradriver
  60. virtualstatus_tsendCommand(int32_tcmd,int32_targ1,int32_targ2)=0;
  61. //tellthecamerahaltostoremetadataorrealYUVdatainvideobuffers.
  62. virtualstatus_tstoreMetaDataInBuffers(boolenabled)=0;
  63. };</pre><br>
  64. <prename="code"class="cpp"style="background-color:rgb(255,255,255);">ICamera接口有两个子类BnCamera和BpCamera,是Binder通信的两端,BpCamera提供客户端调用接口,BnCamera封装具体的实现,BnCamera也并没有真正实现ICamera相关接口而是在BnCamera子类CameraService::Client中进行实现。而在CameraService::Client类中会继续调用硬件抽象层中相关方法来具体实现Camera功能,
  65. 现在来缕一缕android中Camera各个类如何联系的
  66. 。。。。未完</pre>
  67. <pre></pre>
  68. <pre></pre>
  69. <pre></pre>
  70. <pre></pre>
  71. <pre></pre>

更多相关文章

  1. android listview 圆角的实现方案,模仿Iphone的UITableView
  2. android之播放多媒体文件一(播放音频)
  3. android输入法02:openwnn源码解析01—输入流程
  4. Android(安卓)HIDL学习(2) ---- HelloWorld
  5. 在Android里完美实现基站和WIFI定位
  6. UiAutomator通过ant实现快速调试
  7. Android编程实现连接Wifi(运用Wifi 相关 API)
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. android webrtc构建过程
  2. 详解Android(安卓)触摸事件处理和传递过
  3. Android(安卓)String Placeholders
  4. 谁说Android的动画不廉价(三)之共享元素动
  5. usb 配置
  6. 浅谈Android中的线程的通信及Handle机制
  7. android 基础知识整理 1
  8. Android退出程序(三)——Android事件总线
  9. Android: Actions for BroadcastReceiver
  10. Android(安卓)系統存在設計漏洞,釣魚網站