İsteğe bağlı yayınlamayı yapılandırın

Özellik modülleri, belirli özellik ve kaynakları uygulamanızın temel modülünden ayırıp uygulama paketinize dahil etmenize olanak tanır. Örneğin, kullanıcılar Play Feature Delivery yoluyla, uygulamanızın temel APK'sını yükledikten sonra 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ı ele alalım. 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 mesaj gönderen kullanıcıların bu ek bileşeni indirmesi gerekir.

Bu tür bir modülerleştirmenin daha fazla çaba gerektirdiğini ve uygulamanızın mevcut kodunu yeniden düzenlemenizin gerekeceğini unutmayın. Bu nedenle, uygulamanızın hangi özelliklerinin kullanıcılara isteğe bağlı olarak sunulacağına karar verirken dikkatlice düşünün. İsteğe bağlı özelliklerle ilgili ideal kullanım alanlarını ve yönergeleri 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ş yayınlama seçeneklerini etkinleştirmeden uygulama özelliklerini zaman içinde kademeli olarak modüler hale getirmek istiyorsanız bunun yerine yükleme zamanında yayınlamayı yapılandırın.

Bu sayfa, uygulama projenize bir özellik modülü eklemenize ve isteğe bağlı yayınlama için yapılandırmanıza yardımcı olur. Başlamadan önce Android Studio 3.5 veya sonraki bir sürüm ile 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ülleri doğal olarak temel uygulama modülüne bağımlı 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ı uygulayın:

  1. Henüz yapmadıysanız uygulama projenizi IDE'de açın.
  2. Menü çubuğundan Dosya > Yeni > Yeni Modül'ü seçin.
  3. Yeni Modül Oluştur iletişim kutusunda Dinamik Özellik Modülü'nü seçin ve İleri'yi tıklayın.
  4. Yeni modülünüzü yapılandırın bölümünde aşağıdaki adımları uygulayın:
    1. Açılır menüden uygulama projeniz için Base uygulama modülünü seçin.
    2. 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ştururken Gradle, özellik modülünün manifest dosyasına <manifest split> özelliğini eklemek için alt proje adının son öğesini kullanır.
    3. Modülün paket adını belirtin. Varsayılan olarak Android Studio, temel modülün kök paket adı ile önceki adımda belirttiğiniz modül adını birleştiren bir paket adı önerir.
    4. Modülün desteklemesini istediğiniz Minimum API düzeyini seçin. Bu değer, temel modülün değeriyle eşleşmelidir.
  5. İleri'yi tıklayın.
  6. Modül İndirme Seçenekleri bölümünde aşağıdakileri tamamlayın:

    1. En fazla 50 karakter kullanarak Modül başlığı'nı belirtin. Platform, örneğin kullanıcının modülü indirmek isteyip istemediğini onaylamak için modülü kullanıcılara tanımlamak için bu başlığı kullanır. Bu nedenle, uygulamanızın temel modülü, modül başlığını bir dize kaynağı olarak içermelidir. Bu kaynağı çevirebilirsiniz. Android Studio kullanarak modülü 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>
      
    2. Yükleme süresine 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 aşağıdakileri modülün manifest dosyasına ekler:

      <dist:module ... >
        <dist:delivery>
            <dist:on-demand/>
        </dist:delivery>
      </dist:module>
      
    3. 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 Fusing (Birleştirme) seçeneğinin yanındaki kutuyu işaretleyin. Bu, bu modül için isteğe bağlı davranışı etkinleştirebileceğiniz ve bölünmüş APK'ların indirilmesini ve yüklenmesini desteklemeyen cihazlarda çakışmayı hariç tutmak için birleştirmeyi devre dışı bırakabileceğiniz anlamına gelir. Android Studio, seçiminizi yansıtmak için aşağıdakileri modülün manifest dosyasına ekler:

      <dist:module ...>
          <dist:fusing dist:include="true | false" />
      </dist:module>
      
  7. Son'u tıklayın.

Android Studio, modülünüzü oluşturmayı bitirdikten sonra Proje bölmesinden modülün 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ü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 dahil etme

Başlamadan önce projenize Play Özellik Yayınlama Kitaplığı'nı eklemeniz gerekir.

İsteğe bağlı modül isteme

