ViewModel'e genel bakış Android Jetpack'in bir parçasıdır.

ViewModel sınıfı, iş mantığı veya ekran düzeyinde bir durumdur. tutucu'ya dokunun. Durumu kullanıcı arayüzüne gösterir ve ilgili iş mantığını içerir. En önemli avantajı, durumu önbelleğe alması ve yapılandırma değişiklikleridir. Böylece kullanıcı arayüzünüzün tekrar veri getirmesi gerekmez işlemler arasında gezinirken veya yapılandırma değişikliklerini takip ederken (örneğin, dokunun.

Eyalet sahipleri hakkında daha fazla bilgi için eyalet sahipleriyle ilgili kılavuzu inceleyin. Benzer şekilde, genel olarak kullanıcı arayüzü katmanı hakkında daha fazla bilgi edinmek için kullanıcı arayüzü katmanına da bakabilirsiniz. rehberlik eder.

ViewModel'in avantajları

ViewModel'in alternatifi, görüntülediğiniz verileri barındıran düz bir sınıftır kontrol edin. Bu, aktiviteler arasında gezinirken bir sorun olabilir ya da Navigasyon hedefleri. Bu işlem, depolamadığınız verileri yok eder örnek kaydetme durum mekanizmasını kullanın. ViewModel, dönüşüm hunisinin Veri kalıcılığı için API, bu sorunu çözer.

ViewModel sınıfının temel avantajları temelde ikidir:

  • Kullanıcı arayüzü durumunu korumanızı sağlar.
  • İş mantığına erişim sağlar.
ziyaret edin.

Kalıcı

ViewModel, hem ViewModel'in sahip olduğu durum hem de bir ViewModel'in tetiklediği işlemler. Bu önbelleğe alma, yaygın yapılandırma değişiklikleriyle (ör. ekran) ve sağlayabilir.

Kapsam

Bir ViewModel'i örneklendirdiğinizde, ona ViewModelStoreOwner arayüzü. Bu bir Navigasyon hedefi olabilir kullanır. Daha sonra ViewModel'iniz, modelinizin Yaşam Döngüsü'nü ViewModelStoreOwner. Saat ViewModelStoreOwner olana kadar bellekte kalır kalıcı olarak kaybolur.

Çeşitli sınıflar, ViewModelStoreOwner arayüzü. Doğrudan alt sınıflar ComponentActivity, Fragment ve NavBackStackEntry. Dolaylı alt sınıfların tam listesi için bkz. ViewModelStoreOwner referansı.

ViewModel'in kapsamının ayarlandığı parça veya etkinlik kaldırıldığında, eşzamansız çalışma, kapsama alınan ViewModel'de devam eder. Bu, sebatın anahtarıdır.

Daha fazla bilgi için aşağıdaki ViewModel yaşam döngüsü ile ilgili bölüme bakın.

SavedStateHerkese Açık

SavedStateHandle, yalnızca yapılandırma aracılığıyla değil verileri kalıcı hale getirmenize olanak tanır yalnızca sürecin bir parçasını oluşturur. Yani, kullanıcı arayüzünü sürekli olarak kullanıcı uygulamayı kapatıp daha sonra açtığında bile değişmeden kalır.

İş mantığına erişim

İş mantığının büyük çoğunluğu verilerde mevcut olsa da kullanıcı arayüzü katmanında iş mantığı da bulunabilir. Bu durum, ekran kullanıcı arayüzü durumunu oluşturmak için birden çok depodan verileri birleştirme veya veya belirli bir veri türü, veri katmanı gerektirmez.

ViewModel, kullanıcı arayüzü katmanındaki iş mantığını işlemek için doğru yerdir. İlgili içeriği oluşturmak için kullanılan ViewModel, aynı zamanda etkinlikleri yönetmekten ve bunları diğer değişiklik yapmak için işletme mantığının uygulanması gerektiğinde uygulama verileri.

Jetpack Compose

Jetpack Compose'u kullanırken ViewModel, ekran kullanıcı arayüzünü göstermenin birincil yoludur tam olarak bunu görüntüleyebilirsiniz. Karma uygulamalarda etkinlikler ve parçalar yalnızca composable işlevlerinizi kullanmanızı öneririz. Bu, geçmişte uygulanan yaklaşımlardan bir değişimdir; yeniden kullanılabilir kullanıcı arayüzü parçaları oluşturmak için basit ve sezgisel bu da, kullanıcı arayüzü denetleyicileri olarak çok daha etkin olmalarını sağladı.

ViewModel'i Compose ile birlikte kullanırken unutulmaması gereken en önemli nokta ViewModel'in kapsamını bir composable olarak belirleyemeyeceğinizden emin olun. Bunun nedeni, composable bir ViewModelStoreOwner değil. Aynı composable’ın Beste veya aynı ViewModel türüne erişen iki farklı composable aynı ViewModelStoreOwner altında bir aynı örneği alır ViewModel'den farklıdır.

