Mengonfigurasi pengiriman on demand

Modul fitur memungkinkan Anda memisahkan fitur dan resource tertentu dari modul dasar aplikasi dan menyertakannya dalam app bundle. Melalui Play Feature Delivery, pengguna dapat melakukan berbagai hal, seperti mendownload dan menginstal komponen di lain waktu secara on demand setelah menginstal APK dasar untuk aplikasi Anda terlebih dahulu.

Misalnya, ada aplikasi pesan teks yang menyertakan fungsi untuk mengambil dan mengirim pesan gambar, namun hanya sebagian kecil pengguna yang mengirim pesan gambar. Maka wajar saja untuk menyertakan fitur pesan gambar sebagai modul fitur yang dapat didownload. Dengan begitu, download aplikasi awal ukurannya akan lebih kecil untuk semua pengguna, dan hanya pengguna yang memerlukan fitur pesan gambar yang harus mendownload komponen tambahan tersebut.

Perlu diingat bahwa jenis modularisasi ini membutuhkan lebih banyak upaya dan mungkin pemfaktoran ulang kode aplikasi yang sudah ada, jadi pertimbangkan dengan hati-hati fitur aplikasi yang paling diuntungkan dari segi ketersediaan secara on demand bagi pengguna. Untuk lebih memahami pedoman dan kasus penggunaan yang optimal untuk fitur on demand, baca praktik terbaik UX untuk pengiriman on demand.

Jika Anda ingin memodularisasi fitur aplikasi secara bertahap dari waktu ke waktu tanpa mengaktifkan opsi pengiriman lanjutan, seperti on demand, Anda dapat mengonfigurasi pengiriman saat penginstalan.

Halaman ini membantu Anda menambahkan modul fitur ke project aplikasi dan mengonfigurasinya untuk pengiriman on demand. Sebelum memulai, pastikan Anda menggunakan Android Studio 3.5 atau versi lebih tinggi dan Plugin Android Gradle 3.5.0 atau versi lebih tinggi.

Konfigurasi modul baru untuk pengiriman on demand

Cara termudah untuk membuat modul fitur baru adalah dengan menggunakan Android Studio 3.5 atau yang lebih tinggi. Karena modul fitur memiliki dependensi melekat pada modul aplikasi dasar, Anda hanya dapat menambahkannya ke project aplikasi yang sudah ada.

Untuk menambahkan modul fitur ke project aplikasi Anda menggunakan Android Studio, lakukan langkah-langkah berikut:

  1. Buka project aplikasi Anda di IDE jika belum melakukannya.
  2. Dari panel menu, pilih File > New > New Module
  3. Pada dialog Create New Module, pilih Dynamic Feature Module, lalu klik Next.
  4. Pada bagian Configure your new module, lakukan langkah-langkah berikut:
    1. Dari menu dropdown, pilih Base application module untuk project aplikasi Anda.
    2. Tentukan Module name. IDE menggunakan nama ini untuk mengidentifikasi modul sebagai subproject Gradle dalam file setelan Gradle Anda. Jika Anda membuat app bundle, Gradle akan menggunakan elemen terakhir dari nama subproject untuk memasukkan atribut <manifest split> dalam manifes modul fitur.
    3. Tentukan package name modul. Secara default, Android Studio menyarankan nama paket dengan menggabungkan nama paket root modul dasar dan nama modul yang Anda tentukan di langkah sebelumnya.
    4. Pilih Level API minimum yang Anda inginkan untuk didukung modul. Nilai ini harus sesuai dengan yang ada di modul dasar.
  5. Klik Next.
  6. Pada bagian Module Download Options, lakukan langkah-langkah berikut:

    1. Tentukan Module title menggunakan maksimal 50 karakter. Platform tersebut menggunakan judul ini untuk mengidentifikasi modul kepada pengguna saat, misalnya, mengonfirmasi apakah pengguna ingin mendownload modul atau tidak. Karena alasan ini, modul dasar aplikasi Anda harus menyertakan judul modul sebagai resource string, yang dapat Anda terjemahkan. Saat membuat modul menggunakan Android Studio, IDE akan menambahkan resource string ke modul dasar dan memasukkan entri berikut dalam manifes modul fitur:

      <dist:module
          ...
          dist:title="@string/feature_title">
      </dist:module>
      
    2. Di menu dropdown pada bagian Install-time inclusion, pilih Do not include module at install-time. Android Studio memasukkan kode berikut ke dalam manifes modul untuk merefleksikan pilihan Anda:

      <dist:module ... >
        <dist:delivery>
            <dist:on-demand/>
        </dist:delivery>
      </dist:module>
      
    3. Centang kotak di sebelah Fusing jika Anda ingin modul ini tersedia untuk perangkat yang menjalankan Android 4.4 (level API 20) atau yang lebih rendah dan termasuk dalam multi-APK. Artinya, Anda dapat mengaktifkan perilaku on demand untuk modul ini dan menonaktifkan penggabungan untuk menghilangkannya dari perangkat yang tidak mendukung download dan penginstalan APK terpisah. Android Studio memasukkan kode berikut ke dalam manifes modul untuk merefleksikan pilihan Anda:

      <dist:module ...>
          <dist:fusing dist:include="true | false" />
      </dist:module>
      
  7. Klik Finish.

Setelah Android Studio selesai membuat modul Anda, periksa sendiri kontennya dari panel Project (pilih View > Tool Windows > Project dari panel menu). Kode, resource, dan organisasi default harus serupa dengan yang ada di modul aplikasi standar.

Selanjutnya, Anda perlu menerapkan fungsi penginstalan on demand menggunakan library Play Feature Delivery.

Menyertakan Library Play Feature Delivery dalam project Anda

Sebelum memulai, Anda harus terlebih dahulu menambahkan Library Play Feature Delivery ke project Anda.

Meminta modul on demand

Jika perlu menggunakan modul fitur, aplikasi Anda dapat meminta modul fitur saat berada di latar depan melalui class SplitInstallManager. Saat membuat permintaan, aplikasi Anda perlu menentukan nama modul seperti yang ditetapkan oleh elemen split dalam manifes modul target. Saat Anda membuat modul fitur menggunakan Android Studio, sistem build menggunakan Module name (Nama modul) yang Anda sediakan untuk memasukkan properti ini ke dalam manifes modul pada waktu kompilasi. Untuk informasi selengkapnya, baca tentang manifes modul fitur.

Misalnya, pertimbangkan aplikasi yang memiliki modul on demand untuk mengambil dan mengirim pesan gambar menggunakan kamera perangkat, dan modul on demand ini menentukan split="pictureMessages" dalam manifesnya. Contoh berikut menggunakan SplitInstallManager untuk meminta modul pictureMessages (beserta modul tambahan untuk beberapa filter promosi):

Kotlin