Uygulamanızın bir özellik modülü kullanması gerektiğinde, uygulama ön plandayken SplitInstallManager sınıfı üzerinden bir özellik modülü isteyebilir. İstekte bulunurken uygulamanızın, modülün adını hedef modülün manifest dosyasında split öğesi tarafından tanımlandığı şekilde belirtmesi gerekir. Android Studio'yu kullanarak bir özellik modülü oluşturduğunuzda, derleme sistemi, derleme sırasında bu özelliği modülün manifestine 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ülü olan bir uygulama kullandığınızı ve bu isteğe bağlı modülün manifest dosyasında split="pictureMessages" ifadesini içerdiğini varsayalım. Aşağıdaki örnekte pictureMessages modülünü istemek için SplitInstallManager kullanılmaktadır (bazı tanıtım filtreleri için ek bir modülle birlikte):

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ı modül istediğinde Play Özellik Yayınlama Kitaplığı "tetikle ve unut" stratejisi kullanır. Yani, modülü indirme isteğini platforma gönderir ancak yüklemenin başarılı olup olmadığını izlemez. Yükleme sonrasında kullanıcı yolculuğunu ilerletmek veya hataları sorunsuz şekilde ele almak için istek durumunu izlediğinizden emin olun.

Not: Cihazda yüklü olan bir özellik modülü isteyebilirsiniz. API, modülün zaten yüklü olduğunu tespit ederse isteği anında tamamlanmış olarak kabul eder. Ayrıca Google Play, yüklenen modülleri otomatik olarak günceller. Yani, uygulama paketinizin yeni bir sürümünü yüklediğinizde platform, uygulamanıza ait yüklü tüm APK'ları günceller. Daha fazla bilgi için Uygulama güncellemelerini yönetme konusunu okuyun.

Modülün kod ve kaynaklarına erişmek için uygulamanızın SplitCompat'u etkinleştirmesi gerekir. Android Hazır Uygulamalar için SplitCompat'ın gerekli olmadığını unutmayın.

İsteğe bağlı modüllerin yüklenmesini erteleme

Uygulamanızın isteğe bağlı bir modülü hemen indirip yüklemesine ihtiyaç duymuyorsanız, yükleme işlemini uygulama arka plandayken gerçekleştirilecek şekilde erteleyebilirsiniz. Örneğin, uygulamanızın daha sonra yapılacak lansmanı için bazı tanıtım materyallerini önceden yüklemek isteyebilirsiniz.

Aşağıda gösterildiği gibi deferredInstall() yöntemini kullanarak bir modülü daha sonra indirilecek şekilde belirtebilirsiniz. Ayrıca SplitInstallManager.startInstall()'in aksine, ertelenmiş yükleme isteği başlatmak için uygulamanızın ö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 yöntemdir ve ilerleme durumunu izleyemezsiniz. Bu nedenle, ertelenmiş yükleme için belirttiğiniz bir modüle erişmeye çalışmadan önce modülün yüklenmiş olup olmadığını kontrol etmeniz gerekir. Modülün hemen kullanıma sunulması gerekiyorsa bunun yerine, önceki bölümde gösterildiği gibi SplitInstallManager.startInstall() ile istekte bulunabilirsiniz.

İstek durumunu izleme

İlerleme çubuğunu güncellemek, kurulumdan sonra intent tetiklemek veya istek hatasını sorunsuz şekilde ele almak için eşzamansız SplitInstallManager.startInstall() görevinin durum güncellemelerini dinlemeniz gerekir. Yükleme isteğiniz için güncellemeleri 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ükleme işleminin her zaman başarılı olmaması gibi, özellik modüllerinin isteğe bağlı yüklenmesinin de bazen başarısız olabileceğini unutmayın. 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çmaması gibi sorunlar yüklemenin başarısız olmasından kaynaklanabilir. Bu durumların kullanıcıların bakış açısından nasıl ele alınacağına dair öneriler için isteğe bağlı yayınlamayla ilgili kullanıcı deneyimi kurallarımıza göz atın.

