Android Dev Summit, October 23-24: two days of technical content, directly from the Android team. Sign-up for livestream updates.

Arsitektur CameraX

CameraX adalah tambahan untuk Jetpack yang mempermudah pemanfaatan kapabilitas Camera2 API. Topik ini mencakup arsitektur CameraX, termasuk strukturnya, cara menggunakan API ini, cara menggunakan Siklus Proses, dan cara menggabungkan kasus penggunaan.

Struktur CameraX

Developer menggunakan CameraX untuk berinteraksi dengan kamera perangkat melalui abstraksi yang disebut kasus penggunaan. Kasus penggunaan berikut tersedia saat ini:

  • Pratinjau: menyiapkan SurfaceTexture pratinjau
  • Analisis gambar: menyediakan buffer yang dapat diakses CPU untuk analisis, misalnya untuk machine learning
  • Pengambilan gambar: mengambil dan menyimpan foto

Kasus penggunaan dapat digabungkan dan aktif bersamaan. Misalnya, sebuah aplikasi dapat mengizinkan pengguna untuk menampilkan gambar yang dilihat kamera menggunakan kasus penggunaan pratinjau, memiliki kasus penggunaan analisis gambar yang menentukan apakah orang-orang dalam foto tersenyum, dan mencakup kasus penggunaan pengambilan gambar untuk mengambil gambar saat orang-orang tersebut tersenyum.

Model API

Untuk menggunakan library ini, Anda harus menentukan berikut ini:

  • Kasus penggunaan yang diinginkan dengan opsi konfigurasi
  • Apa yang akan dilakukan dengan data output dengan menambahkan pemroses
  • Alur yang diinginkan, seperti kapan mengaktifkan kamera dan kapan menghasilkan data, dengan menggabungkan kasus penggunaan ke Siklus Proses Arsitektur Android

Objek konfigurasi untuk kasus penggunaan dikonfigurasi menggunakan metode set() dan diselesaikan dengan metode build(). Setiap objek kasus penggunaan menyediakan seperangkat API untuk kasus penggunaan tertentu. Misalnya, kasus penggunaan pengambilan gambar menyediakan panggilan metode takePicture().

Sebagai pengganti panggilan metode mulai dan akhiri spesifik di onResume() dan onPause(), aplikasi menentukan siklus proses yang akan dikaitkan dengan kamera menggunakan CameraX.bindToLifecycle(). Proses memulai, mengakhiri, dan memproduksi data diatur oleh Siklus Proses Arsitektur yang ditentukan. Siklus proses tersebut selanjutnya memberi tahu CameraX kapan harus mengonfigurasi sesi pengambilan gambar dan memastikan kamera berubah ke status yang tepat untuk menyesuaikan dengan peralihan siklus proses.

Untuk langkah implementasi setiap kasus penggunaan, lihat Menerapkan pratinjau, Menganalisis gambar, dan Mengambil foto.

Contoh model API

Kasus penggunaan pratinjau menyediakan SurfaceTexture untuk tampilan. Aplikasi membuat kasus penggunaan ini dengan opsi konfigurasi menggunakan kode berikut:

Kotlin

    val previewConfig = PreviewConfig.Builder().build()
    val preview = Preview(previewConfig)

    val textureView: TextureView = findViewById(R.id.textureView)

    // The output data-handling is configured in a listener.
    preview.setOnPreviewOutputUpdateListener { previewOutput ->
        textureView.surfaceTexture = previewOutput.surfaceTexture
    }

    // The use case is bound to an Android Lifecycle with the following code.
    CameraX.bindToLifecycle(this as LifecycleOwner, preview)
    

Java

    PreviewConfig config = new PreviewConfig.Builder().build();
    Preview preview = new Preview(config);

    TextureView textureView = findViewById(R.id.textureView);

    preview.setOnPreviewOutputUpdateListener(
        new Preview.OnPreviewOutputUpdateListener() {
            @Override
            public void onUpdated(Preview.PreviewOutput previewOutput) {
                // The output data-handling is configured in a listener.
                textureView.setSurfaceTexture(previewOutput.getSurfaceTexture());
                // Your custom code here.
            });
    });

    // The use case is bound to an Android Lifecycle with the following code.
    CameraX.bindToLifecycle((LifecycleOwner) this, preview);
    