Compose'da ViewModel'in avantajlarından yararlanmak için her ekranı bir Parçada barındırın veya Etkinlik oluşturun ya da Gezinme Oluştur'u kullanın ve ViewModelleri'ni composable'da kullanın olabildiğince yakın çalışır. Çünkü bir ViewModel'i navigasyon hedeflerine, Navigasyon grafiklerine, Etkinlikler ve Parçalar.

Daha fazla bilgi için Jetpack Compose için eyalet kaldırma rehberine bakın.

ViewModel Uygulama

Aşağıda, Veriye Dayalı İlişkilendirme'nin kullanıldığı bir ekran için kullanıcının zar atmasına izin verir.

Kotlin

data class DiceUiState(
    val firstDieValue: Int? = null,
    val secondDieValue: Int? = null,
    val numberOfRolls: Int = 0,
)

class DiceRollViewModel : ViewModel() {

    // Expose screen UI state
    private val _uiState = MutableStateFlow(DiceUiState())
    val uiState: StateFlow<DiceUiState> = _uiState.asStateFlow()

    // Handle business logic
    fun rollDice() {
        _uiState.update { currentState ->
            currentState.copy(
                firstDieValue = Random.nextInt(from = 1, until = 7),
                secondDieValue = Random.nextInt(from = 1, until = 7),
                numberOfRolls = currentState.numberOfRolls + 1,
            )
        }
    }
}

Java

public class DiceUiState {
    private final Integer firstDieValue;
    private final Integer secondDieValue;
    private final int numberOfRolls;

    // ...
}

public class DiceRollViewModel extends ViewModel {

    private final MutableLiveData<DiceUiState> uiState =
        new MutableLiveData(new DiceUiState(null, null, 0));
    public LiveData<DiceUiState> getUiState() {
        return uiState;
    }

    public void rollDice() {
        Random random = new Random();
        uiState.setValue(
            new DiceUiState(
                random.nextInt(7) + 1,
                random.nextInt(7) + 1,
                uiState.getValue().getNumberOfRolls() + 1
            )
        );
    }
}

Daha sonra, ViewModel'e bir etkinlikten aşağıdaki şekilde erişebilirsiniz:

Kotlin

import androidx.activity.viewModels

class DiceRollActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        // Create a ViewModel the first time the system calls an activity's onCreate() method.
        // Re-created activities receive the same DiceRollViewModel instance created by the first activity.

        // Use the 'by viewModels()' Kotlin property delegate
        // from the activity-ktx artifact
        val viewModel: DiceRollViewModel by viewModels()
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.uiState.collect {
                    // Update UI elements
                }
            }
        }
    }
}

Java

public class MyActivity extends AppCompatActivity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Create a ViewModel the first time the system calls an activity's onCreate() method.
        // Re-created activities receive the same MyViewModel instance created by the first activity.
        DiceRollViewModel model = new ViewModelProvider(this).get(DiceRollViewModel.class);
        model.getUiState().observe(this, uiState -> {
            // update UI
        });
    }
}

Jetpack Compose

import androidx.lifecycle.viewmodel.compose.viewModel

// Use the 'viewModel()' function from the lifecycle-viewmodel-compose artifact
@Composable
fun DiceRollScreen(
    viewModel: DiceRollViewModel = viewModel()
) {
    val uiState by viewModel.uiState.collectAsStateWithLifecycle()
    // Update UI elements
}

ViewModel ile eş yordamlar kullanma

ViewModel, Kotlin eş yordamlarını destekler. Kalıcı ve etkili eşzamansız çalışır. Bu işlem, kullanıcı arayüzü durumunda kalır.

Daha fazla bilgi için Android Mimarisi ile Kotlin eş yordamlarını kullanma konusuna bakın. Bileşenler.

ViewModel'in yaşam döngüsü

Bir ViewModel'nın yaşam döngüsü doğrudan onun kapsamına bağlıdır. ViewModel Ayarlandığı ViewModelStoreOwner tarihine kadar bellekte kalır kaybolur. Bu, aşağıdaki bağlamlarda gerçekleşebilir:

  • Bir etkinlik söz konusu olduğunda, etkinlik tamamlandığında.
  • Bir parça durumunda, ayrıldığında.
  • Gezinme girişi olması durumunda, söz konusu giriş arka yığından kaldırıldığında.

Bu da ViewModels'i, kalıcı olmayan verileri depolamak için mükemmel bir çözüm yapılandırma değişiklikleridir.

Şekil 1'de bir etkinliğin zaman içindeki çeşitli yaşam döngüsü döndürülüyor ve ardından durduruluyor. Bu görselde, e-posta ve sohbet ViewModel simgesini tıklayın. Bu özel diyagram bir etkinliğin durumunu gösterir. Aynı temel durumlar yaşam döngüsünü takip eder.

Etkinlik durumu değiştikçe ViewModel&#39;in yaşam döngüsünü gösterir.