// Creates an instance of SplitInstallManager.
val splitInstallManager = SplitInstallManagerFactory.create(context)

// Creates a request to install a module.
val request =
    SplitInstallRequest
        .newBuilder()
        // You can download multiple on demand modules per
        // request by invoking the following method for each
        // module you want to install.
        .addModule("pictureMessages")
        .addModule("promotionalFilters")
        .build()

splitInstallManager
    // Submits the request to install the module through the
    // asynchronous startInstall() task. Your app needs to be
    // in the foreground to submit the request.
    .startInstall(request)
    // You should also be able to gracefully handle
    // request state changes and errors. To learn more, go to
    // the section about how to Monitor the request state.
    .addOnSuccessListener { sessionId -> ... }
    .addOnFailureListener { exception ->  ... }

Java

// Creates an instance of SplitInstallManager.
SplitInstallManager splitInstallManager =
    SplitInstallManagerFactory.create(context);

// Creates a request to install a module.
SplitInstallRequest request =
    SplitInstallRequest
        .newBuilder()
        // You can download multiple on demand modules per
        // request by invoking the following method for each
        // module you want to install.
        .addModule("pictureMessages")
        .addModule("promotionalFilters")
        .build();

splitInstallManager
    // Submits the request to install the module through the
    // asynchronous startInstall() task. Your app needs to be
    // in the foreground to submit the request.
    .startInstall(request)
    // You should also be able to gracefully handle
    // request state changes and errors. To learn more, go to
    // the section about how to Monitor the request state.
    .addOnSuccessListener(sessionId -> { ... })
    .addOnFailureListener(exception -> { ... });

Jika aplikasi Anda meminta modul on demand, Library Play Feature Delivery akan menggunakan strategi “fire-and-forget”. Artinya, aplikasi akan mengirim permintaan untuk mendownload modul ke platform, tetapi tidak memantau apakah penginstalan berhasil atau tidak. Untuk melanjutkan perjalanan pengguna setelah penginstalan atau menangani error dengan baik, pastikan Anda memantau status permintaan.

Catatan: Anda dapat meminta modul fitur yang sudah terinstal di perangkat. API secara instan menganggap permintaan sebagai selesai jika mendeteksi bahwa modul sudah terinstal. Selain itu, setelah modul terinstal, Google Play akan mengupdatenya secara otomatis. Artinya, saat Anda mengupload app bundle versi baru, platform akan mengupdate semua APK yang terinstal milik aplikasi Anda. Untuk informasi selengkapnya, baca Mengelola update aplikasi.

Untuk mendapatkan akses ke kode dan resource modul, aplikasi Anda perlu mengaktifkan SplitCompat. Perhatikan bahwa SplitCompat tidak diperlukan untuk aplikasi instan Android.

Menunda penginstalan modul on demand

Jika tidak menginginkan aplikasi untuk segera mendownload dan menginstal modul on demand, Anda dapat menunda penginstalan saat aplikasi berada di latar belakang. Misalnya, jika Anda ingin melakukan pramuat beberapa materi promosi untuk peluncuran aplikasi Anda nanti.

Anda dapat menentukan modul yang akan didownload nanti menggunakan metode deferredInstall(), seperti yang ditunjukkan di bawah ini. Selain itu, tidak seperti SplitInstallManager.startInstall(), aplikasi Anda tidak perlu berada di latar depan untuk memulai permintaan penginstalan tertunda.

Kotlin

// Requests an on demand module to be downloaded when the app enters
// the background. You can specify more than one module at a time.
splitInstallManager.deferredInstall(listOf("promotionalFilters"))

Java

// Requests an on demand module to be downloaded when the app enters
// the background. You can specify more than one module at a time.
splitInstallManager.deferredInstall(Arrays.asList("promotionalFilters"));

Permintaan untuk menunda penginstalan adalah upaya terbaik dan tidak dapat dilacak progresnya. Jadi, sebelum mencoba mengakses modul yang telah Anda tentukan untuk penginstalan tertunda, sebaiknya Anda memeriksa apakah modul telah diinstal. Jika Anda perlu segera menyediakan modul, gunakan SplitInstallManager.startInstall() untuk memintanya, seperti yang ditunjukkan di bagian sebelumnya.

Memantau status permintaan

Agar dapat memperbarui status progres, mengaktifkan intent setelah penginstalan, atau menangani error permintaan dengan baik, Anda perlu memproses perubahan status dari tugas SplitInstallManager.startInstall() asinkron. Sebelum Anda dapat mulai menerima update untuk permintaan penginstalan, daftarkan pemroses dan dapatkan ID sesi untuk meminta, seperti yang ditunjukkan di bawah ini.

Kotlin

// Initializes a variable to later track the session ID for a given request.
var mySessionId = 0

// Creates a listener for request status updates.
val listener = SplitInstallStateUpdatedListener { state ->
    if (state.sessionId() == mySessionId) {
      // Read the status of the request to handle the state update.
    }
}

// Registers the listener.
splitInstallManager.registerListener(listener)

...

splitInstallManager
    .startInstall(request)
    // When the platform accepts your request to download
    // an on demand module, it binds it to the following session ID.
    // You use this ID to track further status updates for the request.
    .addOnSuccessListener { sessionId -> mySessionId = sessionId }
    // You should also add the following listener to handle any errors
    // processing the request.
    .addOnFailureListener { exception ->
        // Handle request errors.
    }

// When your app no longer requires further updates, unregister the listener.
splitInstallManager.unregisterListener(listener)

Java

// Initializes a variable to later track the session ID for a given request.
int mySessionId = 0;

// Creates a listener for request status updates.
SplitInstallStateUpdatedListener listener = state -> {
    if (state.sessionId() == mySessionId) {
      // Read the status of the request to handle the state update.
    }
};

// Registers the listener.
splitInstallManager.registerListener(listener);

...

splitInstallManager
    .startInstall(request)
    // When the platform accepts your request to download
    // an on demand module, it binds it to the following session ID.
    // You use this ID to track further status updates for the request.
    .addOnSuccessListener(sessionId -> { mySessionId = sessionId; })
    // You should also add the following listener to handle any errors
    // processing the request.
    .addOnFailureListener(exception -> {
        // Handle request errors.
    });

// When your app no longer requires further updates, unregister the listener.
splitInstallManager.unregisterListener(listener);

Menangani error permintaan

Perlu diingat bahwa penginstalan modul fitur secara on demand terkadang dapat gagal, seperti halnya penginstalan aplikasi yang tidak selalu berhasil. Kegagalan penginstalan dapat disebabkan oleh masalah seperti kapasitas penyimpanan perangkat yang rendah, tidak ada konektivitas jaringan, atau pengguna tidak login ke Google Play Store. Untuk mengetahui saran tentang cara menangani situasi ini dengan lancar dari sudut pandang pengguna, lihat panduan UX untuk pengiriman on-demand.

