Özellik modülleri, belirli özellik ve kaynakları uygulamanızın temel modülünden ayırmanıza ve uygulama paketinize dahil etmenize olanak tanır. Örneğin, kullanıcılar uygulamanızın temel APK'sını yükledikten sonra Play Feature Delivery aracılığıyla bu bileşenleri daha sonra istek üzerine indirip yükleyebilirler.
Örneğin, resimli mesaj 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 kısa mesaj uygulamasını düşünün. Resimli mesajlaşmayı indirilebilir bir özellik modülü olarak eklemek mantıklı olabilir. Bu şekilde, ilk uygulama indirme işlemi tüm kullanıcılar için daha küçük olur ve yalnızca resimli mesajlar gönderen kullanıcıların bu ek bileşeni indirmesi gerekir.
Bu tür bir modülerleştirmenin daha fazla çalışma gerektirdiğini ve uygulamanızın mevcut kodunun yeniden düzenlenmesi gerektiğini unutmayın. Bu nedenle, istek üzerine kullanıcılara sunulması sayesinde uygulamanızın hangi özelliklerinden en çok fayda sağlayacağını dikkatlice düşünün. İsteğe bağlı özelliklerle ilgili en uygun kullanım alanlarını ve kuralları daha iyi anlamak için isteğe bağlı yayınlama için kullanıcı deneyimiyle ilgili en iyi uygulamaları okuyun.
İsteğe bağlı yayınlama gibi gelişmiş dağıtım seçeneklerini etkinleştirmeden uygulama özelliklerini zaman içinde kademeli olarak modüler hale getirmek istiyorsanız bunun yerine yükleme sırasında yayınlamayı yapılandırın.
Bu sayfa, uygulama projenize bir özellik modülü eklemenize ve isteğe bağlı dağıtım için yapılandırmanıza yardımcı olur. Başlamadan önce Android Studio 3.5 veya üzeri, Android Gradle Eklentisi 3.5.0 veya üzerini kullandığınızdan emin olun.
İsteğe bağlı yayın için yeni bir modül yapılandırın
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 yapısı gereği temel uygulama modülüne bağımlılığı olduğundan, bunları yalnızca mevcut uygulama projelerine ekleyebilirsiniz.
Android Studio'yu kullanarak uygulama projenize bir özellik modülü eklemek için aşağıdaki adımları izleyin:
- Henüz yapmadıysanız uygulama projenizi IDE'de açın.
- Menü çubuğundan 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çin ve İleri'yi tıklayın.
- Yeni modülünüzü yapılandırın bölümünde aşağıdaki adımları uygulayın:
- Açılır menüden uygulama projeniz için Temel uygulama modülünü seçin.
- Bir Modül adı belirtin. IDE, modülü Gradle ayarları dosyanızda bir Gradle alt projesi olarak tanımlamak için bu adı kullanır. Uygulama paketinizi oluşturduğunuzda Gradle, özellik modülünün manifestine
<manifest split>
özelliğini eklemek için alt proje adının son öğesini kullanır. - Modülün paket adını belirtin. Varsayılan olarak Android Studio, önceki adımda belirttiğiniz temel modülün kök paket adını ve modül adını birleştiren bir paket adı önerir.
- Modülün desteklemesini istediğiniz Minimum API düzeyi'ni seçin. Bu değer, temel modülün değeriyle eşleşmelidir.
- Sonraki'ni tıklayın.
Modül İndirme Seçenekleri bölümünde aşağıdakileri tamamlayın:
En fazla 50 karakter kullanarak Modül başlığı'nı belirtin. Platform, örneğin kullanıcının modülü indirmek isteyip istemediğini onaylarken modülü kullanıcılara tanıtmak için bu başlığı kullanır. Bu nedenle, uygulamanızın temel modülünde modül başlığı, çevirebileceğiniz bir dize kaynağı olarak bulunmalıdır. Modülü Android Studio kullanarak oluştururken IDE, dize kaynağını sizin için temel modüle ekler ve aşağıdaki girişi özellik modülünün manifest dosyasına ekler:
<dist:module ... dist:title="@string/feature_title"> </dist:module>
Yükleme zamanını dahil etme bölümündeki açılır menüden Yükleme sırasında modülü dahil etme seçeneğini belirleyin. Android Studio, seçiminizi yansıtmak için modülün manifest dosyasına aşağıdaki kodu 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 ve çoklu APK'lara dahil edilen cihazlarda kullanılabilmesini istiyorsanız Fusing (Birleştirme) seçeneğinin yanındaki kutuyu işaretleyin. Yani bu modül için isteğe bağlı davranışı etkinleştirebilir ve bölünmüş APK'ların indirilmesini ve yüklenmesini desteklemeyen cihazlardan çıkarmak için birleştirmeyi devre dışı bırakabilirsiniz. Android Studio, seçiminizi yansıtmak için modülün manifest dosyasına aşağıdaki kodu ekler:
<dist:module ...> <dist:fusing dist:include="true | false" /> </dist:module>
Son'u tıklayın.
Android Studio, modülünüzü oluşturmayı bitirdikten sonra, Proje bölmesinden modül içeriğini kendiniz inceleyin (menü çubuğundan Görünüm > Araç Pencereleri > Proje'yi seçin). Varsayılan kod, kaynaklar ve kuruluş standart uygulama modülününkine benzer olmalıdır.
Ardından, Play Özellik Dağıtım kitaplığını kullanarak isteğe bağlı yükleme işlevini uygulamanız gerekir.
Projenize Play Özellik Yayınlama Kitaplığı'nı dahil etme
İşleme başlamadan önce projenize Play Özellik Yayınlama Kitaplığı'nı eklemeniz gerekir.
İsteğe bağlı modül isteyin
Uygulamanızın bir özellik modülü kullanması gerektiğinde, uygulama ön plandayken SplitInstallManager
sınıfı aracılığıyla yeni bir özellik modülü isteyebilir. Uygulamanızın bir istekte bulunurken, hedef modülün manifest dosyasındaki split
öğesi tarafından tanımlanan modülün adını belirtmesi gerekir. Android Studio'yu kullanarak bir özellik modülü oluşturduğunuzda derleme sistemi, bu özelliği derleme sırasında 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 resim mesajları yakalayıp göndermek için isteğe bağlı modüle sahip bir uygulama düşünün. Bu isteğe bağlı modülün manifest dosyasında split="pictureMessages"
belirtilir. Aşağıdaki örnekte, pictureMessages
modülü (bazı tanıtım filtreleri için ek bir modülle birlikte) istemek için 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 Özellik Yayınlama Kitaplığı, "etkinle ve unut" stratejisinden yararlanır. Yani modülü indirme isteğini platforma gönderir ancak kurulumun başarılı olup olmadığını izlemez. Yüklemeden sonra kullanıcı yolculuğunu ileriye taşımak veya hataları sorunsuz bir şekilde ele almak için istek durumunu izlediğinizden emin olun.
Not: Cihazda zaten yüklü olan bir özellik modülü için istekte bulunabilirsiniz. API, modülün zaten yüklü olduğunu tespit ederse isteği anında tamamlanmış olarak kabul eder. Ayrıca, bir modül yüklendikten sonra Google Play o modülü otomatik olarak günceller. Yani uygulama paketinizin yeni bir sürümünü yüklediğinizde platform, uygulamanıza ait olan tüm yüklü APK'ları günceller. Daha fazla bilgi için Uygulama güncellemelerini yönetme bölümünü okuyun.
Modülün koduna ve kaynaklarına erişmek için uygulamanızın SplitCompat'ı etkinleştirmesi gerekir. Android Hazır Uygulamalar için SplitCompat'ın gerekli olmadığını unutmayın.
İsteğe bağlı modüllerin yüklenmesini ertele
Uygulamanızın isteğe bağlı bir modülü hemen indirip yüklemesi gerekmiyorsa, yüklemeyi uygulama arka plandayken gerçekleştirilecek şekilde erteleyebilirsiniz. Örneğin, uygulamanızın daha sonraki bir lansmanı için bazı tanıtım materyallerini önceden yüklemek isteyebilirsiniz.
Aşağıda gösterildiği gibi, deferredInstall()
yöntemini kullanarak daha sonra indirilecek bir modül belirtebilirsiniz. Ayrıca SplitInstallManager.startInstall()
'in aksine 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üklemelerle ilgili istekler en iyi sonucu verir ve ilerleme durumunu izleyemezsiniz. Bu nedenle, ertelenen yükleme için belirttiğiniz bir modüle erişmeye çalışmadan önce modülün yüklü olup olmadığını kontrol etmeniz gerekir. Modülün hemen kullanılabilir olması gerekiyorsa önceki bölümde gösterildiği gibi bunu istemek için SplitInstallManager.startInstall()
öğesini kullanın.
İstek durumunu izleme
Bir ilerleme çubuğunu güncellemek, kurulumdan sonra bir intent tetiklemek veya bir istek hatasını sorunsuz bir şekilde ele almak için eşzamansız SplitInstallManager.startInstall()
görevindeki durum güncellemelerini dinlemeniz gerekir.
Yükleme isteğiniz için güncelleme almaya başlamadan önce, bir işleyici kaydedin ve aşağıda gösterildiği gibi isteğ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ı işleme
Uygulama yüklemenin her zaman başarılı olmadığı gibi, özellik modüllerinin isteğe bağlı olarak yüklenmesinin de bazen başarısız olabileceğini unutmayın. Yüklemenin başarısız olmasının nedeni cihazın depolama alanının az olması, ağ bağlantısının olmaması veya kullanıcının Google Play Store'da oturum açmaması gibi sorunlar olabilir. Bu durumları kullanıcının bakış açısından nasıl düzgün bir şekilde yönetebileceğinize dair öneriler için istek üzerine yayın için kullanıcı deneyimi yönergelerimize göz atın.
Kod açısından, addOnFailureListener()
kullanarak modül indirme veya yükleme sorunlarını aşağıda gösterildiği gibi 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 | İstek, şu anda indirilen en az bir mevcut istek olduğundan reddedildi. | Yukarıdaki örnekte gösterildiği gibi indirilmekte olan isteklerin olup olmadığını kontrol edin. |
MODULE_UNAVAILABLE | Google Play, uygulamanın yüklü olan sürümü, cihaz 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. |
GEÇERSİZ_İSTEK | Google Play isteği aldı, ancak geçerli değil. | İstekte yer alan bilgilerin eksiksiz ve doğru olduğunu onaylayı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_KULLANILAMIYOR | Play Özellik Yayınlama Kitaplığı mevcut cihazda desteklenmiyor. Yani cihaz, özellikleri istek üzerine indirip yükleyemez. | Android 4.4 (API düzeyi 20) veya önceki sürümleri çalıştıran cihazlar için yükleme sırasında dist:fusing manifest özelliğini kullanarak özellik modüllerini eklemeniz gerekir. Daha fazla bilgi için özellik modülü manifesti hakkında bilgi edinin.
|
AĞ_HATASI | İstek, bir ağ hatası nedeniyle başarısız oldu. | Kullanıcıdan ağ bağlantısı oluşturmasını veya farklı bir ağa geçmesini isteyin. |
ERİŞİM_REDDEDİLDİ | Uygulama, yetersiz izinler nedeniyle isteği kaydedemiyor. | Bu durum genellikle uygulama arka plandayken yaşanır. Uygulama ön plana döndüğünde isteği deneyin. |
EXISTING_SESSION [INCOMPATIBLE_WITH_EXISTING_SESSION] | İstek, daha önce istenmiş ancak henüz yüklenmemiş bir veya daha fazla modül içeriyor. | Uygulamanızın zaten istediği modülleri içermeyen yeni bir istek oluşturun veya isteği yeniden denemeden önce istenen tüm modüllerin yüklenmesinin tamamlanmasını bekleyin.
Önceden yüklenmiş bir modül isteğinde bulunmanın hatayla çözülemeyeceğini unutmayın. |
SERVICE_DIED | İsteğin ele alınmasından sorumlu hizmet artık çalışmıyor. | İsteği yeniden göndermeyi 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ına sahip olmadığını bildirin. |
SPLITCOMPAT_DOĞRU_HATA, SPLITCOMPAT_EMULATION_ERROR, SPLITCOMPAT_COPY_ERROR | SplitCompat, özellik modülünü yükleyemedi. | Bu hatalar, uygulama yeniden başlatıldıktan sonra kendiliğinden kendiliğinden çözülür. |
PLAY_STORE_NOT_FOUND | Play Store uygulaması cihazda yüklü değil. | Kullanıcıya bu özelliği indirmek için Play Store uygulamasının gerektiğini bildirin. |
UYGULAMA_DEĞİL_SAHİP | Uygulama Google Play tarafından yüklenmediğinden özellik indirilemiyor. Bu hata yalnızca ertelenen yüklemeler için oluşabilir. | Kullanıcının uygulamayı Google Play'de edinmesini istiyorsanız gerekli kullanıcı onayını alabilecek startInstall() özelliğini kullanın. |
DAHİLİ_HATA | Play Store'da dahili bir hata oluştu. | İsteği yeniden göndermeyi deneyin. |
Bir kullanıcı istek üzerine modül indirme isteğinde bulunur ve bir 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 terk eder). Daha fazla destek için kullanıcıları Google Play Yardım Merkezi'ne yönlendiren Yardım bağlantısı da sağlamanız gerekir.
Durum güncellemelerini işleme
Bir işleyiciyi kaydettikten ve isteğinizin oturum kimliğini kaydettikten sonra, durum değişikliklerini aşağıda gösterildiği gibi yönetmek için StateUpdatedListener.onStateUpdate()
öğesini 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ğinizle ilgili 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şlemi hakkında 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ının onayı gerekiyor. Bu durum genellikle uygulama Google Play üzerinden yüklenmediğinde ortaya çıkar. | Kullanıcıdan özelliğin Google Play üzerinden indirilmesini onaylamasını isteyin. Daha fazla bilgi edinmek için kullanıcı onayı alma bölümüne gidin. |
İNDİRİLİYOR | İndirme işlemi devam ediyor. | İndirme için bir ilerleme çubuğu sağlarsanız kullanıcı arayüzünü güncellemek için SplitInstallSessionState.bytesDownloaded() ve SplitInstallSessionState.totalBytesToDownload() yöntemlerini kullanın (bu tablonun üzerindeki kod örneğine bakın). |
İNDİRİLDİ | Cihaz modülü indirdi, ancak yükleme henüz başlamadı. | İndirilen modüllere erişebilmeleri ve bu durumu görmemeleri için uygulamaların SplitCompat'ı etkinleştirmesi gerekir. 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ısadır. |
YÜKLENDİ | Modül cihaza yüklenmiştir. | Kullanıcı yolculuğuna devam etmek için modüldeki koda ve kaynağa erişin.
Modül, Android 8.0 (API düzeyi 26) veya sonraki sürümleri çalıştıran Android Hazır Uygulama içinse uygulama bileşenlerini yeni modülle güncellemek için |
SIÇTI | 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ürecinde. | Daha fazla bilgi edinmek için yükleme isteğini iptal etme konulu bölüme gidin. |
İPTAL EDİLDİ | İstek iptal edildi. |
Kullanıcı onayı alma
Bazı durumlarda Google Play, bir indirme isteğini yerine getirmeden önce kullanıcının onayını gerektirebilir. Örneğin, uygulamanız Google Play tarafından yüklenmediyse veya
mobil veri üzerinden büyük bir indirme işlemine çalışıyorsanız. Bu gibi durumlarda, REQUIRES_USER_CONFIRMATION
isteğinin durumu ve uygulamanızın istekte bulunan modülleri indirip yükleyebilmesi için önce uygulamanızın kullanıcı onayı alması gerekir. Onay almak için uygulamanızın kullanıcıdan aşağıdaki şekilde istemesi gerekir:
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ıyı kaydedebilirsiniz. Etkinlik Sonucu API'leri konusuna bakın.
İsteğin durumu, kullanıcı yanıtına bağlı olarak güncellenir:
- Kullanıcı onayı kabul ederse isteğin durumu
PENDING
olarak değişir ve indirme işlemi devam eder. - Kullanıcı onayı reddederse isteğin durumu
CANCELED
olarak değişir. - Kullanıcı, iletişim kutusu kaldırılmadan önce bir seçim yapmazsa istek durumu
REQUIRES_USER_CONFIRMATION
olarak kalır. Uygulamanız, kullanıcıdan tekrar isteği tamamlamasını isteyebilir.
Kullanıcının yanıtıyla birlikte bir geri arama almak için aşağıda gösterildiği gibiActivityResultCallback'i 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);
Modüllere erişin
İndirilmiş bir modüldeki koda ve kaynaklara, indirildikten sonra erişmek için uygulamanızın hem uygulamanız hem de uygulamanızın indirdiği özellik modüllerindeki her etkinlik için SplitCompat Library'yi etkinleştirmesi gerekir.
Bununla birlikte, modülü indirdikten sonra platformun bir süre boyunca (bazı durumlarda günler) modülün içeriğine erişimle ilgili aşağıdaki kısıtlamalarla karşılaştığını 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 bu kaynakları dahil etmeyi düşünebilirsiniz.
SplitCompat'ı etkinleştirin
Uygulamanızın indirilen bir modüldeki koda ve kaynaklara erişebilmesi için SplitCompat'ı aşağıdaki bölümlerde açıklanan yöntemlerden yalnızca birini kullanarak etkinleştirmeniz gerekir.
Uygulamanız için SplitCompat'ı etkinleştirdikten sonra, uygulamanızın erişebilmesini istediğiniz özellik modüllerinde her etkinlik için SplitCompat'ı etkinleştirmeniz gerekir.
Manifest'te SplitCompatApplication bildirme
SplitCompat'ı etkinleştirmenin en basit yolu, aşağıda gösterildiği gibi, uygulamanızın manifest dosyasında SplitCompatApplication
alt sınıfını Application
alt sınıfı olarak tanımlamaktır:
<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'ı çağır
SplitCompat'ı çalışma zamanında belirli etkinliklerde veya hizmetlerde de etkinleştirebilirsiniz.
Özellik modüllerinde yer alan etkinlikleri başlatmak için SplitCompat'ın bu şekilde etkinleştirilmesi gerekir. Bunu yapmak için aşağıda gösterildiği gibi attachBaseContext
kodunu geçersiz kılın.
Özel bir Application (Uygulama) sınıfınız varsa SplitCompat'ı uygulamanızda etkinleştirmek için aşağıda gösterildiği gibi bu sınıfı genişletin: SplitCompatApplication
:
Kotlin
class MyApplication : SplitCompatApplication() { ... }
Java
public class MyApplication extends SplitCompatApplication { ... }
SplitCompatApplication
, SplitCompat.install(Context applicationContext)
öğesini içerecek şekilde ContextWrapper.attachBaseContext()
öğesini geçersiz kılar. Application
sınıfınızın SplitCompatApplication
kapsamını genişletmesini istemiyorsanız attachBaseContext()
yöntemini manuel olarak aşağıdaki ş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); }
Seç-izle modülünüz hem hazır uygulamalar hem de yüklü uygulamalarla uyumluysa SplitCompat'ı koşullu olarak aşağıdaki şekilde ç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'ı etkinleştir
Temel uygulamanız için SplitCompat'ı etkinleştirdikten sonra, uygulamanızın bir özellik modülünde indirdiği her etkinlik için SplitCompat'ı etkinleştirmeniz gerekir. Bunu yapmak için SplitCompat.installActivity()
yöntemini aşağıdaki şekilde 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
Bir özellik modülünde tanımlanan etkinliği başlatma
SplitCompat'ı etkinleştirdikten sonra, startActivity()
kodunu kullanarak özellik modüllerinde tanımlanan etkinlikleri 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
öğesinin ilk parametresi, uygulamanın paket adıdır. İkinci 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'ı etkinleştirmeniz gerekir.
Bir özellik modülünde tanımlanan hizmeti başlatma
SplitCompat'ı etkinleştirdikten sonra, özellik modüllerinde tanımlanan hizmetleri startService()
kullanarak 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(...));
Bir özellik modülünde tanımlanan bileşeni dışa aktarma
Dışa aktarılan Android bileşenlerini isteğe bağlı modüllerin içine dahil etmemelisiniz.
Derleme sistemi, tüm modüllerin manifest girişlerini temel modülde birleştirir. İsteğe bağlı bir modül dışa aktarılmış bir bileşen içeriyorsa modül yüklenmeden önce bile erişilebilir hale gelirdi ve başka bir uygulamadan çağrıldığında eksik kod nedeniyle kilitlenmeye neden olabilir.
Bu, dahili bileşenler için bir sorun teşkil etmez. Bunlara yalnızca uygulama tarafından erişilir. Böylece 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 bir proxy kalıbı uygulamayı düşünün.
Bunu, proxy'den dışa aktarılan bir bileşeni tabana ekleyerek yapabilirsiniz. Erişildiğinde, proxy bileşeni içeriği barındıran modülün olup olmadığını kontrol edebilir. Modül mevcutsa proxy bileşeni, dahili bileşeni bir Intent
aracılığıyla başlatabilir ve bunu çağıran uygulamadan gelen amacı iletir. Modül yoksa bileşen, modülü indirebilir veya arayan uygulamasına uygun bir hata mesajı döndürebilir.
Yüklü modüllerdeki koda ve kaynaklara erişin
Temel uygulama içeriğiniz ve özellik modülünüzdeki etkinlikler için SplitCompat'ı etkinleştirirseniz isteğe bağlı modül yüklendikten sonra, özellik modülünün kodunu ve kaynaklarını temel APK'nın parçasıymış gibi kullanabilirsiniz.
Farklı bir modülden koda erişin
Bir modülden temel koda erişme
Temel modülünüzün içindeki kod, doğrudan diğer modüller tarafından kullanılabilir. Özel bir şey yapmanıza gerek yoktur. İhtiyacınız olan sınıfları içe aktarıp kullanabilirsiniz.
Başka bir modülden modül koduna erişin
Bir modülün içindeki nesneye veya sınıfa başka bir modülden doğrudan statik olarak erişilemez ama bu nesneye veya sınıfa yansıma özelliği kullanılarak dolaylı yoldan erişilebilir.
Performans üzerine düşünmeden kaynaklanan maliyetler nedeniyle bunun ne sıklıkla gerçekleştiği konusunda dikkatli olmalısınız. Karmaşık kullanım alanlarında, uygulama ömrü başına tek bir yansıma çağrısı olmasını garanti etmek için Dagger 2 gibi bağımlılık yerleştirme çerçeveleri kullanın.
Örneklemeden sonra nesneyle etkileşimleri basitleştirmek için temel modülde bir arayüz tanımlamanız ve özellik modülünde uygulanmasını öneririz. Ö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şin
Modül yüklendikten sonra, modül içindeki kaynaklara ve öğelere standart şekilde erişebilirsiniz. Ancak bu durumda dikkat etmeniz gereken iki nokta vardır:
- Bir kaynağa farklı bir modülden erişiyorsanız modülün kaynak tanımlayıcısına erişimi olmaz. Ancak kaynağa yine de adla erişilebilir. Kaynağa referans vermek için kullanılacak paketin, kaynağın tanımlandığı modülün paketi olduğunu unutmayın.
- Uygulamanızın yüklenen farklı bir modülünden yeni yüklenmiş bir modüldeki öğelere veya kaynaklara 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, bu bileşeni yeniden oluşturabilir (örneğin, Activity.recreate() işlevini çağırabilir) veya özellik modülü yüklendikten sonra SplitCompat'ı bu bileşene yeniden yükleyebilirsiniz.
İsteğe bağlı yayınlama kullanarak bir uygulamada yerel kod yükleme
Özellik modüllerinin isteğe bağlı yayını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ı bölümünde bulabilirsiniz.
İsteğe bağlı bir modülden yerel kod yükleme
Split yüklendikten sonra, yerel kodunu ReLinker üzerinden 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 bu diğer kitaplığı manuel olarak yüklemeniz gerekir.
ReLinker kullanıyorsanız eşdeğer işlem:
Relinker.recursively().loadLibrary()
.
İsteğe bağlı bir modülde tanımlanan kitaplığı yüklemek için yerel kodda dlopen()
kullanıyorsanız göreli kitaplık yollarıyla çalışmaz.
En iyi çözüm, kitaplığın mutlak yolunu ClassLoader.findLibrary()
aracılığıyla Java kodundan almak ve ardından dlopen()
çağrınızda kullanmaktır.
Bunu yerel kodu girmeden önce yapın veya yerel kodunuzdan Java'ya bir JNI çağrısı yapın.
Yüklü Android Hazır Uygulamalar'a erişme
Bir Android Hazır Uygulama modülü INSTALLED
olarak bildirildikten sonra, yenilenmiş bir uygulama Bağlamı kullanarak modülün koduna ve kaynaklarına erişebilirsiniz. Uygulamanızın bir modülü yüklemeden önce oluşturduğu bağlamda (örneğin, değişkende önceden depolanan bir öğe), yeni modülün içeriği yer almaz. Ancak yeni bir bağlam sunar. Bu, örneğin createPackageContext
kullanılarak elde edilebilir.
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ümlerdeki Android Hazır Uygulamalar
Android 8.0 (API düzeyi 26) ve sonraki sürümlerde Android Hazır Uygulama için istek üzerine modül isteğinde
bulunurken, yükleme isteği INSTALLED
olarak bildirildikten sonra, SplitInstallHelper.updateAppInfo(Context context)
çağrısıyla uygulamayı yeni modülün bağlamıyla güncellemeniz gerekir.
Aksi takdirde, uygulama henüz modülün kodunu ve kaynaklarını bilmez. Uygulamanın meta verilerini güncelledikten sonra, bir sonraki ana iş parçacığı etkinliği sırasında, aşağıda gösterildiği gibi yeni bir Handler
çağırarak modülün içeriğini 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
C/C++ kitaplıklarını, cihazın Hazır Uygulama'da daha önce indirmiş olduğu bir modülden yüklemek isterseniz SplitInstallHelper.loadLibrary(Context context, String libName)
aracını aşağıda gösterildiği gibi 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. Bunun nedeni, Android API düzeyi 28 ve önceki sürümlerde WebView ile SplitCompat arasındaki uyumsuzluktur.
- Android
ApplicationInfo
nesnelerini, bunların içeriklerini veya uygulamanızın içinde bunları içeren nesneleri önbelleğe alamazsınız. Bu nesneleri gerektiğinde her zaman uygulama bağlamından getirmeniz gerekir. Bu tür nesnelerin önbelleğe alınması, bir özellik modülü yüklenirken uygulamanın kilitlenmesine neden olabilir.
Yüklü modülleri yönet
Cihazda şu anda hangi özellik modüllerinin yüklü olduğunu kontrol etmek için SplitInstallManager.getInstalledModules()
yöntemini çağırabilirsiniz. Bu işlem, aşağıda gösterildiği gibi yüklü modüllerin adlarından bir Set<String>
döndürür.
Kotlin
val installedModules: Set<String> = splitInstallManager.installedModules
Java
Set<String> installedModules = splitInstallManager.getInstalledModules();
Modülleri kaldır
Aşağıda gösterildiği gibi SplitInstallManager.deferredUninstall(List<String> moduleNames)
komutunu çağırarak cihazdan modüllerin kaldırılması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()
kodunu çağırıp sonucu inceleyerek cihazın bir modülü sildiğini onaylayabilirsiniz.
Ek dil kaynaklarını indirin
Uygulama paketleri sayesinde cihazlar yalnızca uygulamanızı çalıştırmak için gereken kodu ve kaynakları indirir. Böylece, dil kaynakları için kullanıcının cihazı yalnızca uygulamanızın, cihaz ayarlarında seçili olan bir veya daha fazla dille eşleşen dil kaynaklarını indirir.
Uygulamanızın ek dil kaynaklarına erişmesini istiyorsanız (örneğin, uygulama içi bir dil seçici kullanmak için) Play Özellik Dağıtım Kitaplığı'nı kullanarak bu kaynakları isteğe bağlı olarak indirebilirsiniz. Bu işlem, aşağıda gösterildiği gibi, bir ö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, bir özellik modülü isteği gibi işlenir. Yani normalde yaptığınız gibi istek durumunu izleyebilirsiniz.
Uygulamanız ek dil kaynaklarını hemen gerektirmiyorsa yükleme işlemini, aşağıda gösterildiği gibi uygulama arka plandayken erteleyebilirsiniz.
Kotlin
splitInstallManager.deferredLanguageInstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)))
Java
splitInstallManager.deferredLanguageInstall( Locale.forLanguageTag(sharedPrefs.getString(LANGUAGE_SELECTION)));
İndirilen dil kaynaklarına erişme
İndirilen dil kaynaklarına erişim elde etmek için uygulamanızın, 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
üzerinden 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
olduktan 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ırın
Özellik modüllerine benzer şekilde, ek kaynakları istediğiniz zaman kaldırabilirsiniz. Kaldırma isteği göndermeden önce, aşağıdaki adımları uygulayarak ilk olarak hangi dillerin yüklü olduğunu belirlemeniz yerinde olur.
Kotlin
val installedLanguages: Set<String> = splitInstallManager.installedLanguages
Java
Set<String> installedLanguages = splitInstallManager.getInstalledLanguages();
Daha sonra, 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 edin
Play Özellik Yayınlama Kitaplığı, Play Store'a bağlanmadan uygulamanızın aşağıdakileri yapma becerisini yerel olarak test etmenize olanak tanır:
- Modül yüklemelerini isteyin ve izleyin.
- Yükleme hatalarını ele alma.
- Modüllere erişmek için
SplitCompat
kullanın.
Bu sayfada, Play Feature Delivery özelliğinin bu APK'ları kullanarak Play Store'dan modül isteme, indirme ve yükleme simülasyonu yapmak için otomatik olarak kullanması için uygulamanızın bölünmüş APK'larını test cihazınıza nasıl dağıtacağınız açıklanmaktadır.
Uygulamanızın mantığında herhangi bir değişiklik yapmanız gerekmese de aşağıdaki gereksinimleri karşılamanız gerekir:
bundletool
uygulamasının en son sürümünü indirip yükleyin. Uygulamanızın paketinden yeni bir yüklenebilir APK grubu oluşturmak içinbundletool
eklentisinin olması gerekir.
APK grubu oluşturma
Henüz yapmadıysanız uygulamanızın bölünmüş APK'larını aşağıdaki gibi 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ında bir APK grubu oluşturmak için
bundletool
öğesini 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ında yer alan meta veriler içerir. Bu veriler, Play Store'a bağlanmadan özellik modüllerinin yüklenmesini test etmek için Play Özellik Yayınlama Kitaplığı'nın yerel bölünmüş APK'ları kullanmasını sağlar.
Uygulamanızı cihaza dağıtma
--local-testing
işaretini kullanarak bir APK seti 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
uygulamasını kullanın. Aşağıdaki komutu kullanarak her iki işlemi de gerçekleştirebilirsiniz:
bundletool install-apks --apks my_app.apks
Artık uygulamanızı başlatıp bir özellik modülü indirip yüklemek için kullanıcı akışını tamamladığınızda, Play Özellik Yayınlama Kitaplığı bundletool
tarafından cihazın yerel depolama alanına aktarılan APK'ları kullanır.
Ağ hatası simüle edilir
Play Store'dan modül yüklemelerini simüle etmek amacıyla Play Özellik Dağıtım Kitaplığı, modül isteğinde bulunmak için SplitInstallManager
yerine FakeSplitInstallManager
adlı bir alternatif kullanır. Bir APK grubu oluşturmak ve test cihazınıza dağıtmak için bundletool
kodunu --local-testing
işaretiyle kullandığınızda, Play Özellik Yayınlama Kitaplığı'na uygulamanızın API çağrılarını SplitInstallManager
yerine FakeSplitInstallManager
çağırmak için otomatik olarak değiştirme talimatı veren meta veriler de içerir.
FakeSplitInstallManager
, uygulamanız bir sonraki modül yükleme isteğinde bulunduğunda ağ hatasını simüle etmek için etkinleştirebileceğiniz bir boole işareti içerir. Testlerinizde FakeSplitInstallManager
aracına erişmek için aşağıda gösterildiği gibi FakeSplitInstallManagerFactory
kodunu kullanarak bunun 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);