Untuk kode contoh lainnya, lihat aplikasi contoh CameraX resmi.

Siklus proses CameraX

CameraX mengamati siklus proses untuk menentukan kapan harus membuka kamera, memulai sesi pengambilan gambar, serta kapan harus berhenti dan menutup kamera. API kasus penggunaan menyediakan panggilan metode dan callback untuk memantau progres.

Seperti dijelaskan dalam Menggabungkan kasus penggunaan, Anda dapat menggabungkan beberapa campuran kasus penggunaan menjadi satu siklus proses. Saat aplikasi Anda perlu mendukung kasus penggunaan yang tidak dapat digabung, Anda dapat melakukan salah satu dari berikut ini:

  • Mengelompokkan kasus penggunaan yang kompatibel bersama-sama menjadi beberapa fragmen, lalu berpindah-pindah di antara fragmen
  • Membuat komponen siklus proses kustom dan menggunakannya untuk mengontrol siklus proses kamera secara manual

Jika Anda memisahkan pemilik Siklus proses kasus penggunaan tampilan dan kamera (misalnya jika Anda menggunakan siklus proses kustom atau fragmen penahan), maka Anda harus memastikan bahwa semua kasus penggunaan terpisah dari CameraX menggunakan CameraX.unbindAll() atau dengan memisahkan kasus penggunaan tersebut satu per satu. Cara lainnya, jika Anda menggabungkan kasus penggunaan melalui metode onCreate untuk sebuah Siklus proses standar, Anda dapat mengizinkan CameraX mengelola awal dan akhir sesi pengambilan gambar dan pemisahan kasus penggunaan.

Jika semua fungsionalitas kamera Anda sesuai dengan siklus proses untuk sebuah komponen yang memperhatikan siklus proses, seperti AppCompatActivity atau fragmen AppCompat, maka penggunaan siklus proses komponen tersebut saat menggabungkan semua kasus penggunaan yang diinginkan akan memastikan bahwa fungsionalitas kamera siap ketika komponen yang memperhatikan siklus proses tersebut aktif, dan diakhiri dengan aman, sehingga tidak menggunakan resource apa pun, setelah komponen tersebut tidak aktif.

LifecycleOwner kustom

Untuk kasus lanjutan, Anda dapat membuat LifecycleOwner kustom agar aplikasi mengontrol siklus proses sesi CameraX secara eksplisit, bukan mengaitkannya ke LifecycleOwner standar Android.

Contoh kode berikut menunjukkan cara membuat LifecycleOwner kustom sederhana:

Kotlin

    class CustomLifecycle : LifecycleOwner {
        private val lifecycleRegistry: LifecycleRegistry

        init {
            lifecycleRegistry = LifecycleRegistry(this);
            lifecycleRegistry.markState(Lifecycle.State.CREATED)
        }
        ...
        fun doOnResume() {
            lifecycleRegistry.markState(State.RESUMED)
        }
        ...
        override fun getLifecycle(): Lifecycle {
            return lifecycleRegistry
        }
    }
    

Java

    public class CustomLifecycle implements LifecycleOwner {
        private LifecycleRegistry mLifecycleRegistry;
        public CustomLifecycle() {
            mLifecycleRegistry = new LifecycleRegistry(this);
            mLifecycleRegistry.markState(Lifecycle.State.CREATED);
        }
       ...
       public void doOnResume() {
            mLifecycleRegistry.markState(State.RESUMED);
        }
       ...
        public Lifecycle getLifecycle() {
            return mLifecycleRegistry;
        }
    }
    

Dengan LifecycleOwner, aplikasi Anda dapat menempatkan peralihan status pada posisi yang diinginkan dalam kodenya. Untuk selengkapnya tentang cara menerapkan fungsionalitas ini pada aplikasi Anda, lihat Menerapkan LifecycleOwner kustom.

Menggabungkan kasus penggunaan

Kasus penggunaan dapat berjalan secara bersamaan. Meskipun dapat digabung secara berurutan ke sebuah siklus proses, akan lebih baik jika semua kasus penggunaan digabungkan dengan satu panggilan ke CameraX.bindToLifecycle(). Untuk informasi selengkapnya tentang praktik terbaik perubahan konfigurasi, lihat Menangani perubahan konfigurasi.