Menurut kodenya, Anda harus menangani kegagalan saat mendownload atau menginstal modul menggunakan addOnFailureListener(), seperti yang ditunjukkan di bawah ini:

Kotlin

splitInstallManager
    .startInstall(request)
    .addOnFailureListener { exception ->
        when ((exception as SplitInstallException).errorCode) {
            SplitInstallErrorCode.NETWORK_ERROR -> {
                // Display a message that requests the user to establish a
                // network connection.
            }
            SplitInstallErrorCode.ACTIVE_SESSIONS_LIMIT_EXCEEDED -> checkForActiveDownloads()
            ...
        }
    }

fun checkForActiveDownloads() {
    splitInstallManager
        // Returns a SplitInstallSessionState object for each active session as a List.
        .sessionStates
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                // Check for active sessions.
                for (state in task.result) {
                    if (state.status() == SplitInstallSessionStatus.DOWNLOADING) {
                        // Cancel the request, or request a deferred installation.
                    }
                }
            }
        }
}

Java

splitInstallManager
    .startInstall(request)
    .addOnFailureListener(exception -> {
        switch (((SplitInstallException) exception).getErrorCode()) {
            case SplitInstallErrorCode.NETWORK_ERROR:
                // Display a message that requests the user to establish a
                // network connection.
                break;
            case SplitInstallErrorCode.ACTIVE_SESSIONS_LIMIT_EXCEEDED:
                checkForActiveDownloads();
            ...
    });

void checkForActiveDownloads() {
    splitInstallManager
        // Returns a SplitInstallSessionState object for each active session as a List.
        .getSessionStates()
        .addOnCompleteListener( task -> {
            if (task.isSuccessful()) {
                // Check for active sessions.
                for (SplitInstallSessionState state : task.getResult()) {
                    if (state.status() == SplitInstallSessionStatus.DOWNLOADING) {
                        // Cancel the request, or request a deferred installation.
                    }
                }
            }
        });
}

Tabel di bawah menjelaskan status error yang mungkin perlu ditangani oleh aplikasi Anda:

Kode error Deskripsi Tindakan yang disarankan
ACTIVE_SESSIONS_LIMIT_EXCEEDED Permintaan ditolak karena terdapat setidaknya satu permintaan yang ada yang sedang didownload. Periksa apakah ada permintaan apa pun yang masih didownload, seperti yang ditunjukkan pada contoh di atas.
MODULE_UNAVAILABLE Google Play tidak dapat menemukan modul yang diminta berdasarkan versi aplikasi yang terinstal saat ini, perangkat, dan akun Google Play pengguna. Jika pengguna tidak memiliki akses ke modul, beri tahu mereka.
INVALID_REQUEST Google Play menerima permintaan, tetapi permintaan tidak valid. Verifikasi bahwa informasi yang disertakan dalam permintaan sudah lengkap dan akurat.
SESSION_NOT_FOUND Sesi untuk ID sesi yang diberikan tidak ditemukan. Jika Anda mencoba memantau status permintaan berdasarkan ID sesinya, pastikan ID sesi sudah benar.
API_NOT_AVAILABLE Library Play Feature Delivery tidak didukung di perangkat saat ini. Artinya, perangkat tidak dapat mendownload dan menginstal fitur on demand. Untuk perangkat yang menjalankan Android 4.4 (level API 20) atau lebih rendah, Anda harus menyertakan modul fitur pada waktu penginstalan menggunakan properti manifes dist:fusing. Untuk mempelajari lebih lanjut, baca manifes modul fitur.
NETWORK_ERROR Permintaan gagal karena error jaringan. Minta pengguna untuk membuat koneksi jaringan atau beralih ke jaringan lain.
ACCESS_DENIED Aplikasi tidak dapat mendaftarkan permintaan karena izin tidak memadai. Hal ini biasanya terjadi saat aplikasi berada di latar belakang. Coba permintaan saat aplikasi kembali ke latar depan.
INCOMPATIBLE_WITH_EXISTING_SESSION Permintaan berisi satu atau beberapa modul yang telah diminta tetapi belum diinstal. Buat permintaan baru yang tidak menyertakan modul yang telah diminta oleh aplikasi Anda, atau tunggu semua modul yang saat ini diminta untuk menyelesaikan penginstalan sebelum mencoba kembali permintaan tersebut.

Perlu diingat, meminta modul yang telah diinstal tidak menyelesaikan error.

SERVICE_DIED Layanan yang bertanggung jawab untuk menangani permintaan sudah tidak berlaku. Coba lagi permintaan tersebut.

SplitInstallStateUpdatedListener menerima SplitInstallSessionState dengan kode error, status FAILED dan ID sesi -1.

INSUFFICIENT_STORAGE Perangkat tidak memiliki penyimpanan gratis yang cukup untuk menginstal modul fitur. Beri tahu pengguna bahwa mereka tidak memiliki penyimpanan yang cukup untuk menginstal fitur ini.
SPLITCOMPAT_VERIFICATION_ERROR, SPLITCOMPAT_EMULATION_ERROR, SPLITCOMPAT_COPY_ERROR SplitCompat tidak dapat memuat modul fitur. Error ini akan otomatis teratasi dengan sendirinya setelah aplikasi dimulai ulang.
PLAY_STORE_NOT_FOUND Aplikasi Play Store belum diinstal di perangkat. Beri tahu pengguna bahwa aplikasi Play Store diperlukan untuk mendownload fitur ini.
APP_NOT_OWNED Aplikasi belum diinstal oleh Google Play dan fitur tidak dapat didownload. Error ini hanya dapat terjadi pada penginstalan yang ditangguhkan. Jika Anda ingin pengguna memperoleh aplikasi di Google Play, gunakan startInstall() yang dapat memperoleh konfirmasi pengguna yang diperlukan.
INTERNAL_ERROR Terjadi error internal dalam Play Store. Coba lagi permintaan tersebut.

Jika pengguna meminta untuk mendownload modul on demand dan terjadi error, sebaiknya tampilkan dialog yang memberikan dua opsi kepada pengguna: Coba lagi (yang mencoba mengajukan permintaan lagi) dan Batal (yang membatalkan permintaan tersebut). Untuk dukungan tambahan, Anda juga harus menyediakan link Bantuan yang mengarahkan pengguna ke Pusat Bantuan Google Play.

Menangani perubahan status

Setelah Anda mendaftarkan pemroses dan mencatat ID sesi untuk permintaan Anda, gunakan StateUpdatedListener.onStateUpdate() untuk menangani perubahan status, seperti yang ditunjukkan di bawah ini.

Kotlin

override fun onStateUpdate(state : SplitInstallSessionState) {
    if (state.status() == SplitInstallSessionStatus.FAILED
        && state.errorCode() == SplitInstallErrorCode.SERVICE_DIED) {
       // Retry the request.
       return
    }
    if (state.sessionId() == mySessionId) {
        when (state.status()) {
            SplitInstallSessionStatus.DOWNLOADING -> {
              val totalBytes = state.totalBytesToDownload()
              val progress = state.bytesDownloaded()
              // Update progress bar.
            }
            SplitInstallSessionStatus.INSTALLED -> {

              // After a module is installed, you can start accessing its content or
              // fire an intent to start an activity in the installed module.
              // For other use cases, see access code and resources from installed modules.

              // If the request is an on demand module for an Android Instant App
              // running on Android 8.0 (API level 26) or higher, you need to
              // update the app context using the SplitInstallHelper API.
            }
        }
    }
}

Java

@Override
public void onStateUpdate(SplitInstallSessionState state) {
    if (state.status() == SplitInstallSessionStatus.FAILED
        && state.errorCode() == SplitInstallErrorCode.SERVICE_DIES) {
       // Retry the request.
       return;
    }
    if (state.sessionId() == mySessionId) {
        switch (state.status()) {
            case SplitInstallSessionStatus.DOWNLOADING:
              int totalBytes = state.totalBytesToDownload();
              int progress = state.bytesDownloaded();
              // Update progress bar.
              break;

            case SplitInstallSessionStatus.INSTALLED:

              // After a module is installed, you can start accessing its content or
              // fire an intent to start an activity in the installed module.
              // For other use cases, see access code and resources from installed modules.

              // If the request is an on demand module for an Android Instant App
              // running on Android 8.0 (API level 26) or higher, you need to
              // update the app context using the SplitInstallHelper API.
        }
    }
}

Status yang memungkinkan untuk permintaan penginstalan Anda dijelaskan dalam tabel di bawah ini.

Status permintaan Deskripsi Tindakan yang disarankan
PENDING Permintaan telah diterima dan download akan segera dimulai. Menginisialisasi komponen UI, seperti status progres, untuk memberikan masukan kepada pengguna mengenai download.
REQUIRES_USER_CONFIRMATION Proses download ini memerlukan konfirmasi pengguna. Paling sering status ini muncul jika aplikasi belum diinstal melalui Google Play. Minta pengguna untuk mengonfirmasi download fitur melalui Google Play. Untuk mempelajari lebih lanjut, buka bagian tentang cara mendapatkan konfirmasi pengguna.
DOWNLOADING Proses download sedang berlangsung. Jika Anda menyediakan status progres untuk download, gunakan metode SplitInstallSessionState.bytesDownloaded() dan SplitInstallSessionState.totalBytesToDownload() untuk mengupdate UI (lihat contoh kode di atas tabel ini).
DOWNLOADED Perangkat telah mendownload modul, tetapi penginstalan belum dimulai. Aplikasi harus mengaktifkan SplitCompat agar memiliki akses ke modul yang didownload dan terhindar dari status ini. Hal ini diperlukan untuk mengakses kode dan resource modul fitur.
INSTALLING Perangkat saat ini sedang menginstal modul. Memperbarui status progres. Status ini biasanya singkat.
INSTALLED Modul diinstal di perangkat. Kode akses dan resource dalam modul untuk melanjutkan perjalanan pengguna.

Jika modul ditujukan untuk Aplikasi Instan Android yang berjalan di Android 8.0 (level API 26) atau yang lebih tinggi, Anda harus menggunakan splitInstallHelper untuk mengupdate komponen aplikasi dengan modul baru.

FAILED Permintaan gagal sebelum modul diinstal di perangkat. Minta pengguna untuk mencoba kembali permintaan atau membatalkannya.
CANCELING Perangkat sedang dalam proses membatalkan permintaan. Untuk mempelajari lebih lanjut, buka bagian tentang cara membatalkan permintaan penginstalan.
CANCELED Permintaan telah dibatalkan.

Mendapatkan konfirmasi pengguna

Dalam beberapa kasus, Google Play mungkin memerlukan konfirmasi pengguna sebelum memenuhi permintaan download. Misalnya, jika aplikasi Anda belum diinstal oleh Google Play atau jika Anda mencoba download yang besar melalui data seluler. Dalam kasus semacam itu, status laporan permintaan REQUIRES_USER_CONFIRMATION dan aplikasi Anda perlu mendapatkan konfirmasi pengguna sebelum perangkat dapat mendownload dan menginstal modul yang diminta. Untuk mendapatkan konfirmasi, aplikasi Anda akan meminta pengguna seperti berikut:

Kotlin

override fun onSessionStateUpdate(state: SplitInstallSessionState) {
    if (state.status() == SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION) {
        // Displays a confirmation for the user to confirm the request.
        splitInstallManager.startConfirmationDialogForResult(
          state,
          // an activity result launcher registered via registerForActivityResult
          activityResultLauncher)
    }
    ...
 }

Java

@Override void onSessionStateUpdate(SplitInstallSessionState state) {
    if (state.status() == SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION) {
        // Displays a confirmation for the user to confirm the request.
        splitInstallManager.startConfirmationDialogForResult(
          state,
          // an activity result launcher registered via registerForActivityResult
          activityResultLauncher);
    }
    ...
 }

Anda dapat mendaftarkan peluncur hasil aktivitas menggunakan kontrak ActivityResultContracts.StartIntentSenderForResult bawaan. Lihat Activity Result API.

Status permintaan akan diperbarui bergantung pada respons pengguna:

  • Jika pengguna menyetujui konfirmasi, status permintaan akan berubah menjadi PENDING dan proses download akan dilanjutkan.
  • Jika pengguna menolak konfirmasi, status permintaan akan berubah menjadi CANCELED.
  • Jika pengguna tidak memilih apa pun sebelum dialog ditutup, status permintaan tetap menjadi REQUIRES_USER_CONFIRMATION. Aplikasi Anda dapat meminta pengguna kembali untuk menyelesaikan permintaan.

Untuk menerima callback dengan respons pengguna, Anda dapat mengganti ActivityResultCallback seperti yang ditunjukkan di bawah ini.

Kotlin

registerForActivityResult(StartIntentSenderForResult()) { result: ActivityResult -> {
        // Handle the user's decision. For example, if the user selects "Cancel",
        // you may want to disable certain functionality that depends on the module.
    }
}

Java

registerForActivityResult(
    new ActivityResultContracts.StartIntentSenderForResult(),
    new ActivityResultCallback<ActivityResult>() {
        @Override
        public void onActivityResult(ActivityResult result) {
            // Handle the user's decision. For example, if the user selects "Cancel",
            // you may want to disable certain functionality that depends on the module.
        }
    });

Membatalkan permintaan penginstalan

Jika aplikasi Anda perlu membatalkan permintaan sebelum diinstal, aplikasi dapat memanggil metode cancelInstall() menggunakan ID sesi permintaan, seperti yang ditunjukkan di bawah ini.

Kotlin

splitInstallManager
    // Cancels the request for the given session ID.
    .cancelInstall(mySessionId)

Java

splitInstallManager
    // Cancels the request for the given session ID.
    .cancelInstall(mySessionId);

Modul akses

Untuk mengakses kode dan resource dari modul yang didownload, aplikasi Anda harus mengaktifkan Library SplitCompat untuk aplikasi dan setiap aktivitas dalam modul fitur yang didownload aplikasi.

Namun, sebaiknya perhatikan bahwa platform memiliki pembatasan berikut untuk mengakses konten modul, selama beberapa waktu (berhari-hari, dalam beberapa kasus) setelah mendownload modul:

  • Platform tidak dapat menerapkan entri manifes baru yang disertakan oleh modul.
  • Platform tidak dapat mengakses resource modul untuk komponen UI sistem, seperti notifikasi. Jika Anda perlu segera menggunakan resource tersebut, pertimbangkan untuk menyertakan resource tersebut dalam modul dasar aplikasi.

Mengaktifkan SplitCompat

Agar aplikasi dapat mengakses kode dan resource dari modul yang didownload, Anda perlu mengaktifkan SplitCompat dengan hanya menggunakan salah satu metode yang dijelaskan di bagian berikut.

Setelah mengaktifkan SplitCompat untuk aplikasi, Anda juga perlu mengaktifkan SplitCompat untuk setiap aktivitas di modul fitur yang Anda inginkan agar dapat diakses oleh aplikasi.

Mendeklarasikan SplitCompatApplication dalam manifes

Cara termudah untuk mengaktifkan SplitCompat adalah dengan mendeklarasikan SplitCompatApplication sebagai subclass Application dalam manifes aplikasi Anda, seperti yang ditunjukkan di bawah:

<application
    ...
    android:name="com.google.android.play.core.splitcompat.SplitCompatApplication">
</application>

Setelah aplikasi terinstal di perangkat, Anda dapat mengakses kode dan resource dari modul fitur yang didownload secara otomatis.

Memanggil SplitCompat pada saat runtime

Anda juga dapat mengaktifkan SplitCompat dalam aktivitas atau layanan tertentu pada saat runtime. Mengaktifkan SplitCompat dengan cara ini diperlukan untuk meluncurkan aktivitas yang disertakan dalam modul fitur. Untuk melakukannya, ganti attachBaseContext seperti yang ditunjukkan di bawah ini.

Jika Anda memiliki class Application khusus, Anda tidak perlu memperluas SplitCompatApplication untuk dapat mengaktifkan SplitCompat untuk aplikasi Anda, seperti yang ditunjukkan di bawah ini:

Kotlin

class MyApplication : SplitCompatApplication() {
    ...
}

Java

public class MyApplication extends SplitCompatApplication {
    ...
}

SplitCompatApplication hanya mengganti ContextWrapper.attachBaseContext() untuk menyertakan SplitCompat.install(Context applicationContext). Jika tidak ingin class Application memperluas SplitCompatApplication, Anda dapat mengganti metode attachBaseContext() secara manual, seperti berikut:

Kotlin

override fun attachBaseContext(base: Context) {
    super.attachBaseContext(base)
    // Emulates installation of future on demand modules using SplitCompat.
    SplitCompat.install(this)
}

Java

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    // Emulates installation of future on demand modules using SplitCompat.
    SplitCompat.install(this);
}