Kod açısından, bir modül indirirken veya indirirken addOnFailureListener() kullanan hataları 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 Şu anda indirilmekte olan en az bir mevcut istek olduğundan istek reddedildi. Yukarıdaki örnekte gösterildiği gibi hâlâ indirilmekte olan istekler olup olmadığını kontrol edin.
MODÜL_YOK Google Play; uygulamanın, cihazın ve kullanıcının Google Play hesabının mevcut yüklü sürümüne dayalı olarak istenen modülü bulamıyor. Kullanıcının modüle erişimi yoksa durumu kendisine bildirin.
GEÇERSİZ_İST Google Play isteği aldı, ancak istek geçerli değil. İstekteki 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_KULLANILAMIYOR Play Feature Delivery 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ü manifestini okuyun.
AĞ_HATASI Bir ağ hatası nedeniyle istek başarısız oldu. Kullanıcıdan ağ bağlantısı oluşturmasını veya farklı bir ağa geçiş yapmasını isteyin.
ERİŞİM_REDDEDİLDİ Uygulama, yetersiz izinler nedeniyle isteği kaydedemiyor. Bu durum genellikle uygulama arka plandayken meydana gelir. Uygulama ön plana döndüğünde isteği denemeye çalış.
VARSAYILAN_OTURUMUN_İÇİ_UYGUN OLMAYAN Bu istek, daha önce talep edilen ancak henüz yüklenmemiş bir veya daha fazla modül içeriyor. Uygulamanızın önceden istediği modülleri içermeyen yeni bir istek oluşturun veya isteği yeniden denemeden önce şu anda istenen tüm modüllerin yüklenmesini bekleyin.

Zaten yüklenmiş olan bir modülü istemenin hata sonucu çözmeyeceğini unutmayın.

HİZMET_DIED İsteği işlemekten sorumlu olan hizmet kullanımdan kaldırıldı. İsteği yeniden deneyin.

SplitInstallStateUpdatedListener cihazınız bu hata kodunu, FAILED durumunu ve -1 oturum kimliğini içeren bir SplitInstallSessionState alır.

YETERSİZ_DEPOLAMA 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_VERIFICATION_ERROR, SPLITCOMPAT_EMULATION_ERROR, SPLITCOMPAT_COPY_ERROR SplitCompat özellik modülünü yükleyemedi. Bu hatalar, uygulama tekrar yeniden başlatıldığında otomatik olarak kendiliğinden çözülür.
PLAY_STORE_NOT_FOUND Play Store uygulaması cihazda yüklü değildir. Bu özelliği indirebilmek için Play Store uygulamasının gerektiğini kullanıcıya bildirin.
UYGULAMA_NOT_OWNED Uygulama Google Play tarafından yüklenmediğinden özellik indirilemez. 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ı almak için startInstall() kullanın.
DAHİLİ_HATA 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örüntülemeyi düşünün: 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 kaydedip isteğinizin oturum kimliğini kaydettikten sonra durum değişikliklerini uygulamak için aşağıda gösterildiği gibi 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ğiniz için olası durumlar aşağıdaki tabloda açıklanmıştır.

İstek durumu Açıklama Önerilen işlem
BEKLEMEDE İstek kabul edildi. İndirme işlemi kısa süre içinde başlayacaktır. İlerleme çubuğu gibi kullanıcı arayüzü bileşenlerini başlatın. Böylece, indirme işlemiyle ilgili kullanıcı geri bildirimi alabilirsiniz.
REQUIRES_USER_CONFIRMATION İndirme işlemi için kullanıcı onayı gerekiyor. Bu durum genellikle uygulama Google Play üzerinden yüklenmediğinde ortaya çıkar. Kullanıcıdan, Google Play'den özellik indirme işlemini onaylamasını isteyin. Daha fazla bilgi edinmek için kullanıcı onayı alma ile ilgili bölüme gidin.
İNDİRİLİYOR İndirme işlemi devam ediyor. İndirme işlemi için 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 üstündeki kod örneğine bakın).
İNDİRİLDİ Cihaz, modülü indirdi ancak yükleme henüz başlamadı. Uygulamaların indirilen modüllere erişebilmesi ve bu durumu görmemesi için SplitCompat'u 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 eyalet genellikle kısadır.
YÜKLENDİ Modül cihazda yüklüdür. 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ümlerde çalışan bir Android Hazır Uygulama içinse uygulama bileşenlerini yeni modülle güncellemek üzere splitInstallHelper kullanmanız gerekir.

SIÇTI İstek, modül cihaza yüklenmeden önce 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 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 yapmaya çalışıyorsanız bu durumla karşılaşabilirsiniz. Bu tür durumlarda, isteğin durumu REQUIRES_USER_CONFIRMATION olarak raporlanır ve cihaz, istekteki modülleri indirip yükleyebilmek için uygulamanızın kullanıcı onayı alması gerekir. Onay almak için uygulamanız kullanıcıya şu şekilde izin vermelidir:

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 etkinlik sonucu başlatıcı kaydedebilirsiniz. Etkinlik Sonucu API'leri bölümünü inceleyin.