Dalam contoh kode berikut, aplikasi menentukan dua kasus penggunaan yang akan dibuat dan dijalankan secara bersamaan. Aplikasi juga menentukan siklus proses yang digunakan untuk kedua kasus penggunaan, sehingga keduanya dimulai dan dihentikan sesuai dengan siklus prosesnya.

Kotlin

    val imageCapture: ImageCapture

    override fun onCreate() {
        val previewConfig = PreviewConfig.Builder().build()
        val imageCaptureConfig = ImageCaptureConfiguration.Builder().build()

        val imageCapture = ImageCapture(imageCaptureConfig)
        val preview = Preview(previewConfig)

        val textureView = findViewById(R.id.textureView)

        preview.setOnPreviewOutputUpdateListener { previewOutput ->
            textureView.surfaceTexture = previewOutput.surfaceTexture
        }

        CameraX.bindToLifecycle(this as LifecycleOwner, preview, imageCapture)
    }
    

Java

    private ImageCapture imageCapture;

    void onCreate() {
        PreviewConfig previewConfig = new PreviewConfig.Builder().build();
        imageCaptureConfig imageCaptureConfig =
            new ImageCaptureConfig.Builder().build();

        imageCapture = new ImageCapture(imageCaptureConfig);
        preview = new Preview(previewConfig);

        TextureView textureView = findViewById(R.id.textureView);

        preview.setOnPreviewOutputUpdateListener(
            previewOutput -> {
                textureView.setSurfaceTexture(previewOutput.getSurfaceTexture());
        });

        CameraX.bindToLifecycle((LifecycleOwner) this, preview, imageCapture);
    }
    

Kombinasi konfigurasi berikut ini didukung:

Pratinjau Analisis Pengambilan gambar Menggabungkan kasus penggunaan
Memberikan pratinjau kepada pengguna, mengambil foto, dan menganalisis aliran gambar.
Mengambil foto dan menganalisis aliran gambar.
Memberikan pratinjau dengan efek visual yang diterapkan berdasarkan analisis atas gambar yang sedang dialirkan.
Menampilkan apa yang dilihat kamera dan mengambil foto sesuai tindakan pengguna.

Izin

Aplikasi Anda membutuhkan izin CAMERA. Untuk menyimpan gambar ke file, aplikasi juga memerlukan izin WRITE_EXTERNAL_STORAGE, kecuali pada perangkat yang menjalankan Android Q atau yang lebih baru.

Untuk informasi selengkapnya tentang mengonfigurasi izin untuk aplikasi Anda, baca Meminta Izin Aplikasi.

Persyaratan

CameraX memiliki persyaratan versi minimum berikut:

  • Android API level 21
  • Komponen Arsitektur Android 1.1.1

Untuk aktivitas yang memperhatikan siklus proses, gunakan FragmentActivity atau AppCompatActivity.

Menyatakan dependensi

Untuk menambahkan dependensi pada CameraX, Anda harus menambahkan repositori Google Maven ke project Anda.

Buka file build.gradle untuk project Anda, lalu tambahkan repositori google() seperti ditunjukkan di bawah ini:

    allprojects {
      repositories {
        google()
        jcenter()
      }
    }
    

Tambahkan berikut ini ke file build.gradle masing-masing modul:

    dependencies {
        // CameraX core library.
        def camerax_version = "1.0.0-alpha01"
        implementation "androidx.camera.core:core:$camerax_version"
        // If you want to use CameraView.
        implementation "androidx.camera.core:view:$camerax_version"
        // If you want to use Camera2 extensions.
        implementation "androidx.camera.core:camera2:$camerax_version"
    }
    

Untuk informasi selengkapnya tentang cara mengonfigurasi aplikasi agar sesuai dengan persyaratan ini, lihat Menyatakan dependensi.

Referensi lainnya

Untuk mempelajari CameraX lebih lanjut, pelajari referensi tambahan berikut.

Codelab

  • Memulai CameraX
  • Menambahkan Fragmen CameraView ke aplikasi Anda
  • Contoh kode

  • Contoh aplikasi CameraX resmi