Jika modul on demand Anda kompatibel dengan aplikasi instan dan aplikasi yang terinstal, Anda dapat memanggil SplitCompat secara kondisional, seperti berikut:

Kotlin

override fun attachBaseContext(base: Context) {
    super.attachBaseContext(base)
    if (!InstantApps.isInstantApp(this)) {
        SplitCompat.install(this)
    }
}

Java

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    if (!InstantApps.isInstantApp(this)) {
        SplitCompat.install(this);
    }
}

Mengaktifkan SplitCompat untuk aktivitas modul

Setelah mengaktifkan SplitCompat untuk aplikasi dasar, Anda perlu mengaktifkan SplitCompat untuk setiap aktivitas yang didownload aplikasi dalam modul fitur. Untuk melakukannya, gunakan metode SplitCompat.installActivity(), seperti berikut:

Kotlin

override fun attachBaseContext(base: Context) {
    super.attachBaseContext(base)
    // Emulates installation of on demand modules using SplitCompat.
    SplitCompat.installActivity(this)
}

Java

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    // Emulates installation of on demand modules using SplitCompat.
    SplitCompat.installActivity(this);
}

Mengakses komponen yang ditentukan dalam modul fitur

Memulai aktivitas yang ditentukan dalam modul fitur

Anda dapat meluncurkan aktivitas yang ditentukan dalam modul fitur menggunakan startActivity() setelah mengaktifkan SplitCompat.