İsteğin durumu, kullanıcının yanıtına göre güncellenir:

  • Kullanıcı onayı kabul ederse istek durumu PENDING olarak değişir ve indirme işlemi devam eder.
  • Kullanıcı onayı reddederse istek durumu CANCELED olarak değişir.
  • Kullanıcı, iletişim kutusu silinmeden önce bir seçim yapmazsa istek durumu REQUIRES_USER_CONFIRMATION olarak kalır. Uygulamanız kullanıcıdan isteği tamamlamasını tekrar isteyebilir.

Kullanıcının yanıtıyla geri arama 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

İndirildikten sonra, indirilen bir modüldeki koda ve kaynaklara 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 Kitaplığı'nı etkinleştirmesi gerekir.

Bununla birlikte, platformu indirdikten sonra bir süre (bazı durumlarda günler, bazı durumlarda) bir modülün içeriğine erişimle ilgili aşağıdaki kısıtlamaların geçerli olduğunu unutmayın:

  • Platform, modül tarafından oluşturulan yeni manifest girişlerini uygulayamaz.
  • Platform, bildirimler gibi sistem kullanıcı arayüzü bileşenleri için modül kaynaklarına erişemez. Bu tür kaynakları hemen kullanmanız gerekiyorsa bu kaynakları uygulamanızın temel modülüne eklemeyi düşünün.

SplitCompat'ı etkinleştir

Uygulamanızın indirilen bir modüldeki koda ve kaynaklara erişmesi için SplitCompat'ı aşağıdaki bölümlerde açıklanan yöntemlerden yalnızca birini kullanarak etkinleştirmeniz gerekir.

Uygulamanızda SplitCompat'u etkinleştirdikten sonra, uygulamanızın erişmesini istediğiniz özellik modüllerindeki her etkinlik için SplitCompat'u etkinleştirmeniz gerekir.

Manifest dosyasında SplitCompatApplication bildirme

SplitCompat'ı etkinleştirmenin en basit yolu, aşağıda gösterildiği gibi uygulamanızın manifest dosyasında SplitCompatApplication öğesini 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üllerinden 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'un bu şekilde etkinleştirilmesi gerekir. Bunu yapmak için attachBaseContext öğesini aşağıda gösterildiği gibi geçersiz kılın.

Özel bir Uygulama sınıfınız varsa aşağıda gösterildiği gibi uygulamanızda SplitCompat'u etkinleştirmek için SplitCompatApplication genişletmesini sağlayın:

Kotlin

class MyApplication : SplitCompatApplication() {
    ...
}

Java

public class MyApplication extends SplitCompatApplication {
    ...
}

SplitCompatApplication, SplitCompat.install(Context applicationContext) öğesini dahil etmek için ContextWrapper.attachBaseContext() politikasını geçersiz kılar. Application sınıfınızın SplitCompatApplication öğesini genişletmesini istemiyorsanız attachBaseContext() yöntemini aşağıdaki gibi manuel olarak 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 uygulamalarla hem de yüklü uygulamalarla uyumluysa SplitCompat'ı aşağıdaki gibi koşullu olarak ç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ızda SplitCompat'u etkinleştirdikten sonra, uygulamanızın bir özellik modülünde indirdiği her etkinlik için SplitCompat'u etkinleştirmeniz gerekir. Bunun için aşağıdaki SplitCompat.installActivity() yöntemini 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şim

Özellik modülünde tanımlanan bir etkinliği başlatma

SplitCompat'ı etkinleştirdikten sonra startActivity() 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 parametresi 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 bir etkinliğiniz olduğunda, etkinlikte SplitCompat'ı etkinleştirmeniz gerekir.

Özellik modülünde tanımlanan bir hizmeti başlatma

SplitCompat'ı 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 bileşeni dışa aktarma

Dışa aktarılan Android bileşenlerini isteğe bağlı modüllere eklememelisiniz.

Derleme sistemi, tüm modüller için manifest girişlerini temel modülle 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 hale gelir ve başka bir uygulamadan çağrıldığında eksik kod nedeniyle kilitlenmeye neden olabilir.