Genellikle sistem tarafından ilk kez bir ViewModel çağrısı yapıldığında etkinlik nesnesinin onCreate() yöntemi. Sistem sizi arayabilir Bir etkinlik süresince onCreate() birkaç kez, örneğin Örneğin, cihaz ekranı döndürüldüğünde ortaya çıkar. ViewModel şu tarihten itibaren kullanılabilmektedir: önce, etkinlik tamamlanıp kaldırılana kadar bir ViewModel isteğinde bulunun.

ViewModel bağımlılıklarını temizleme

ViewModel aşağıdaki durumlarda onCleared yöntemini çağırır: ViewModelStoreOwner yaşam döngüsü içinde yok eder. Bu şekilde tüm çalışmalarınızı temizleyebilirsiniz ViewModel'in yaşam döngüsünü izleyen bağımlılıklar.

Aşağıdaki örnekte viewModelScope için bir alternatif gösterilmektedir. viewModelScope, yerleşik bir CoroutineScope ürünüdür ve ViewModel'in yaşam döngüsünü otomatik olarak izler. ViewModel bunu aşağıdakileri yapmak için kullanır: İşletme faaliyetlerini tetiklemek için kullanır. Bunun yerine özel bir kapsam kullanmak isterseniz daha kolay test için viewModelScope sürümünü kullanıyorsanız ViewModel CoroutineScope uygulayıcısına bağımlılık olarak tanımladı. ViewModelStoreOwner, yaşam döngüsünün sonunda ViewModel'i temizler. ViewModel, CoroutineScope öğesini de iptal eder.

class MyViewModel(
    private val coroutineScope: CoroutineScope =
        CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
) : ViewModel() {

    // Other ViewModel logic ...

    override fun onCleared() {
        coroutineScope.cancel()
    }
}

Yaşam döngüsü 2.5 sürümünde ve sonraki sürümlerde bir veya daha fazla Closeable geçirebilirsiniz Nesneleri ViewModel'in oluşturucusuna otomatik olarak kapanan ViewModel örneği temizlendi.

class CloseableCoroutineScope(
    context: CoroutineContext = SupervisorJob() + Dispatchers.Main.immediate
) : Closeable, CoroutineScope {
    override val coroutineContext: CoroutineContext = context
    override fun close() {
        coroutineContext.cancel()
   }
}

class MyViewModel(
    private val coroutineScope: CoroutineScope = CloseableCoroutineScope()
) : ViewModel(coroutineScope) {
    // Other ViewModel logic ...
}

En iyi uygulamalar

Aşağıda, ViewModel:

  • Kapsamları oluşturmaları nedeniyle, bir öğenin uygulama ayrıntıları olarak ViewModelleri'ni ekran düzeyi durum tutucusu. Bunları, yeniden kullanılabilir kullanıcı arayüzünün durum sahipleri olarak kullanmayın. bileşenlerden yalnızca birkaçı. Aksi takdirde Aynı kullanıcı arayüzü bileşeninin aynı altındaki farklı kullanımlarındaki ViewModel örneği Çip başına açık bir görünüm modeli anahtarı kullanmadığınız sürece ViewModelStoreOwner.
  • ViewModel'ler, kullanıcı arayüzü uygulama ayrıntıları hakkında bilgi sahibi olmamalıdır. Adları koruyun ViewModel API'nin sunduğu yöntemlerin ve kullanıcı arayüzü durum alanlarının olabildiğince genel olmalıdır. Bu şekilde, ViewModel'iniz her türlü form için Kullanıcı arayüzü: cep telefonu, katlanabilir cihaz, tablet, hatta Chromebook!
  • ViewModelStoreOwner, ViewModelleri'nden daha uzun süre yaşayabileceğinden Context gibi yaşam döngüsüyle ilgili API referanslarını içermemelidir. veya Resources kullanarak bellek sızıntılarını önleyin.
  • ViewModelleri başka sınıflara, işlevlere veya diğer kullanıcı arayüzü bileşenlerine geçirmeyin. Platform bunları yönettiği için onlarla mümkün olduğunca yakın yapabilir. Etkinlik, parça veya ekran düzeyinde composable işlevinize yakın bir yerde. Bu, alt düzey bileşenlerin yardımcı olur.

Daha fazla bilgi

Verileriniz daha karmaşık hale geldikçe, yalnızca yüklemenizi sağlar. ViewModel özelliğinin amacı, verilerin yapılandırma değişikliklerinden etkilenmemesi için bir kullanıcı arayüzü denetleyicisi. Daha fazla bilgi için Yapılandırma değişiklikleri genelinde verileri yükleme, kalıcı hale getirme ve yönetme hakkında bilgi için Kaydedilen Kullanıcı Arayüzü Durumları.

Android Uygulama Mimarisi Kılavuzu, depo sınıfı oluşturmanızı önerir kullanmaları gerekecek.

Ek kaynaklar

ViewModel dersi hakkında daha fazla bilgi için aşağıdakilere bakın: kaynaklar.

Belgeler

Örnekler

ziyaret edin.