Kotlin

startActivity(Intent()
  .setClassName("com.package", "com.package.module.MyActivity")
  .setFlags(...))

Java

startActivity(new Intent()
  .setClassName("com.package", "com.package.module.MyActivity")
  .setFlags(...));

Parameter pertama untuk setClassName adalah nama paket aplikasi dan parameter kedua adalah nama class lengkap aktivitas.

Jika Anda memiliki aktivitas di modul fitur yang didownload sesuai permintaan, Anda harus mengaktifkan SplitCompat di aktivitas.

Memulai layanan yang ditentukan dalam modul fitur

Anda dapat meluncurkan layanan yang ditentukan dalam modul fitur menggunakan startService() setelah mengaktifkan SplitCompat.

Kotlin

startService(Intent()
  .setClassName("com.package", "com.package.module.MyService")
  .setFlags(...))

Java

startService(new Intent()
  .setClassName("com.package", "com.package.module.MyService")
  .setFlags(...));

Mengekspor komponen yang ditentukan dalam modul fitur

Anda tidak boleh menyertakan komponen Android yang diekspor ke dalam modul opsional.

Sistem build menggabungkan entri manifes untuk semua modul ke dalam modul dasar; jika modul opsional berisi komponen yang diekspor, modul tersebut akan dapat diakses bahkan sebelum modul diinstal dan dapat menyebabkan error karena kode tidak ada saat dipanggil dari aplikasi lain.

Ini bukan masalah untuk komponen internal; modul hanya dapat diakses oleh aplikasi, sehingga aplikasi dapat memeriksa apakah modul telah diinstal sebelum mengakses komponen.

Jika Anda memerlukan komponen yang diekspor, dan ingin kontennya berada dalam modul opsional, sebaiknya implementasikan pola proxy. Anda dapat melakukannya dengan menambahkan komponen yang diekspor proxy ke modul dasar. Jika diakses, komponen proxy dapat memeriksa keberadaan modul yang berisi konten. Jika modul ada, komponen proxy dapat memulai komponen internal dari modul melalui Intent, yang meneruskan intent dari aplikasi pemanggil. Jika modul tidak ada, komponen dapat mendownload modul atau menampilkan pesan error yang sesuai ke aplikasi pemanggil.

