Özellik modülleri, belirli özellikleri ve kaynakları uygulamanızın temel modülünden ayırmanıza ve uygulama paketinize eklemenize olanak tanır. Play Feature Delivery sayesinde kullanıcılar, uygulamanızın temel APK'sını yükledikten sonra bu bileşenleri isteğe bağlı olarak indirip yükleyebilirler.
Örneğin, resimli mesajları yakalama ve gönderme işlevi içeren ancak kullanıcıların yalnızca küçük bir yüzdesinin resimli mesaj gönderdiği bir mesajlaşma uygulamasını ele alalım. Resimli mesajlaşmayı indirilebilir bir özellik modülü olarak eklemek mantıklı olabilir. Bu sayede, ilk uygulama indirme işlemi tüm kullanıcılar için daha küçük olur ve yalnızca resimli mesaj gönderen kullanıcıların bu ek bileşeni indirmesi gerekir.
Bu tür bir modülerleştirme için daha fazla çaba harcamanız ve uygulamanızın mevcut kodunu yeniden düzenlemeniz gerekebilir. Bu nedenle, uygulamanızın hangi özelliklerinin kullanıcılara isteğe bağlı olarak sunulmasının en faydalı olacağını dikkatlice değerlendirin. İsteğe bağlı özelliklerin en uygun kullanım alanlarını ve yönergelerini daha iyi anlamak için İsteğe bağlı yayınlama için kullanıcı deneyimiyle ilgili en iyi uygulamalar başlıklı makaleyi okuyun.
Uygulama özelliklerini zaman içinde kademeli olarak modüler hale getirmek istiyorsanız isteğe bağlı yayınlama gibi gelişmiş yayınlama seçeneklerini etkinleştirmeden yükleme sırasında yayınlamayı yapılandırın.
Bu sayfa, uygulama projenize özellik modülü eklemenize ve bu modülü isteğe bağlı dağıtım için yapılandırmanıza yardımcı olur. Başlamadan önce Android Studio 3.5 veya sonraki bir sürümü ve Android Gradle eklentisi 3.5.0 veya sonraki bir sürümü kullandığınızdan emin olun.
İsteğe bağlı yayınlama için yeni bir modül yapılandırma
Yeni bir özellik modülü oluşturmanın en kolay yolu Android Studio 3.5 veya sonraki bir sürümü kullanmaktır. Özellik modüllerinin temel uygulama modülüne doğal bir bağımlılığı olduğundan, bunları yalnızca mevcut uygulama projelerine ekleyebilirsiniz.
Android Studio'yu kullanarak uygulama projenize özellik modülü eklemek için aşağıdaki adımları uygulayın:
- Henüz yapmadıysanız uygulama projenizi IDE'de açın.
- Menü çubuğundan File > New > New Module'ü (Dosya > Yeni > Yeni Modül) seçin.
- Create New Module (Yeni Modül Oluştur) iletişim kutusunda Dynamic Feature Module'u (Dinamik Özellik Modülü) seçip Next'i (İleri) tıklayın.
- Configure your new module (Yeni modülünüzü yapılandırın) bölümünde aşağıdakileri tamamlayın:
- Açılır menüden uygulama projeniz için Base application module'ü (Temel uygulama modülü) seçin.
- Modül adı belirtin. IDE, Gradle ayarları dosyanızda modülü Gradle alt projesi olarak tanımlamak için bu adı kullanır. Uygulama paketinizi oluşturduğunuzda Gradle, özellik modülünün manifest dosyasında
<manifest split>özelliğini eklemek için alt proje adının son öğesini kullanır. - Modülün paket adını belirtin. Android Studio, varsayılan olarak temel modülün kök paket adını ve önceki adımda belirttiğiniz modül adını birleştiren bir paket adı önerir.
- Modülün desteklemesini istediğiniz Minimum API düzeyini seçin. Bu değer, temel modülün değeriyle eşleşmelidir.
- İleri'yi tıklayın.
Modül İndirme Seçenekleri bölümünde aşağıdakileri yapın:
En fazla 50 karakter kullanarak Modül başlığı'nı belirtin. Platform, modülü kullanıcılara tanımlamak için bu başlığı kullanır. Örneğin, kullanıcının modülü indirmek isteyip istemediğini onaylarken bu başlık kullanılır. Bu nedenle, uygulamanızın temel modülü, modül başlığını çevirebileceğiniz bir dize kaynağı olarak içermelidir. Android Studio'yu kullanarak modülü oluştururken IDE, dize kaynağını sizin için temel modüle ekler ve özellik modülünün manifest dosyasına aşağıdaki girişi ekler:
<dist:module ... dist:title="@string/feature_title"> </dist:module>Yükleme sırasında dahil etme altındaki açılır menüden Yükleme sırasında modülü dahil etme'yi seçin. Android Studio, seçiminizi yansıtmak için modülün manifest dosyasına aşağıdakileri ekler:
<dist:module ... > <dist:delivery> <dist:on-demand/> </dist:delivery> </dist:module>Bu modülün Android 4.4 (API düzeyi 20) ve önceki sürümleri çalıştıran cihazlarda kullanılabilmesini ve çoklu APK'lara dahil edilmesini istiyorsanız Birleştirme'nin yanındaki kutuyu işaretleyin. Bu sayede, bu modül için isteğe bağlı davranışı etkinleştirebilir ve bölünmüş APK'ların indirilip yüklenmesini desteklemeyen cihazlarda bu modülü atlamak için birleştirmeyi devre dışı bırakabilirsiniz. Android Studio, seçiminizi yansıtmak için modülün manifest dosyasına aşağıdakileri ekler:
<dist:module ...> <dist:fusing dist:include="true | false" /> </dist:module>
Son'u tıklayın.
Android Studio modülünüzü oluşturmayı tamamladıktan sonra Proje bölmesinden (menü çubuğundan Görünüm > Araç Pencereleri > Proje'yi seçin) içeriğini kendiniz inceleyin. Varsayılan kod, kaynaklar ve organizasyon, standart uygulama modülündekilere benzer olmalıdır.
Ardından, Play Feature Delivery kitaplığını kullanarak isteğe bağlı yükleme işlevini uygulamanız gerekir.
Play Feature Delivery Kitaplığı'nı projenize ekleme
Başlamadan önce Play Feature Delivery kitaplığını projenize eklemeniz gerekir.
İsteğe bağlı modül talep etme
Uygulamanızın bir özellik modülü kullanması gerektiğinde, ön plandayken SplitInstallManager sınıfı aracılığıyla modül isteğinde bulunabilir. Uygulamanız istekte bulunurken hedef modülün manifest dosyasındaki split öğesi tarafından tanımlanan modülün adını belirtmelidir. Android Studio'yu kullanarak özellik modülü oluşturduğunuzda derleme sistemi, derleme sırasında bu özelliği modülün manifest dosyasına eklemek için sağladığınız Modül adını kullanır.
Daha fazla bilgi için özellik modülü manifestleri hakkında bilgi edinin.
Örneğin, cihazın kamerasını kullanarak resimli mesajlar yakalayıp gönderen isteğe bağlı bir modüle sahip bir uygulama düşünün. Bu isteğe bağlı modül, manifest dosyasında split="pictureMessages" değerini belirtir. Aşağıdaki örnekte, pictureMessages modülünü (bazı tanıtım filtreleri için ek bir modülle birlikte) istemek üzere SplitInstallManager kullanılmıştır:
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 -> { ... });
Uygulamanız isteğe bağlı bir modül istediğinde Play Feature Delivery Kitaplığı, "başlat ve unut" stratejisini kullanır. Yani modülü indirme isteğini platforma gönderir ancak yüklemenin başarılı olup olmadığını izlemez. Yüklemeden sonra kullanıcı yolculuğunu ilerletmek veya hataları düzgün bir şekilde ele almak için istek durumunu izlediğinizden emin olun.
Not: Cihazda zaten yüklü olan bir özellik modülünü talep edebilirsiniz. API, modülün zaten yüklü olduğunu algılarsa isteği anında tamamlanmış olarak kabul eder. Ayrıca, bir modül yüklendikten sonra Google Play bu modülü otomatik olarak güncel tutar. Yani uygulama paketinizin yeni bir sürümünü yüklediğinizde platform, uygulamanıza ait tüm yüklü APK'ları günceller. Daha fazla bilgi için Uygulama güncellemelerini yönetme başlıklı makaleyi okuyun.
Uygulamanızın, modülün koduna ve kaynaklarına erişebilmesi için SplitCompat'i etkinleştirmesi gerekir. SplitCompat'in Android Hazır Uygulamalar için gerekli olmadığını unutmayın.
İsteğe bağlı modüllerin yüklenmesini erteleme
Uygulamanızın seç-izle modülünü hemen indirip yüklemesi gerekmiyorsa yüklemeyi uygulama arka plandayken yapılacak şekilde erteleyebilirsiniz. Örneğin, uygulamanızın daha sonraki bir lansmanı için bazı tanıtım materyallerini önceden yüklemek istiyorsanız bu özelliği kullanabilirsiniz.
Aşağıda gösterildiği gibi deferredInstall() yöntemini kullanarak daha sonra indirilecek bir modül belirtebilirsiniz. Ayrıca, SplitInstallManager.startInstall()'den farklı olarak, uygulamanızın ertelenmiş yükleme isteği başlatmak için ön planda olması gerekmez.
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"));
Ertelenen yükleme istekleri, en iyi çaba ilkesine göre işlenir ve ilerleme durumlarını takip edemezsiniz. Bu nedenle, ertelenmiş yükleme için belirttiğiniz bir modüle erişmeye çalışmadan önce modülün yüklendiğini kontrol etmeniz gerekir. Modülün hemen kullanılabilir olması gerekiyorsa önceki bölümde gösterildiği gibi SplitInstallManager.startInstall() kullanarak istekte bulunun.
İstek durumunu izleme
İlerleme çubuğunu güncellemek, yüklemeden sonra bir intent tetiklemek veya istek hatasını düzgün bir şekilde işlemek için eşzamansız SplitInstallManager.startInstall() görevinden gelen durum güncellemelerini dinlemeniz gerekir.
Yükleme isteğinizle ilgili güncellemeleri almaya başlamadan önce bir dinleyici kaydedin ve aşağıda gösterildiği gibi istek için oturum kimliğini alın.
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);
İstek hatalarını giderme
Özellik modüllerinin isteğe bağlı yüklenmesi, uygulama yükleme işleminin her zaman başarılı olmaması gibi bazen başarısız olabilir. Yükleme hatası, cihaz depolama alanının az olması, ağ bağlantısının olmaması veya kullanıcının Google Play Store'da oturum açmamış olması gibi sorunlardan kaynaklanabilir. Bu durumları kullanıcı açısından sorunsuz bir şekilde ele alma konusunda öneriler için İsteğe bağlı teslimat için kullanıcı deneyimi yönergelerimizi inceleyin.
Kod açısından, bir modülün indirilmesi veya yüklenmesiyle ilgili hataları aşağıda gösterildiği gibi addOnFailureListener() kullanarak ele almanız gerekir:
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. } } } }); }
Aşağıdaki tabloda, uygulamanızın işlemesi gerekebilecek hata durumları açıklanmaktadır:
| Hata kodu | Açıklama | Önerilen işlem |
|---|---|---|
| ACTIVE_SESSIONS_LIMIT_EXCEEDED | Şu anda indirilmekte olan en az bir istek olduğu için istek reddedildi. | Yukarıdaki örnekte gösterildiği gibi, hâlâ indirilmekte olan istekler olup olmadığını kontrol edin. |
| MODULE_UNAVAILABLE | Google Play; uygulamanın yüklü olan mevcut sürümüne, cihaza ve kullanıcının Google Play hesabına göre istenen modülü bulamıyor. | Kullanıcının modüle erişimi yoksa kullanıcıyı bilgilendirin. |
| INVALID_REQUEST | Google Play isteği aldı ancak istek geçerli değil. | İstekte yer alan bilgilerin eksiksiz ve doğru olduğunu doğrulayın. |
| SESSION_NOT_FOUND | Belirli bir oturum kimliği için oturum bulunamadı. | Bir isteğin durumunu oturum kimliğine göre izlemeye çalışıyorsanız oturum kimliğinin doğru olduğundan emin olun. |
| API_NOT_AVAILABLE | Play Feature Delivery Kitaplığı mevcut cihazda desteklenmiyor. Yani cihaz, özellikleri isteğe bağlı olarak indirip yükleyemez. | Android 4.4 (API düzeyi 20) veya daha eski sürümleri çalıştıran cihazlarda, yükleme sırasında dist:fusing manifest özelliğini kullanarak özellik modüllerini eklemeniz gerekir. Daha fazla bilgi edinmek için özellik modülü manifesti ile ilgili makaleyi okuyun.
|
| NETWORK_ERROR | Ağ hatası nedeniyle istek başarısız oldu. | Kullanıcıdan ağ bağlantısı kurmasını veya farklı bir ağa geçmesini isteyin. |
| ERİŞİM_ENGELLENDİ | Uygulama, yetersiz izinler nedeniyle isteği kaydedemiyor. | Bu durum genellikle uygulama arka plandayken ortaya çıkar. Uygulama ön plana döndüğünde isteği deneyin. |
| INCOMPATIBLE_WITH_EXISTING_SESSION | İstek, daha önce istenmiş ancak henüz yüklenmemiş bir veya daha fazla modül içeriyor. | Uygulamanızın daha önce talep ettiği modülleri içermeyen yeni bir istek oluşturun veya isteği yeniden denemeden önce, şu anda talep edilen tüm modüllerin yüklenmesinin tamamlanmasını bekleyin.
Daha önce yüklenmiş bir modülün istenmesi hata vermez. |
| SERVICE_DIED | İsteği işlemekten sorumlu hizmet sonlandırıldı. | İsteği yeniden deneyin.
|
| INSUFFICIENT_STORAGE | Cihazda özellik modülünü yüklemek için yeterli boş depolama alanı yok. | Kullanıcıya bu özelliği yüklemek için yeterli depolama alanı olmadığını bildirin. |
| SPLITCOMPAT_VERIFICATION_ERROR, SPLITCOMPAT_EMULATION_ERROR, SPLITCOMPAT_COPY_ERROR | SplitCompat, özellik modülünü yükleyemedi. | Bu hatalar, uygulama bir sonraki yeniden başlatıldığında otomatik olarak çözülür. |
| PLAY_STORE_NOT_FOUND | Play Store uygulaması cihaza yüklenmemiş. | Kullanıcıya, bu özelliği indirmek için Google Play Store uygulamasının gerekli olduğunu bildirin. |
| APP_NOT_OWNED | Uygulama, Google Play tarafından yüklenmediği için özellik indirilemiyor. Bu hata yalnızca ertelenen yüklemelerde ortaya çıkabilir. | Kullanıcının uygulamayı Google Play'den edinmesini istiyorsanız gerekli kullanıcı onayını alabilen startInstall() yöntemini kullanın. |
| INTERNAL_ERROR | Google Play Store'da dahili bir hata oluştu. | İsteği yeniden deneyin. |
Bir kullanıcı isteğe bağlı modül indirme isteğinde bulunur ve hata oluşursa kullanıcıya iki seçenek sunan bir iletişim kutusu gösterebilirsiniz: Tekrar dene (isteği tekrar dener) ve İptal (isteği iptal eder). Ek destek için kullanıcıları Google Play Yardım Merkezi'ne yönlendiren bir Yardım bağlantısı da sağlamanız gerekir.
Durum güncellemelerini işleme
Bir dinleyici kaydedip isteğiniz için oturum kimliğini kaydettikten sonra, durum değişikliklerini işlemek için aşağıda gösterildiği gibi StateUpdatedListener.onStateUpdate() kullanın.
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. } } }
Yükleme isteğinizin olası durumları aşağıdaki tabloda açıklanmıştır.
| İstek durumu | Açıklama | Önerilen işlem |
|---|---|---|
| BEKLEMEDE | İstek kabul edildi ve indirme işlemi kısa süre içinde başlayacak. | Kullanıcıya indirme işlemiyle ilgili geri bildirim sağlamak için ilerleme çubuğu gibi kullanıcı arayüzü bileşenlerini başlatın. |
| REQUIRES_USER_CONFIRMATION | İndirme işlemi için kullanıcı onayı gerekir. Bu durum en sık, uygulama Google Play üzerinden yüklenmediğinde ortaya çıkar. | Kullanıcıdan, Google Play üzerinden özellik indirme işlemini onaylamasını isteyin. Daha fazla bilgi edinmek için kullanıcı onayı alma ile ilgili bölüme gidin. |
| İNDİRME | İndirme işlemi devam ediyor. | İndirme işlemi için bir ilerleme çubuğu sağlıyorsanız kullanıcı arayüzünü güncellemek için SplitInstallSessionState.bytesDownloaded() ve SplitInstallSessionState.totalBytesToDownload() yöntemlerini kullanın (bu tablonun üstündeki kod örneğine bakın). |
| İNDİRİLENLER | Cihaz modülü indirdi ancak yükleme henüz başlamadı. | Uygulamalar, indirilen modüllere erişmek ve bu durumu görmemek için SplitCompat'i etkinleştirmelidir. Bu, özellik modülünün koduna ve kaynaklarına erişmek için gereklidir. |
| YÜKLENİYOR | Cihaz şu anda modülü yüklüyor. | İlerleme çubuğunu güncelleyin. Bu durum genellikle kısa sürer. |
| YÜKLENDİ | Modül cihaza yüklenir. | Kullanıcı yolculuğuna devam etmek için modüldeki erişim koduna ve kaynağa erişin.
Modül, Android 8.0 (API düzeyi 26) veya sonraki sürümleri çalıştıran bir Android Hazır Uygulama içinse uygulama bileşenlerini yeni modülle güncellemek için |
| BAŞARISIZ | Modül cihaza yüklenmeden önce istek başarısız oldu. | Kullanıcıdan isteği yeniden denemesini veya iptal etmesini isteyin. |
| İPTAL EDİLİYOR | Cihaz, isteği iptal etme sürecindedir. | Daha fazla bilgi edinmek için yükleme isteğini iptal etme ile ilgili bölüme gidin. |
| İPTAL EDİLDİ | İstek iptal edildi. |
Kullanıcı onayı alma
Bazı durumlarda Google Play, indirme isteğini yerine getirmeden önce kullanıcı onayı isteyebilir. Örneğin, uygulamanız Google Play tarafından yüklenmediyse veya mobil veri üzerinden büyük bir indirme işlemi yapmaya çalışıyorsanız. Bu gibi durumlarda, istek durumu REQUIRES_USER_CONFIRMATION olarak bildirilir ve cihazın istekteki modülleri indirip yükleyebilmesi için uygulamanızın kullanıcı onayı alması gerekir. Onay almak için uygulamanız kullanıcıya aşağıdaki gibi bir istem göstermelidir:
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); } ... }
Yerleşik ActivityResultContracts.StartIntentSenderForResult sözleşmesini kullanarak bir etkinlik sonucu başlatıcı kaydedebilirsiniz. Activity Result API'leri bölümüne bakın.
İsteğin durumu, kullanıcının yanıtına göre güncellenir:
- Kullanıcı onayı kabul ederse istek durumu
PENDINGolarak değişir ve indirme işlemi devam eder. - Kullanıcı onayı reddederse istek durumu
CANCELEDolarak değişir. - Kullanıcı, iletişim kutusu kapatılmadan önce seçim yapmazsa istek durumu
REQUIRES_USER_CONFIRMATIONolarak kalır. Uygulamanız, isteği tamamlaması için kullanıcıdan tekrar onay isteyebilir.
Kullanıcının yanıtını içeren bir geri çağırma almak için ActivityResultCallback'i aşağıda gösterildiği gibi geçersiz kılabilirsiniz.
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. } });
Yükleme isteğini iptal etme
Uygulamanızın, yüklenmeden önce bir isteği iptal etmesi gerekiyorsa aşağıda gösterildiği gibi isteğin oturum kimliğini kullanarak cancelInstall() yöntemini çağırabilir.
Kotlin
splitInstallManager // Cancels the request for the given session ID. .cancelInstall(mySessionId)
Java
splitInstallManager // Cancels the request for the given session ID. .cancelInstall(mySessionId);
Erişim modülleri
İndirilen bir modüldeki koda ve kaynaklara erişmek için uygulamanızın hem kendisi hem de indirdiği özellik modüllerindeki her etkinlik için SplitCompat Kitaplığı'nı etkinleştirmesi gerekir.
Ancak platformun, modül indirildikten sonra bir süre (bazı durumlarda günler) boyunca modülün içeriğine erişimle ilgili aşağıdaki kısıtlamalara tabi olduğunu unutmayın:
- Platform, modül tarafından sunulan yeni manifest girişlerini uygulayamaz.
- Platform, bildirimler gibi sistem kullanıcı arayüzü bileşenleri için modülün kaynaklarına erişemez. Bu tür kaynakları hemen kullanmanız gerekiyorsa uygulamanızın temel modülüne ekleyebilirsiniz.
SplitCompat'i etkinleştirme
Uygulamanızın, indirilen bir modüldeki koda ve kaynaklara erişebilmesi için yalnızca aşağıdaki bölümlerde açıklanan yöntemlerden birini kullanarak SplitCompat'i etkinleştirmeniz gerekir.
Uygulamanız için SplitCompat'i etkinleştirdikten sonra, uygulamanızın erişmesini istediğiniz özellik modüllerindeki her etkinlik için SplitCompat'i etkinleştirmeniz gerekir.
Manifest dosyasında SplitCompatApplication'ı beyan etme
SplitCompat'i etkinleştirmenin en kolay yolu, uygulamanızın manifest dosyasında SplitCompatApplication sınıfını Application alt sınıfı olarak tanımlamaktır. Bu işlem aşağıda gösterilmiştir:
<application
...
android:name="com.google.android.play.core.splitcompat.SplitCompatApplication">
</application>
Uygulama bir cihaza yüklendikten sonra, indirilen özellik modüllerindeki koda ve kaynaklara otomatik olarak erişebilirsiniz.
Çalışma zamanında SplitCompat'i çağırma
SplitCompat'i çalışma zamanında belirli etkinliklerde veya hizmetlerde de etkinleştirebilirsiniz.
Özellik modüllerinde yer alan etkinlikleri başlatmak için SplitCompat'i bu şekilde etkinleştirmeniz gerekir. Bunun için attachBaseContext değerini aşağıda gösterildiği gibi geçersiz kılın.
Özel bir Application sınıfınız varsa uygulamanızda SplitCompat'i etkinleştirmek için bu sınıfın SplitCompatApplication sınıfını genişletmesini sağlayın:
Kotlin
class MyApplication : SplitCompatApplication() { ... }
Java
public class MyApplication extends SplitCompatApplication { ... }
SplitCompatApplication, SplitCompat.install(Context applicationContext) değerini içerecek şekilde ContextWrapper.attachBaseContext() değerini geçersiz kılar. Application sınıfınızın SplitCompatApplication sınıfını
genişletmesini istemiyorsanız attachBaseContext()
yöntemini manuel olarak şu şekilde
geçersiz kılabilirsiniz:
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); }
İsteğe bağlı modülünüz hem hazır uygulamalar hem de yüklü uygulamalarla uyumluysa SplitCompat'i koşullu olarak aşağıdaki gibi çağırabilirsiniz:
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); } }
Modül etkinlikleri için SplitCompat'i etkinleştirme
Temel uygulamanız için SplitCompat'i etkinleştirdikten sonra, uygulamanızın bir özellik modülünde indirdiği her etkinlik için SplitCompat'i etkinleştirmeniz gerekir. Bunun için SplitCompat.installActivity() yöntemini aşağıdaki gibi kullanın:
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); }
Özellik modüllerinde tanımlanan bileşenlere erişme
Özellik modülünde tanımlanan bir etkinliği başlatma
SplitCompat'i etkinleştirdikten sonra özellik modüllerinde tanımlanan etkinlikleri startActivity() kullanarak başlatabilirsiniz.
Kotlin
startActivity(Intent() .setClassName("com.package", "com.package.module.MyActivity") .setFlags(...))
Java
startActivity(new Intent() .setClassName("com.package", "com.package.module.MyActivity") .setFlags(...));
setClassName için ilk parametre uygulamanın paket adı, ikinci parametre ise etkinliğin tam sınıf adıdır.
İsteğe bağlı olarak indirdiğiniz bir özellik modülünde etkinliğiniz olduğunda etkinlikte SplitCompat'i etkinleştirmeniz gerekir.
Özellik modülünde tanımlanan bir hizmeti başlatma
SplitCompat'i etkinleştirdikten sonra startService() kullanarak özellik modüllerinde tanımlanan hizmetleri başlatabilirsiniz.
Kotlin
startService(Intent() .setClassName("com.package", "com.package.module.MyService") .setFlags(...))
Java
startService(new Intent() .setClassName("com.package", "com.package.module.MyService") .setFlags(...));
Özellik modülünde tanımlanan bir bileşeni dışa aktarma
İsteğe bağlı modüllere dışa aktarılan Android bileşenleri eklememelisiniz.
Derleme sistemi, tüm modüllerin manifest girişlerini temel modülde birleştirir. İsteğe bağlı bir modül, dışa aktarılan bir bileşen içeriyorsa modül yüklenmeden önce bile erişilebilir olur ve başka bir uygulamadan çağrıldığında eksik kod nedeniyle kilitlenmeye neden olabilir.
Bu durum, dahili bileşenler için sorun teşkil etmez. Bu bileşenlere yalnızca uygulama tarafından erişildiği için uygulama, bileşene erişmeden önce modülün yüklü olup olmadığını kontrol edebilir.
Dışa aktarılan bir bileşene ihtiyacınız varsa ve içeriğinin isteğe bağlı bir modülde olmasını istiyorsanız proxy kalıbı uygulamayı düşünebilirsiniz.
Bunu yapmak için tabana proxy olarak dışa aktarılan bir bileşen ekleyebilirsiniz.
Erişildiğinde proxy bileşeni, içeriği barındıran modülün mevcut olup olmadığını kontrol edebilir. Modül mevcutsa proxy bileşeni, arayan uygulamadan gelen intent'i aktararak Intent aracılığıyla modüldeki dahili bileşeni başlatabilir. Modül mevcut değilse bileşen, modülü indirebilir veya arayan uygulamaya uygun bir hata mesajı döndürebilir.
Yüklü modüllerden erişim koduna ve kaynaklara erişme
Temel uygulama bağlamınız ve özellik modülünüzdeki etkinlikler için SplitCompat'i etkinleştirirseniz isteğe bağlı modül yüklendikten sonra özellik modülündeki kod ve kaynakları temel APK'nın bir parçasıymış gibi kullanabilirsiniz.
Farklı bir modüldeki erişim kodu
Bir modülden temel koda erişme
Temel modülünüzün içindeki kod, diğer modüller tarafından doğrudan kullanılabilir. Özel bir işlem yapmanız gerekmez. İhtiyacınız olan sınıfları içe aktarıp kullanmanız yeterlidir.
Başka bir modülden modül koduna erişme
Bir modülün içindeki nesneye veya sınıfa başka bir modülden doğrudan statik olarak erişilemez ancak yansıma kullanılarak dolaylı olarak erişilebilir.
Yansıtmanın performans maliyetleri nedeniyle bunun ne sıklıkta gerçekleştiğine dikkat etmeniz gerekir. Karmaşık kullanım alanlarında, uygulama ömrü boyunca tek bir yansıma çağrısı yapılmasını garanti etmek için Dagger 2 gibi bağımlılık ekleme çerçeveleri kullanın.
Örneklendirmeden sonra nesneyle etkileşimleri basitleştirmek için temel modülde bir arayüz ve özellik modülünde bu arayüzün uygulamasını tanımlamanız önerilir. Örneğin:
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();
Farklı bir modüldeki kaynaklara ve öğelere erişme
Modül yüklendikten sonra, modüldeki kaynaklara ve öğelere standart şekilde erişebilirsiniz. Ancak iki noktaya dikkat etmeniz gerekir:
- Farklı bir modülden bir kaynağa erişiyorsanız modül, kaynak tanımlayıcıya erişemez ancak kaynağa adıyla erişilebilir. Kaynağa referans vermek için kullanılacak paketin, kaynağın tanımlandığı modülün paketi olduğunu unutmayın.
- Yeni yüklenen bir modüldeki öğelere veya kaynaklara uygulamanızın farklı bir yüklü modülünden erişmek istiyorsanız bunu uygulama bağlamını kullanarak yapmanız gerekir. Kaynaklara erişmeye çalışan bileşenin bağlamı henüz güncellenmez. Alternatif olarak, özellik modülü yüklendikten sonra bu bileşeni yeniden oluşturabilir (örneğin, Activity.recreate() işlevini çağırarak) veya bileşene SplitCompat'i yeniden yükleyebilirsiniz.
İsteğe bağlı yayınlamayı kullanarak bir uygulamaya yerel kod yükleme
Özellik modüllerinin isteğe bağlı yayınlanmasını kullanırken tüm yerel kitaplıklarınızı yüklemek için ReLinker'ı kullanmanızı öneririz. ReLinker, bir özellik modülü yüklendikten sonra yerel kitaplıkların yüklenmesiyle ilgili bir sorunu düzeltir. ReLinker hakkında daha fazla bilgiyi Android JNI İpuçları sayfasında bulabilirsiniz.
İsteğe bağlı bir modülden yerel kod yükleme
Bir bölme yüklendikten sonra yerel kodunu ReLinker aracılığıyla yüklemenizi öneririz. Hazır uygulamalar için bu özel yöntemi kullanmanız gerekir.
Yerel kodunuzu yüklemek için System.loadLibrary() kullanıyorsanız ve yerel kitaplığınızın modüldeki başka bir kitaplığa bağımlılığı varsa önce diğer kitaplığı manuel olarak yüklemeniz gerekir.
ReLinker kullanıyorsanız eşdeğer işlem Relinker.recursively().loadLibrary() şeklindedir.
İsteğe bağlı bir modülde tanımlanan kitaplığı yüklemek için yerel kodda dlopen() kullanıyorsanız bu, göreceli kitaplık yollarıyla çalışmaz.
En iyi çözüm, ClassLoader.findLibrary() aracılığıyla Java kodundan kitaplığın mutlak yolunu almak ve ardından bunu dlopen() çağrınızda kullanmaktır.
Bu işlemi yerel kodu girmeden önce yapın veya yerel kodunuzdan Java'ya bir JNI çağrısı kullanın.
Yüklü Android Hazır Uygulamalara erişme
Bir Android Hazır Uygulama modülü INSTALLED olarak raporlandıktan sonra, yenilenmiş bir uygulama Context'i kullanarak koduna ve kaynaklarına erişebilirsiniz. Uygulamanızın bir modülü yüklemeden önce oluşturduğu bağlam (örneğin, zaten bir değişkende depolanmış olan bağlam), yeni modülün içeriğini içermez. Ancak yeni bir bağlam, bu bilgileri içerir. Bu bağlamı, örneğin createPackageContext kullanarak elde edebilirsiniz.
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(); } } }
Android 8.0 ve sonraki sürümlerde Android Hazır Uygulamalar
Android 8.0 (API düzeyi 26) ve sonraki sürümlerde Android Hazır Uygulamalar için isteğe bağlı modül talep ederken, yükleme isteği INSTALLED olarak bildirildikten sonra SplitInstallHelper.updateAppInfo(Context context) çağrısı yaparak uygulamayı yeni modülün bağlamıyla güncellemeniz gerekir.
Aksi takdirde uygulama, modülün kodunu ve kaynaklarını henüz tanımaz. Uygulamanın meta verilerini güncelledikten sonra, aşağıda gösterildiği gibi yeni bir Handler çağırarak bir sonraki ana iş parçacığı etkinliği sırasında modülün içeriklerini yüklemeniz gerekir:
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(); ... } }); } } } }
C/C++ kitaplıklarını yükleme
Cihazın bir hazır uygulamada daha önce indirdiği bir modülden C/C++ kitaplıkları yüklemek istiyorsanız aşağıda gösterildiği gibi SplitInstallHelper.loadLibrary(Context context, String libName) kullanın:
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”); ... } } }
Bilinen sınırlamalar
- İsteğe bağlı bir modüldeki kaynaklara veya öğelere erişen bir etkinlikte Android WebView kullanılamaz. Bu durum, Android API düzeyi 28 ve daha düşük sürümlerde WebView ile SplitCompat arasındaki uyumsuzluktan kaynaklanır.
- Android
ApplicationInfonesnelerini, içeriklerini veya bunları içeren nesneleri uygulamanızda önbelleğe alamazsınız. Bu nesneleri her zaman uygulama bağlamından gerektiği şekilde getirmeniz gerekir. Bu tür nesnelerin önbelleğe alınması, özellik modülü yüklenirken uygulamanın kilitlenmesine neden olabilir.
Yüklü modülleri yönetme
Cihazda yüklü olan özellik modüllerini kontrol etmek için SplitInstallManager.getInstalledModules() yöntemini çağırabilirsiniz. Bu yöntem, aşağıda gösterildiği gibi yüklü modüllerin adlarını içeren bir Set<String> döndürür.
Kotlin
val installedModules: Set<String> = splitInstallManager.installedModules
Java
Set<String> installedModules = splitInstallManager.getInstalledModules();
Modülleri kaldırma
Aşağıda gösterildiği gibi SplitInstallManager.deferredUninstall(List<String> moduleNames) yöntemini çağırarak cihazdan modülleri kaldırmasını isteyebilirsiniz.
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"));
Modül kaldırma işlemleri hemen gerçekleşmez. Yani cihaz, depolama alanından tasarruf etmek için gerektiğinde bunları arka planda kaldırır.
Önceki bölümde açıklandığı gibi SplitInstallManager.getInstalledModules() komutunu çağırıp sonucu inceleyerek cihazın bir modülü sildiğini doğrulayabilirsiniz.
Ek dil kaynaklarını indirme
Uygulama paketleri sayesinde cihazlar yalnızca uygulamanızı çalıştırmak için gereken kodları ve kaynakları indirir. Bu nedenle, dil kaynakları söz konusu olduğunda kullanıcının cihazı yalnızca cihaz ayarlarında seçili olan dillerle eşleşen dil kaynaklarını indirir.
Uygulamanızın ek dil kaynaklarına erişmesini istiyorsanız (ör. uygulama içi dil seçici uygulamak için) bunları isteğe bağlı olarak indirmek üzere Play Feature Delivery kitaplığını kullanabilirsiniz. Bu işlem, aşağıda gösterildiği gibi özellik modülü indirme işlemine benzer.
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);
İstek, özellik modülü isteğiymiş gibi işlenir. Yani istek durumunu normalde yaptığınız gibi izleyebilirsiniz.
Uygulamanız ek dil kaynaklarına hemen ihtiyaç duymuyorsa yüklemeyi, uygulama arka plandayken yapılacak şekilde erteleyebilirsiniz. Bunun için aşağıdaki yöntemi kullanabilirsiniz.
Kotlin
splitInstallManager.deferredLanguageInstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
Java
splitInstallManager.deferredLanguageInstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));
İndirilen dil kaynaklarına erişme
Uygulamanızın, indirilen dil kaynaklarına erişebilmesi için aşağıda gösterildiği gibi bu kaynaklara erişim gerektiren her etkinliğin attachBaseContext() yönteminde SplitCompat.installActivity() yöntemini çalıştırması gerekir.
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); }
Uygulamanızın indirdiği dil kaynaklarını kullanmak istediğiniz her etkinlik için temel bağlamı güncelleyin ve Configuration aracılığıyla yeni bir yerel ayar belirleyin:
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); }
Bu değişikliklerin geçerli olması için yeni dil yüklendikten ve kullanıma hazır hale geldikten sonra etkinliğinizi yeniden oluşturmanız gerekir. Activity#recreate() yöntemini kullanabilirsiniz.
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(); ... }
Ek dil kaynaklarını kaldırma
Özellik modüllerine benzer şekilde, ek kaynakları istediğiniz zaman kaldırabilirsiniz. Kaldırma isteğinde bulunmadan önce, şu anda hangi dillerin yüklü olduğunu belirlemek isteyebilirsiniz. Bunun için aşağıdaki adımları uygulayın.
Kotlin
val installedLanguages: Set<String> = splitInstallManager.installedLanguages
Java
Set<String> installedLanguages = splitInstallManager.getInstalledLanguages();
Ardından, aşağıda gösterildiği gibi deferredLanguageUninstall() yöntemini kullanarak hangi dillerin kaldırılacağına karar verebilirsiniz.
Kotlin
splitInstallManager.deferredLanguageUninstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
Java
splitInstallManager.deferredLanguageUninstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));
Modül yüklemelerini yerel olarak test etme
Play Feature Delivery kitaplığı, uygulamanızın aşağıdaki işlemleri yapma yeteneğini Play Store'a bağlanmadan yerel olarak test etmenize olanak tanır:
- Modül yükleme isteklerini gönderme ve izleme
- Yükleme hatalarını giderme
- Modüllere erişmek için
SplitCompatkullanın.
Bu sayfada, uygulamanızın bölünmüş APK'larını test cihazınıza nasıl dağıtacağınız açıklanmaktadır. Böylece Play Feature Delivery, Play Store'dan modül isteme, indirme ve yükleme işlemlerini simüle etmek için bu APK'ları otomatik olarak kullanır.
Uygulamanızın mantığında herhangi bir değişiklik yapmanız gerekmese de aşağıdaki şartları karşılamanız gerekir:
bundletooluygulamasının en yeni sürümünü indirip yükleyin. Uygulama paketinizden yeni bir yüklenebilir APK grubu oluşturmak içinbundletoolgerekir.
APK grubu oluşturma
Henüz yapmadıysanız uygulamanızın bölünmüş APK'larını aşağıdaki şekilde oluşturun:
- Aşağıdaki yöntemlerden birini kullanarak uygulamanız için bir uygulama paketi oluşturun:
- Android App Bundle oluşturmak ve imzalamak için Android Studio'yu ve Gradle için Android eklentisini kullanın.
- Uygulama paketinizi komut satırından oluşturun.
Aşağıdaki komutla tüm cihaz yapılandırmaları için bir APK grubu oluşturmak üzere
bundletoolaracını kullanın:bundletool build-apks --local-testing --bundle my_app.aab --output my_app.apks
--local-testing işareti, APK'larınızın manifest dosyalarına meta veriler ekler. Bu meta veriler, Play Feature Delivery Kitaplığı'nın, özellik modüllerinin yüklenmesini test etmek için Play Store'a bağlanmadan yerel bölünmüş APK'ları kullanmasını sağlar.
Uygulamanızı cihaza dağıtma
--local-testing işaretini kullanarak bir APK grubu oluşturduktan sonra, uygulamanızın temel sürümünü yüklemek ve ek APK'ları cihazınızın yerel depolama alanına aktarmak için bundletool komutunu kullanın. Aşağıdaki komutla her iki işlemi de gerçekleştirebilirsiniz:
bundletool install-apks --apks my_app.apks
Artık uygulamanızı başlattığınızda ve bir özellik modülünü indirip yüklemek için kullanıcı işlemleri akışını tamamladığınızda Play Feature Delivery Kitaplığı, bundletool tarafından cihazın yerel depolama alanına aktarılan APK'ları kullanır.
Ağ hatası simülasyonu yapma
Play Feature Delivery Kitaplığı, Play Store'dan modül yüklemelerini simüle etmek için modülü istemek üzere SplitInstallManager yerine FakeSplitInstallManager adlı alternatifi kullanır. Bir APK grubu oluşturmak ve bunları test cihazınıza dağıtmak için --local-testing işaretini bundletool ile kullandığınızda, Play Feature Delivery kitaplığına uygulamanızın API çağrılarını SplitInstallManager yerine FakeSplitInstallManager'yi çağıracak şekilde otomatik olarak değiştirmesini söyleyen meta veriler eklenir.
FakeSplitInstallManager, uygulamanız bir sonraki modül yükleme isteğinde bulunduğunda ağ hatası simüle etmek için etkinleştirebileceğiniz bir boole işareti içerir. Testlerinizde FakeSplitInstallManager öğesine erişmek için aşağıda gösterildiği gibi FakeSplitInstallManagerFactory kullanarak bir örneğini alabilirsiniz:
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);