Bu, dahili bileşenler için bir sorun değildir. Bunlara yalnızca uygulama tarafından erişildiğinden 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, proxy dışa aktarılan proxy'yi temele ekleyerek yapabilirsiniz. Erişildiğinde proxy bileşeni, içeriği barındıran modülün varlığını kontrol edebilir. Modül mevcutsa proxy bileşeni, çağrıyı arayan uygulamadan niyeti yönlendiren bir Intent aracılığıyla dahili bileşeni modülden başlatabilir. Modül mevcut değilse bileşen, modülü indirebilir veya arayan uygulamasına uygun bir hata mesajı döndürebilir.

Yüklü modüllerden kod ve kaynaklara erişin

Temel uygulama bağlamınız ve özellik modülünüzdeki etkinlikler için SplitCompat'ı etkinleştirirseniz isteğe bağlı modül yüklendikten sonra özellik modülündeki kodu ve kaynakları temel APK'nın bir parçası gibi kullanabilirsiniz.

Farklı bir modülden erişim kodu

Temel koda modülden erişme

Temel modülünüzde bulunan kod doğrudan diğer modüller tarafından kullanılabilir. Özel bir şey yapmanız gerekmez. İçe aktarmanız ve ihtiyacınız olan sınıfları kullanmanız yeterlidir.

Modül koduna başka bir modülden erişin

Bir modül içindeki nesne veya sınıfa doğrudan başka bir modülden statik olarak erişilemez ancak yansıma kullanılarak dolaylı olarak erişilebilir.

Değerlendirmenin performans maliyetleri nedeniyle bunun ne sıklıkta gerçekleştiği konusunda dikkatli olmalısınız. Karmaşık kullanım alanlarında Dagger 2 gibi bağımlılık yerleştirme çerçevelerini kullanarak uygulama ömrü başına tek bir yansıma çağrısı olmasını sağlayabilirsiniz.

Örneklendirme sonrasında nesneyle olan etkileşimleri basitleştirmek için temel modülde bir arayüz ve özellik modülünde uygulaması tanımlanması ö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();

Kaynak ve öğelere farklı bir modülden erişin

Bir modül yüklendikten sonra, aşağıdaki iki uyarı doğrultusunda modül içindeki kaynaklara ve öğelere standart bir şekilde erişebilirsiniz:

  • 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 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üklenmiş bir modüldeki öğelere veya kaynaklara uygulamanızın farklı bir yüklü modülünden erişmek isterseniz 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() yöntemini çağırabilir) veya özellik modülü yüklendikten sonra SplitCompat'u ona yeniden yükleyebilirsiniz.

İsteğe bağlı yayını kullanarak bir uygulamada yerel kod yükleme

Özellik modüllerinin isteğe bağlı dağıtımını kullanırken tüm yerel kitaplıklarınızı yüklemek için ReLinker kullanmanızı öneririz. ReLinker, ö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ı'nda bulabilirsiniz.

İsteğe bağlı bir modülden yerel kod yükleme

Split yüklendikten sonra ReLinker aracılığıyla yerel kodunu 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() şeklindedir.

İsteğe bağlı bir modülde tanımlanan kitaplığı yüklemek için yerel kodda dlopen() kullanıyorsanız bu kitaplık 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ı kullanın.

Yüklü Android Hazır Uygulamalarına erişme

Bir Android Hazır Uygulama modülü INSTALLED olarak raporlandıktan sonra, yenilenmiş bir uygulama Bağlamı'nı kullanarak koda 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 depolanan bir bağlam) yeni modülün içeriğini içermez. Ancak yeni bir bağlam edinir. Örneğin, createPackageContext kullanılarak bu 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ümlerde Android Hazır Uygulamalar

Android 8.0 (API düzeyi 26) ve sonraki sürümlerde bir Android Hazır Uygulama için isteğe bağlı modül isteğinde bulunurken, yükleme isteği INSTALLED olarak raporlandıktan sonra, SplitInstallHelper.updateAppInfo(Context context) çağrısı yaparak uygulamayı yeni modülün bağlamıyla güncellemeniz gerekir. Aksi takdirde, uygulama henüz modülün kodundan ve kaynaklarından haberdar değildir. 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ç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

Cihazın bir Hazır Uygulamada önceden indirdiği bir modülden C/C++ kitaplıklarını yüklemek istiyorsanız aşağıda gösterildiği gibi SplitInstallHelper.loadLibrary(Context context, String libName) işlevini 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 etkinliklerde Android WebView kullanılamaz. Bu durum, Android API düzey 28 ve önceki sürümlerde WebView ile SplitCompat arasındaki bir uyumsuzluktan kaynaklanır.
  • Android ApplicationInfo nesnelerini, içeriklerini veya bunları uygulamanızın içinde içeren nesneleri önbelleğe alamazsınız. Bu nesneleri her zaman bir uygulama bağlamından gerektiğinde getirmelisiniz. Bu tür nesneleri önbelleğe almak, özellik modülü yüklenirken uygulamanın kilitlenmesine neden olabilir.