Mengakses kode dan resource dari modul yang terinstal

Jika Anda mengaktifkan SplitCompat untuk konteks aplikasi dasar dan aktivitas di modul fitur, Anda dapat menggunakan kode dan resource dari modul fitur seolah-olah merupakan bagian dari APK dasar, setelah modul opsional diinstal.

Mengakses kode dari modul lain

Mengakses kode dasar dari modul

Kode yang ada di dalam modul dasar dapat digunakan langsung oleh modul lain. Anda tidak perlu melakukan tindakan khusus; cukup impor dan gunakan class yang dibutuhkan.

Mengakses kode modul dari modul lain

Objek atau class di dalam modul tidak dapat diakses secara statis dari modul lain secara langsung, tetapi dapat diakses secara tidak langsung, menggunakan refleksi.

Anda harus mewaspadai seberapa sering hal ini terjadi, karena biaya performa refleksi. Untuk kasus penggunaan yang kompleks, gunakan framework injeksi dependensi seperti Dagger 2 untuk menjamin satu panggilan refleksi per masa aktif aplikasi.

Untuk menyederhanakan interaksi dengan objek setelah pembuatan instance, sebaiknya tentukan antarmuka di modul dasar dan implementasinya dalam modul fitur. Sebagai contoh:

Kotlin

// In the base module
interface MyInterface {
  fun hello(): String
}

// In the feature module
object MyInterfaceImpl : MyInterface {
  override fun hello() = "Hello"
}

// In the base module, where we want to access the feature module code
val stringFromModule = (Class.forName("com.package.module.MyInterfaceImpl")
    .kotlin.objectInstance as MyInterface).hello();

Java

// In the base module
public interface MyInterface {
  String hello();
}

// In the feature module
public class MyInterfaceImpl implements MyInterface {
  @Override
  public String hello() {
    return "Hello";
  }
}

// In the base module, where we want to access the feature module code
String stringFromModule =
   ((MyInterface) Class.forName("com.package.module.MyInterfaceImpl").getConstructor().newInstance()).hello();

Mengakses resource dan aset dari modul lain

Setelah modul diinstal, Anda dapat mengakses resource dan aset di dalam modul dengan cara standar, dengan dua peringatan:

  • Jika Anda mengakses resource dari modul lain, modul tersebut tidak akan memiliki akses ke ID resource, meskipun resource tetap dapat diakses berdasarkan nama. Perhatikan bahwa paket yang akan digunakan untuk mereferensikan resource adalah paket modul tempat resource ditentukan.
  • Jika Anda ingin mengakses aset atau resource yang ada dalam modul yang baru diinstal dari modul aplikasi terinstal lain, Anda harus melakukannya menggunakan konteks aplikasi. Konteks komponen yang mencoba mengakses resource belum akan diupdate. Atau, Anda dapat membuat ulang komponen tersebut (misalnya memanggil Activity.recreate()) atau menginstal ulang SplitCompat pada komponen tersebut setelah penginstalan modul fitur.

Memuat kode native di aplikasi menggunakan pengiriman on demand

Sebaiknya gunakan ReLinker untuk memuat semua library native Anda saat menggunakan pengiriman on-demand modul fitur. ReLinker memperbaiki masalah dalam memuat library native setelah penginstalan modul fitur. Anda dapat mempelajari ReLinker lebih lanjut di Tips JNI Android.

Memuat kode native dari modul opsional

Setelah pemisah diinstal, sebaiknya muat kode native-nya melalui ReLinker. Untuk aplikasi instan, Anda harus menggunakan metode khusus ini.

Jika Anda menggunakan System.loadLibrary() untuk memuat kode native dan library native Anda memiliki dependensi pada library lain dalam modul, Anda harus memuat library lain tersebut secara manual terlebih dahulu. Jika Anda menggunakan ReLinker, operasi yang setara adalah Relinker.recursively().loadLibrary().

Jika Anda menggunakan dlopen() dalam kode native untuk memuat library yang ditentukan dalam modul opsional, kode tersebut tidak akan berfungsi dengan jalur library relatif. Solusi terbaik adalah mengambil jalur library absolut dari kode Java melalui ClassLoader.findLibrary(), lalu menggunakannya dalam panggilan dlopen(). Lakukan hal ini sebelum memasukkan kode native atau gunakan panggilan JNI dari kode native ke Java.

Mengakses Aplikasi Instan Android yang terinstal

Setelah modul Aplikasi Instan Android dilaporkan sebagai INSTALLED, Anda dapat mengakses kode dan resource-nya menggunakan Konteks aplikasi yang dimuat ulang. Konteks yang dibuat aplikasi Anda sebelum menginstal modul (misalnya, yang telah tersimpan dalam variabel) tidak berisi konten modul baru. Tetapi, konteks yang benar-benar baru berisi modul baru—hal ini dapat diperoleh, misalnya, menggunakan createPackageContext.

Kotlin

// Generate a new context as soon as a request for a new module
// reports as INSTALLED.
override fun onStateUpdate(state: SplitInstallSessionState ) {
    if (state.sessionId() == mySessionId) {
        when (state.status()) {
            ...
            SplitInstallSessionStatus.INSTALLED -> {
                val newContext = context.createPackageContext(context.packageName, 0)
                // If you use AssetManager to access your app’s raw asset files, you’ll need
                // to generate a new AssetManager instance from the updated context.
                val am = newContext.assets
            }
        }
    }
}

Java

// Generate a new context as soon as a request for a new module
// reports as INSTALLED.
@Override
public void onStateUpdate(SplitInstallSessionState state) {
    if (state.sessionId() == mySessionId) {
        switch (state.status()) {
            ...
            case SplitInstallSessionStatus.INSTALLED:
                Context newContext = context.createPackageContext(context.getPackageName(), 0);
                // If you use AssetManager to access your app’s raw asset files, you’ll need
                // to generate a new AssetManager instance from the updated context.
                AssetManager am = newContext.getAssets();
        }
    }
}

Aplikasi Instan Android di Android 8.0 dan yang lebih tinggi

Saat meminta modul on demand untuk Aplikasi Instan Android di Android 8.0 (level API 26) dan yang lebih tinggi, setelah permintaan penginstalan dilaporkan sebagai INSTALLED, Anda perlu mengupdate aplikasi dengan konteks modul baru melalui panggilan ke SplitInstallHelper.updateAppInfo(Context context). Jika tidak, aplikasi tidak akan mengetahui kode dan resource modul. Setelah mengupdate metadata aplikasi, Anda harus memuat konten modul selama peristiwa thread utama berikutnya dengan memanggil Handler baru, seperti yang ditunjukkan di bawah:

Kotlin

override fun onStateUpdate(state: SplitInstallSessionState ) {
    if (state.sessionId() == mySessionId) {
        when (state.status()) {
            ...
            SplitInstallSessionStatus.INSTALLED -> {
                // You need to perform the following only for Android Instant Apps
                // running on Android 8.0 (API level 26) and higher.
                if (BuildCompat.isAtLeastO()) {
                    // Updates the app’s context with the code and resources of the
                    // installed module.
                    SplitInstallHelper.updateAppInfo(context)
                    Handler().post {
                        // Loads contents from the module using AssetManager
                        val am = context.assets
                        ...
                    }
                }
            }
        }
    }
}

Java

@Override
public void onStateUpdate(SplitInstallSessionState state) {
    if (state.sessionId() == mySessionId) {
        switch (state.status()) {
            ...
            case SplitInstallSessionStatus.INSTALLED:
            // You need to perform the following only for Android Instant Apps
            // running on Android 8.0 (API level 26) and higher.
            if (BuildCompat.isAtLeastO()) {
                // Updates the app’s context with the code and resources of the
                // installed module.
                SplitInstallHelper.updateAppInfo(context);
                new Handler().post(new Runnable() {
                    @Override public void run() {
                        // Loads contents from the module using AssetManager
                        AssetManager am = context.getAssets();
                        ...
                    }
                });
            }
        }
    }
}

Memuat library C/C++

Jika Anda ingin memuat library C/C++ dari modul yang telah didownload di Aplikasi Instan, gunakan SplitInstallHelper.loadLibrary(Context context, String libName), seperti yang ditunjukkan di bawah ini:

Kotlin

override fun onStateUpdate(state: SplitInstallSessionState) {
    if (state.sessionId() == mySessionId) {
        when (state.status()) {
            SplitInstallSessionStatus.INSTALLED -> {
                // Updates the app’s context as soon as a module is installed.
                val newContext = context.createPackageContext(context.packageName, 0)
                // To load C/C++ libraries from an installed module, use the following API
                // instead of System.load().
                SplitInstallHelper.loadLibrary(newContext, “my-cpp-lib”)
                ...
            }
        }
    }
}

Java

public void onStateUpdate(SplitInstallSessionState state) {
    if (state.sessionId() == mySessionId) {
        switch (state.status()) {
            case SplitInstallSessionStatus.INSTALLED:
                // Updates the app’s context as soon as a module is installed.
                Context newContext = context.createPackageContext(context.getPackageName(), 0);
                // To load C/C++ libraries from an installed module, use the following API
                // instead of System.load().
                SplitInstallHelper.loadLibrary(newContext, “my-cpp-lib”);
                ...
        }
    }
}

Batasan umum

  • Android WebView tidak dapat digunakan dalam aktivitas yang mengakses resource atau aset dari modul opsional. Hal ini terjadi karena ketidakcocokan antara WebView dan SplitCompat di Android level API 28 dan yang lebih rendah.
  • Anda tidak dapat menyimpan cache objek ApplicationInfo Android, kontennya, atau objek yang memuatnya di dalam aplikasi Anda. Objek ini harus selalu diambil sesuai kebutuhan dari konteks aplikasi. Menyimpan cache objek semacam itu dapat menyebabkan aplikasi tidak bekerja saat menginstal modul fitur.

Mengelola modul yang terinstal

Untuk memeriksa modul fitur yang saat ini terinstal pada perangkat, Anda dapat memanggil SplitInstallManager.getInstalledModules(), yang menampilkan Set<String> dari nama modul yang terinstal, seperti yang ditunjukkan di bawah ini.

Kotlin

val installedModules: Set<String> = splitInstallManager.installedModules

Java

Set<String> installedModules = splitInstallManager.getInstalledModules();

Meng-uninstal modul

Anda dapat meminta perangkat untuk meng-uninstal modul dengan memanggil SplitInstallManager.deferredUninstall(List<String> moduleNames), seperti yang ditunjukkan di bawah ini.

Kotlin

// Specifies two feature modules for deferred uninstall.
splitInstallManager.deferredUninstall(listOf("pictureMessages", "promotionalFilters"))

Java

// Specifies two feature modules for deferred uninstall.
splitInstallManager.deferredUninstall(Arrays.asList("pictureMessages", "promotionalFilters"));

Proses uninstal modul tidak terjadi secara langsung. Artinya, perangkat meng-uninstalnya di latar belakang sesuai kebutuhan untuk menghemat ruang penyimpanan. Anda dapat mengonfirmasi bahwa perangkat telah menghapus modul dengan memanggil SplitInstallManager.getInstalledModules() dan memeriksa hasilnya, seperti yang dijelaskan di bagian sebelumnya.

Mendownload resource bahasa tambahan

Dengan app bundle, perangkat hanya mendownload kode dan resource yang diperlukan untuk menjalankan aplikasi Anda. Jadi, untuk resource bahasa, perangkat pengguna hanya mendownload resource bahasa aplikasi Anda yang cocok dengan satu atau beberapa bahasa yang saat ini dipilih di setelan perangkat.

Jika ingin aplikasi memiliki akses ke resource bahasa tambahan—misalnya, untuk mengimplementasikan pemilih bahasa dalam aplikasi, Anda dapat menggunakan Library Play Feature Delivery untuk mendownloadnya secara on demand. Prosesnya mirip dengan mendownload modul fitur, seperti yang ditunjukkan di bawah ini.

Kotlin

// Captures the user’s preferred language and persists it
// through the app’s SharedPreferences.
sharedPrefs.edit().putString(LANGUAGE_SELECTION, "fr").apply()
...

// Creates a request to download and install additional language resources.
val request = SplitInstallRequest.newBuilder()
        // Uses the addLanguage() method to include French language resources in the request.
        // Note that country codes are ignored. That is, if your app
        // includes resources for “fr-FR” and “fr-CA”, resources for both
        // country codes are downloaded when requesting resources for "fr".
        .addLanguage(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
        .build()

// Submits the request to install the additional language resources.
splitInstallManager.startInstall(request)

Java

// Captures the user’s preferred language and persists it
// through the app’s SharedPreferences.
sharedPrefs.edit().putString(LANGUAGE_SELECTION, "fr").apply();
...

// Creates a request to download and install additional language resources.
SplitInstallRequest request =
    SplitInstallRequest.newBuilder()
        // Uses the addLanguage() method to include French language resources in the request.
        // Note that country codes are ignored. That is, if your app
        // includes resources for “fr-FR” and “fr-CA”, resources for both
        // country codes are downloaded when requesting resources for "fr".
        .addLanguage(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
        .build();

// Submits the request to install the additional language resources.
splitInstallManager.startInstall(request);

Permintaan ditangani sama seperti permintaan untuk modul fitur. Artinya, Anda dapat memantau status permintaan seperti yang biasa Anda lakukan.

Jika aplikasi Anda tidak memerlukan resource bahasa tambahan dengan segera, Anda dapat menunda penginstalan saat aplikasi berada di latar belakang, seperti yang ditunjukkan di bawah ini.

Kotlin

splitInstallManager.deferredLanguageInstall(
    Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))

Java

splitInstallManager.deferredLanguageInstall(
    Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));

