android camera2启动流程

本文详细梳理了Android原生Camera2应用的启动流程,从CameraActivity的onCreate开始,逐步讲解如何通过PhotoModule和CameraController初始化相机,并最终在CameraAgent中成功打开相机并回调onCameraOpened方法。整个流程从CameraActivity传递Callback到CameraController,再由CameraActivity新建CameraController,完成相机的启动操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

重构原生camera2 有3个月了,现在也算告一段落,这里总结一些原生APK流程以做记录。
camera2的所有主要操作都在一个activity中进行,那就是CameraActivity.java,所以现在先onCreate开始说起,由于我们现在主要讲启动流程,所以将与主流程无关的代码和UI界面相关的复杂代码删除,以便阅读。
CameraActivity.java

public void onCreate(Bundle state) {
    CameraPerformanceTracker.onEvent(CameraPerformanceTracker.ACTIVITY_START);
    super.onCreate(state);
    if (!Glide.isSetup()) {
        Glide.setup(new GlideBuilder(this)
            .setResizeService(new FifoPriorityThreadPoolExecutor(1)));
        Glide.get(this).setMemoryCategory(MemoryCategory.HIGH);
    }

    mOnCreateTime = System.currentTimeMillis();
    mAppContext = getApplicationContext();
    mSoundPlayer = new SoundPlayer(mAppContext);

    //获取cameramanager,在CaptureModule中使用,但是我们拍照用的是PhotoModule所以暂时无用
    mCameraManager = OneCameraManager.get(this);

    // 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();
    GcamHelper.init(getContentResolver());

    //初始化Modules,这里Module的作用相当于MVC模式中M的作用,它对camera进行操作。
    ModulesInfo.setupModules(mAppContext, mModuleManager);

    //SettingsManager保存camera配置
    mSettingsManager = getServices().getSettingsManager();
    AppUpgrader appUpgrader = new AppUpgrader(this);
    appUpgrader.upgrade(mSettingsManager);
    Keys.setDefaults(mSettingsManager, mAppContext);

    getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
    setContentView(R.layout.activity_main);

    mActionBar = getActionBar();
    // set actionbar background to 100% or 50% transparent
    if (ApiHelper.isLOrHigher()) {
        mActionBar.setBackgroundDrawable(new ColorDrawable(0x00000000));
    } else {
        mActionBar.setBackgroundDrawable(new ColorDrawable(0x80000000));
    }
    mActionBar.addOnMenuVisibilityListener(mOnMenuVisibilityListener);

    mMainHandler = new MainHandler(this, getMainLooper());

    //创建camera的controll对象,通过CameraController来对framework的API接口进行控制,现在camera有2套API机制可以在CameraAgentFactory中看到,后续再进行说明。
    mCameraController = new CameraController(mAppContext, this, mMainHandler,
            CameraAgentFactory.getAndroidCameraAgent(this, CameraAgentFactory.CameraApi.API_1),
            CameraAgentFactory.getAndroidCameraAgent(this, CameraAgentFactory.CameraApi.AUTO));
    mCameraController.setCameraDefaultExceptionCallback(mCameraDefaultExceptionCallback,
            mMainHandler);

    .........


    //CameraAppUI来绘制camera总UI,不同module的UI在对应的module内再绘制,比如photomodule的ui由PhotoUI绘制
    mCameraAppUI = new CameraAppUI(this,
            (MainActivityLayout) findViewById(R.id.activity_root_view), isCaptureIntent());

    .........

    //设置当前module
    setModuleFromModeIndex(getModeIndex());

    //初始化UI
    mCameraAppUI.prepareModuleUI();

    //初始化当前Module
    mCurrentModule.init(this, isSecureCamera(), isCaptureIntent());

   .........
}

//这样oncreate完成,接下来看onStart,我们拍照界面用的是PhotoModule,所以后面module都用PhotoModule为列

public void onStart() {
    super.onStart();
    mIsActivityRunning = true;
    mPanoramaViewHelper.onStart();

    //获取当前所用moduleID
    int modeIndex = getModeIndex();
    if (!isCaptureIntent() && mCurrentModeIndex != modeIndex) {
    //切换modeIndex所代表的module
        onModeSelected(modeIndex);
    }

    if (mResetToPreviewOnResume) {
        mCameraAppUI.resume();
        mResetToPreviewOnResume = false;
    }
}


public void onModeSelected(int modeIndex) {
    if (mCurrentModeIndex == modeIndex) {
        return;
    }

    CameraPerformanceTracker.onEvent(CameraPerformanceTracker.MODE_SWITCH_START);
    // Record last used camera mode for quick switching
    if (modeIndex == getResources().getInteger(R.integer.camera_mode_photo)
            || modeIndex == getResources().getInteger(R.integer.camera_mode_gcam)) {
        mSettingsManager.set(SettingsManager.SCOPE_GLOBAL,
  
### Android Camera 组件启动流程详解 #### 1. 系统初始化阶段 在Linux内核启动之后,Android系统会进入用户空间并执行`init`进程。此进程中包含了多个重要步骤用于启动各种必要的守护进程和服务。对于Camera模块而言,其依赖的服务会在这一时期被创建和配置[^4]。 #### 2. Service Manager 启动 CameraService 当Zygote孵化完毕后,SystemServer开始运行,并负责加载核心应用框架以及启动关键性的后台服务。其中包括了CameraService的实例化与注册到ServiceManager中去。这一步骤确保了后续其他组件能够通过Binder机制访问Camera HAL层所提供的能力[^1]。 #### 3. 应用程序请求开启摄像头 开发者通常利用 `CameraManager` 类来获取有关可用摄像机的信息及其状态变化通知。具体来说就是调用了如下所示的方法: ```java CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); ``` 这段代码的作用是从系统的service manager那里取得camera service的一个代理对象,从而可以进一步操作具体的相机设备[^2]。 #### 4. 打开指定ID的物理相机设备 一旦获得了CameraManager实例,就可以尝试打开特定编号的相机单元。这里涉及到的实际API调用可能是这样的形式: ```java public static Camera openCamera(int cameraId) { try{ return Camera.open(cameraId); } catch(Exception e){ Log.e("OpenCameraError", "Failed to open camera with id:" + String.valueOf(cameraId)); return null; } } ``` 上述方法内部实现了对底层硬件抽象层(HAL)接口的调用逻辑,最终实现的是向驱动发送指令以激活相应的图像传感器和其他关联部件[^3]。 #### 5. 完成CameraSession建立 成功打开了目标相机之后,则进入了设置参数、预览流构建等一系列准备工作当中。此时已经建立了完整的从上至下的通信链路——即由Java API经JNI到达native库再到底层HAL直至实际的硬件控制层面;同时也意味着应用程序现在拥有了对该相机资源的有效使用权直到显式释放为止。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值