Yüklü modülleri yönetin

Cihazda şu anda hangi özellik modüllerinin yüklü olduğunu kontrol etmek için SplitInstallManager.getInstalledModules() kodunu arayabilirsiniz. Bu işlem, aşağıda gösterildiği gibi yüklü modüllerin adlarından Set<String> tanesini döndürür.

Kotlin

val installedModules: Set<String> = splitInstallManager.installedModules

Java

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

Modülleri kaldırın

Aşağıda gösterildiği gibi, SplitInstallManager.deferredUninstall(List<String> moduleNames) komutunu ç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 onaylayabilirsiniz.

Ek dil kaynaklarını indirin

Uygulama paketleriyle cihazlar yalnızca uygulamanızı çalıştırmak için gereken kod ve kaynakları indirir. Böylece dil kaynakları için kullanıcının cihazı yalnızca uygulamanızın 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şebilmesini istiyorsanız (örneğin, uygulama içi dil seçici uygulamak için) Play Feature Delivery kitaplığını kullanarak bunları istediğiniz zaman indirebilirsiniz. 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, bir özellik modülüne yönelik istek gibi işlenir. Yani her zamanki gibi istek durumunu izleyebilirsiniz.

Uygulamanız ek dil kaynaklarını hemen gerektirmiyorsa aşağıda gösterildiği gibi yükleme işlemini uygulama arka plandayken gerçekleştirilecek şekilde 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şmek için uygulamanızın, aşağıda gösterildiği gibi SplitCompat.installActivity() yöntemini, bu kaynaklara erişim gerektiren her etkinliğin attachBaseContext() yöntemi içinde ç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ırın

Özellik modüllerine benzer şekilde, istediğiniz zaman ek kaynakları kaldırabilirsiniz. Kaldırma isteğinde bulunmadan önce aşağıdaki gibi şu anda hangi dillerin yüklü olduğunu belirlemek isteyebilirsiniz.

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 kaldırılacak dillere karar verebilirsiniz.

Kotlin

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

Java

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

Yerel test modülü yüklemeleri

Play Özellik Yayınlama Kitaplığı, uygulamanızın aşağıdakileri yapma becerisini Play Store'a bağlanmadan yerel olarak test etmenize olanak tanır:

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:

APK seti oluşturma

Henüz yapmadıysanız uygulamanızın bölünmüş APK'larını aşağıdaki gibi oluşturun:

  1. Aşağıdaki yöntemlerden birini kullanarak uygulamanız için bir uygulama paketi oluşturun:
  2. Tüm cihaz yapılandırmaları için bundletool kullanarak aşağıdaki komutu kullanarak bir dizi APK oluşturun:

    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 meta veriler içerir. Bu sayede Play Özellik Yayınlama Kitaplığı, Play Store'a bağlanmadan özellik modüllerini yüklemeyi test etmek için 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 uygulamasını kullanın. Her iki işlemi de aşağıdaki komutla gerçekleştirebilirsiniz:

bundletool install-apks --apks my_app.apks

Artık uygulamanızı başlatıp özellik modülü indirip yüklemek için kullanıcı akışını tamamladığınızda Play Özellik Yayınlama Kitaplığı, bundletoolcihazın yerel depolama alanına aktarılan APK'ları kullanır.

Ağ hatası simülasyonu

Play Store'daki modül yüklemelerini simüle etmek amacıyla Play Feature Delivery kitaplığı, modülü istemek için SplitInstallManager yerine FakeSplitInstallManager adlı bir alternatif kullanır. Bir APK grubu oluşturmak ve bunları test cihazınıza dağıtmak için bundletool öğesini --local-testing işaretiyle birlikte kullandığınızda, Play Özellik Yayınlama Kitaplığı'na, uygulamanızın API çağrılarını SplitInstallManager yerine FakeSplitInstallManager çağırması için otomatik olarak değiştirme talimatı veren meta veriler 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 ürününe erişmek için aşağıda gösterildiği gibi FakeSplitInstallManagerFactory 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);