Mengakses resource bahasa yang didownload

Untuk mendapatkan akses ke resource bahasa yang didownload, aplikasi Anda harus menjalankan metode SplitCompat.installActivity() dalam metode attachBaseContext() dari setiap aktivitas yang memerlukan akses ke resource tersebut, seperti yang ditunjukkan di bawah ini.

Kotlin

override fun attachBaseContext(base: Context) {
  super.attachBaseContext(base)
  SplitCompat.installActivity(this)
}

Java

@Override
protected void attachBaseContext(Context base) {
  super.attachBaseContext(base);
  SplitCompat.installActivity(this);
}

Untuk setiap aktivitas yang Anda inginkan untuk menggunakan resource bahasa yang telah didownload oleh aplikasi Anda, lakukan update konteks dasarnya dan tetapkan lokalitas baru melalui Configuration:

Kotlin

override fun attachBaseContext(base: Context) {
  val configuration = Configuration()
  configuration.setLocale(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
  val context = base.createConfigurationContext(configuration)
  super.attachBaseContext(context)
  SplitCompat.install(this)
}

Java

@Override
protected void attachBaseContext(Context base) {
  Configuration configuration = new Configuration();
  configuration.setLocale(Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));
  Context context = base.createConfigurationContext(configuration);
  super.attachBaseContext(context);
  SplitCompat.install(this);
}

Agar perubahan ini dapat berpengaruh, Anda harus membuat ulang aktivitas setelah bahasa baru diinstal dan siap digunakan. Anda dapat menggunakan metode Activity#recreate().

Kotlin

when (state.status()) {
  SplitInstallSessionStatus.INSTALLED -> {
      // Recreates the activity to load resources for the new language
      // preference.
      activity.recreate()
  }
  ...
}

Java

switch (state.status()) {
  case SplitInstallSessionStatus.INSTALLED:
      // Recreates the activity to load resources for the new language
      // preference.
      activity.recreate();
  ...
}

Meng-uninstal resource bahasa tambahan

Seperti halnya modul fitur, Anda dapat meng-uninstal resource tambahan kapan saja. Sebelum meminta uninstal, Anda mungkin perlu menentukan bahasa yang terinstal saat ini, seperti berikut.

Kotlin

val installedLanguages: Set<String> = splitInstallManager.installedLanguages

Java

Set<String> installedLanguages = splitInstallManager.getInstalledLanguages();

Kemudian Anda dapat menentukan bahasa yang ingin di-uninstal menggunakan metode deferredLanguageUninstall(), seperti yang ditunjukkan di bawah ini.

Kotlin

splitInstallManager.deferredLanguageUninstall(
    Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))

Java

splitInstallManager.deferredLanguageUninstall(
    Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));

Menguji penginstalan modul secara lokal

Library Play Feature Delivery memungkinkan Anda menguji kemampuan aplikasi untuk melakukan hal berikut secara lokal, tanpa terhubung ke Play Store:

Halaman ini menjelaskan cara men-deploy APK terpisah di aplikasi Anda ke perangkat pengujian agar Play Feature Delivery secara otomatis menggunakan APK tersebut untuk membuat simulasi permintaan, download, dan penginstalan modul dari Play Store.

Meskipun tidak perlu melakukan perubahan pada logika aplikasi, Anda harus memenuhi persyaratan berikut:

  • Mendownload dan menginstal bundletool versi terbaru. Anda perlu bundletool untuk membangun kumpulan APK baru yang dapat diinstal dari paket aplikasi Anda.

Membuat kumpulan APK

Jika Anda belum melakukannya, buat APK terpisah di aplikasi Anda, seperti berikut:

  1. Buat app bundle untuk aplikasi Anda menggunakan salah satu metode berikut:
  2. Gunakan bundletool untuk membuat kumpulan APK untuk semua konfigurasi perangkat dengan perintah berikut:

    bundletool build-apks --local-testing
      --bundle my_app.aab
      --output my_app.apks
    

Flag --local-testing menyertakan meta-data dalam manifes APK yang memungkinkan Library Play Feature Delivery mengetahui cara menggunakan APK terpisah lokal untuk menguji penginstalan modul fitur, tanpa terhubung ke Play Store.

Men-deploy aplikasi Anda ke perangkat

Setelah Anda mem-build kumpulan APK menggunakan flag --local-testing, gunakan bundletool untuk menginstal versi dasar aplikasi Anda dan mentransfer APK tambahan ke penyimpanan lokal perangkat Anda. Anda dapat melakukan kedua tindakan tersebut dengan perintah berikut:

bundletool install-apks --apks my_app.apks

Sekarang, saat Anda memulai aplikasi dan menyelesaikan alur penggunaan untuk mendownload dan menginstal modul fitur, Library Play Feature Delivery menggunakan APK yang ditransfer bundletool ke penyimpanan lokal perangkat.

Membuat simulasi error jaringan

Untuk membuat simulasi penginstalan modul dari Play Store, Library Play Feature Delivery menggunakan alternatif SplitInstallManager, yang disebut FakeSplitInstallManager, untuk meminta modul. Saat Anda menggunakan bundletool dengan flag --local-testing untuk mem-build kumpulan APK dan men-deploy-nya ke perangkat pengujian, tindakan itu menyertakan metadata yang menginstruksikan Library Play Feature Delivery untuk secara otomatis mengganti panggilan API aplikasi Anda guna memanggil FakeSplitInstallManager, bukan SplitInstallManager.

FakeSplitInstallManager menyertakan flag boolean yang dapat Anda aktifkan untuk membuat simulasi error jaringan saat aplikasi Anda meminta untuk menginstal modul lagi. Untuk mengakses FakeSplitInstallManager dalam pengujian, Anda bisa mendapatkan instance menggunakan FakeSplitInstallManagerFactory, seperti yang ditunjukkan di bawah ini:

Kotlin

// Creates an instance of FakeSplitInstallManager with the app's context.
val fakeSplitInstallManager = FakeSplitInstallManagerFactory.create(context)
// Tells Play Feature Delivery Library to force the next module request to
// result in a network error.
fakeSplitInstallManager.setShouldNetworkError(true)

Java

// Creates an instance of FakeSplitInstallManager with the app's context.
FakeSplitInstallManager fakeSplitInstallManager =
    FakeSplitInstallManagerFactory.create(context);
// Tells Play Feature Delivery Library to force the next module request to
// result in a network error.
fakeSplitInstallManager.setShouldNetworkError(true);