---
title: 'Pencere Öğeleri'
source: 'https://academia.sh/tr/kurslar/android-servisler/pencere-ogeleri'
course: 'Platform Servisleri ve Tümleştirmeler'
language: tr
updated: '2026-10-21T05:02:42+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Pencere öğesi sağlayıcısını, güncelleme isteğini ve yerleşimi ayırır'
    - 'Pencere açılana kadar biriken güncellemelerden yalnız sonuncusunun çizildiğini ölçer'
    - 'Aynı anda yaşayan iki pencere öğesinin güncellemelerinin anahtarlarına göre ezildiğini gösterir'
    - 'Ana ekrandan kaldırılmış pencere öğesine gelen güncellemelerin kayıp olduğunu gösterir'
---

# Pencere Öğeleri

Pencere öğesi ana ekranda yaşayan küçük bir görünümdür ve veri güncellemelerini pencere açılana kadar bekletir. Ders biriken güncellemelerden yalnız sonuncusunun çizildiğini, ana ekrandan kaldırılmış pencere öğesine güncellemenin ulaşmadığını ölçer.

Önceki derste olay dışarıdan geliyor ve ekran onu bir kez daha işleyebiliyordu. Pencere öğesinde güncelleme uygulamanın içinde doğar, ama onu çizecek görünüm ana ekrandadır ve uygulamanın kendi süreci dışında yaşar. Uygulama veriyi güncellediğinde görünüm o an çizilmeyebilir. Bu derste de aynı soruyu soruyoruz: **gönderilen bu olay alıcıya kaç kopya olarak ulaştı?**

```kotlin
// Arrival.kt — gonderilen bir olayin aliciya kac kopya olarak ulastigini siniflandirir
class Signal(val key: String, val seq: Int)

class Arrival(val label: String, val sent: Signal, received: List<Signal>) {
    val copies: Int = received.count { it.seq == sent.seq }
    val verdict: String = when {
        copies > 1 -> "yinelenen"
        copies == 1 -> "birebir"
        received.any { it.key == sent.key && it.seq > sent.seq } -> "ezilen"
        else -> "kayip"
    }

    fun line() {
        println("$label: anahtar=${sent.key} | kopya=$copies -> $verdict")
    }
}

fun countArrivals(arrivals: List<Arrival>) {
    for (name in listOf("birebir", "yinelenen", "ezilen", "kayip")) {
        println("$name: ${arrivals.count { it.verdict == name }}")
    }
}
```

Sınıflandırma önceki derslerdekiyle aynıdır. Kural alıcının listesinde aynı sırayı taşıyan kopyaları sayar; hiç kopya yoksa aynı anahtarla daha sonraki bir olayın ulaşıp ulaşmadığına bakar. İçeriği ve nedeni görmez.

## Sağlayıcı ve Yerleşim

Pencere öğesinin üç parçası vardır. Bildirim dosyasındaki tanım pencere öğesini platforma tanıtır, yerleşim görünümün nasıl çizileceğini söyler ve pencere öğesi sağlayıcısı güncelleme isteklerini alır. Sağlayıcı, platform bir güncelleme istediğinde çağrılır ve yeni görünümü platforma geri verir.

```kotlin
// Platform kodu: WeatherWidget
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.widget.RemoteViews

class WeatherWidget : AppWidgetProvider() {
    override fun onUpdate(context: Context, manager: AppWidgetManager, ids: IntArray) {
        for (id in ids) {
            val views = RemoteViews(context.packageName, R.layout.widget_weather)
            views.setTextViewText(R.id.temperature, latestTemperature())
            manager.updateAppWidget(id, views)
        }
    }
}
```

`onUpdate` bir sayı yazmaz: yenileme aralığı pencere öğesinin tanımında verilir ve platform bu aralığı bir istek olarak ele alır. Parça çıktı ya da süre iddia etmez. Model, platformun bu kuralını kurar; model platformun kendisi değildir.

Güncellemenin ertelenmesi ayrı bir teslim değildir. M12/K04'te bir işin koştu mu ertelendi mi diye sorulmuştu; bu kursta ertelenen bir güncelleme sonunda ulaşırsa birebir, ulaşmazsa kayıptır. M12/K01'deki sessiz kanal da kayıp değildir: sessiz kanaldaki kullanıcı bildirimi ulaşır ve birebirdir, yalnız ses çıkarmaz.

## Yenileme Aralığı ve Çizim

Pencere öğesinin tanımında bir yenileme aralığı yazılır, ama bu aralık bir istektir. Platform, pil tasarrufu için aralığı kendisi uzatabilir ve çok kısa verilen bir aralığı belirli bir alt sınıra çeker. Uygulama bu aralıkla yetinmek zorunda değildir: veri değiştiğinde güncellemeyi kendisi tetikleyebilir. İki yol arasındaki fark, kimin saati tuttuğudur. Aralıkla yenilenen pencere öğesinde saati platform tutar ve görünüm veri değişse bile bir sonraki aralığı bekler. Uygulamanın tetiklediği güncellemede saat uygulamadadır ve pencere öğesi veri değiştiği anda yenilenir.

Bunun teslimle ilişkisi şudur: ana ekran pencere öğesini her zaman çizmez. Pencere öğesi görünmüyorsa, örneğin başka bir ana ekran sayfasındaysa ya da ekran kapalıysa, platform görünümü yalnızca saklar. Pencere görünür olduğunda saklanmış son görünüm çizilir. Aradaki görünümler çizilmez ve aynı pencere öğesinin yerini alan sonraki görünüm ezilen demektir. Bu, modelin "pencere açılana kadar biriken güncellemelerin yalnız sonuncusu çizilir" kuralının platformdaki karşılığıdır. Bu yüzden pencere öğesi için her ara durumun gösterilmesini beklemek yanlıştır; hedef, görünür olunduğunda doğru durumu göstermektir.

## Pencere Açılınca Çizilen Son Güncelleme

Modelde her veri güncellemesi bir `Signal`dır; anahtarı pencere öğesinin adıdır. Pencere açık olmadığında uygulama güncellemeleri birbiri ardına verir. Pencere açıldığında yalnız son durum çizilir; açıkken gelen her güncelleme ise tek tek çizilir. Pencerenin açıldığı adım modelin uydurma değeridir.

```kotlin
// Drawn.kt — pencere acilana kadar biriken guncellemelerden her anahtarin yalniz sonuncusu cizilir
fun drawn(sent: List<Signal>, openAt: Int): List<Signal> {
    val before = sent.filter { it.seq < openAt }
    val waiting = before.filter { s -> before.none { it.key == s.key && it.seq > s.seq } }
    return waiting + sent.filter { it.seq >= openAt }
}
```

```kotlin
// Main.kt — pencere acilana kadar biriken guncellemelerden yalniz sonuncusu cizilir
fun main() {
    val sent = (1..6).map { Signal("pencere.hava", it) }
    val received = drawn(sent, openAt = 4)
    println("ulasan siralar: ${received.map { it.seq }}")

    val arrivals = sent.map { Arrival("olay-${it.seq}", it, received) }
    arrivals.forEach { it.line() }
    countArrivals(arrivals)
}
```

```text
ulasan siralar: [3, 4, 5, 6]
olay-1: anahtar=pencere.hava | kopya=0 -> ezilen
olay-2: anahtar=pencere.hava | kopya=0 -> ezilen
olay-3: anahtar=pencere.hava | kopya=1 -> birebir
olay-4: anahtar=pencere.hava | kopya=1 -> birebir
olay-5: anahtar=pencere.hava | kopya=1 -> birebir
olay-6: anahtar=pencere.hava | kopya=1 -> birebir
birebir: 4
yinelenen: 0
ezilen: 2
kayip: 0
```

Bu dersin teslimi **ezilen**dir. Pencere 4 numaralı adımda açıldı. 1 ve 2 numaralı güncellemeler çizilmedi, çünkü aynı anahtarla 3 numaralı güncelleme onların yerini aldı. Pencere açıkken gelen 4, 5 ve 6 numaralı güncellemelerin her biri birebir ulaştı.

**SY1.** Model, açılmadan önceki bütün güncellemeleri tek bir bekleme kümesi sayar. Platformda pencere öğesinin yenilenmesi platformun kendi zamanlamasına bağlıdır ve bekleyen güncellemelerin ne kadar süreyle tutulacağı modelde yoktur.

## İki Pencere Öğesi

Ana ekranda iki pencere öğesi yaşıyorsa her birinin anahtarı kendisine aittir. Birinin güncellemesi diğerinin yerini almaz; ezme yalnız aynı anahtarlı güncellemeler arasında olur.

```kotlin
// Main.kt — iki pencere ogesinde ezme yalniz ayni anahtar icinde olur
fun main() {
    val sent = listOf(
        Signal("pencere.hava", 7),
        Signal("pencere.takvim", 8),
        Signal("pencere.hava", 9),
        Signal("pencere.takvim", 10),
        Signal("pencere.hava", 11),
        Signal("pencere.takvim", 12),
    )
    val received = drawn(sent, openAt = 10)
    println("ulasan siralar: ${received.map { it.seq }}")

    val arrivals = sent.map { Arrival("olay-${it.seq}", it, received) }
    arrivals.forEach { it.line() }
    countArrivals(arrivals)
}
```

```text
ulasan siralar: [8, 9, 10, 11, 12]
olay-7: anahtar=pencere.hava | kopya=0 -> ezilen
olay-8: anahtar=pencere.takvim | kopya=1 -> birebir
olay-9: anahtar=pencere.hava | kopya=1 -> birebir
olay-10: anahtar=pencere.takvim | kopya=1 -> birebir
olay-11: anahtar=pencere.hava | kopya=1 -> birebir
olay-12: anahtar=pencere.takvim | kopya=1 -> birebir
birebir: 5
yinelenen: 0
ezilen: 1
kayip: 0
```

Pencere 10 numaralı adımda açıldı. Açılmadan önceki üç güncellemeden yalnız 7 numaralı hava güncellemesi ezildi: 9 numaralı güncelleme onun yerini aldı. 8 numaralı takvim güncellemesi, aynı anahtarlı başka güncelleme olmadığı için birebir ulaştı.

**SY2.** Model, iki pencere öğesini birbirinden bağımsız kurar. Platformda aynı sağlayıcı birden çok pencere öğesine hizmet verebilir ve güncellemenin hangi örneğe gideceği tanıtıcı numarasına bağlıdır; bu modelde yoktur.

## Yapılandırma Ekranı

Bazı pencere öğeleri kullanıcıdan bir ayar ister: hangi şehrin havası, hangi notun gösterileceği. Kullanıcı pencere öğesini ana ekrana eklediğinde platform önce uygulamanın yapılandırma ekranını açar ve kullanıcı ayarı tamamlayana kadar pencere öğesini bekletir. Yapılandırma bitmeden gelen güncellemeler çizilecek bir ayara sahip değildir ve düşer. Aşağıdaki modelde not gösteren pencere öğesi 23 numaralı adımda yapılandırılıyor; hava pencere öğesi ise baştan hazır.

```kotlin
// Configured.kt — yapilandirma bitmeden gelen guncellemeleri birakir
fun configured(sent: List<Signal>, key: String, doneAt: Int): List<Signal> =
    sent.filter { it.key != key || it.seq >= doneAt }
```

```kotlin
// Main.kt — yapilandirma bitmeden gelen guncellemeler cizilmez
fun main() {
    val sent = listOf(
        Signal("pencere.not", 19),
        Signal("pencere.hava", 20),
        Signal("pencere.not", 21),
        Signal("pencere.hava", 22),
        Signal("pencere.not", 23),
    )
    val received = configured(sent, key = "pencere.not", doneAt = 23)
    println("ulasan siralar: ${received.map { it.seq }}")

    val arrivals = sent.map { Arrival("olay-${it.seq}", it, received) }
    arrivals.forEach { it.line() }
    countArrivals(arrivals)
}
```

```text
ulasan siralar: [20, 22, 23]
olay-19: anahtar=pencere.not | kopya=0 -> ezilen
olay-20: anahtar=pencere.hava | kopya=1 -> birebir
olay-21: anahtar=pencere.not | kopya=0 -> ezilen
olay-22: anahtar=pencere.hava | kopya=1 -> birebir
olay-23: anahtar=pencere.not | kopya=1 -> birebir
birebir: 3
yinelenen: 0
ezilen: 2
kayip: 0
```

Hava pencere öğesinin iki güncellemesi birebir ulaştı. Not pencere öğesinin 19 ve 21 numaralı güncellemeleri çizilmedi, çünkü yapılandırma 23 numaralı adımda bitti ve aynı anahtarla gelen 23 numaralı güncelleme onların yerini aldı. Kural bunları ezilen saydı; kullanıcı açısından ise bunlar henüz ayarı olmayan bir pencere öğesine gönderilmiş, bu yüzden hiç anlam taşımayan güncellemelerdi. Yapılandırma bitiminden sonra aynı anahtarla hiçbir güncelleme gelmeseydi, aynı iki güncelleme kayıp sayılacaktı.

**SY3.** Model, yapılandırmayı tek bir adımda ve kesin olarak bitmiş kabul eder. Platformda kullanıcı yapılandırma ekranından vazgeçebilir ve bu durumda pencere öğesi hiç eklenmez; ayrıca yapılandırma ekranı açıkken platformun güncelleme isteklerine nasıl davrandığı modelde yoktur.

## Neden Her Güncelleme Tüm Görünümü Taşır

Pencere öğesi uygulamanın süreci içinde değil, ana ekran uygulamasının sürecinde çizilir. Uygulama görünümü doğrudan değiştiremez; bunun yerine görünümün bir tarifini üretir ve platform bu tarifi ana ekrana iletir. Tarif, tek bir alanın değişikliği olarak değil çoğunlukla bütün görünümün yeni hali olarak verilir. Sonuç olarak her güncelleme bir öncekini tamamen değiştirir.

Ezilen teslimin bu dersteki doğal yeri budur. İki güncelleme birleştirilemez, çünkü ikinci güncelleme birincinin üzerine eklenmez, yerine geçer. Bir sıcaklık değerini içeren ilk görünüm ile nem değerini içeren ikinci görünüm arasında, ilkini tutarak ikincisini eklemek mümkün değildir. İkinci görünüm sıcaklığı da içermiyorsa pencere öğesinde sıcaklık görünmez olur. Bu yüzden her güncelleme, gösterilecek bütün durumu taşımalıdır.

Aynı kural uygulamaya şunu da söyler: bir güncellemenin ezilmesi bilgi kaybı değildir, yeter ki sonraki güncelleme bütün durumu taşısın. Bilginin kaybolduğu durum, sonraki güncellemenin yalnızca değişen alanı taşıdığı durumdur. Model bunu ayırt etmez; her güncellemeyi aynı anahtarlı bir sıra sayar ve ardıl güncelleme eksik taşısa bile ezilen der. Ardılın tam olup olmadığı uygulamanın tasarım kararıdır.

## Boyut Değişince Ne Olur

Kullanıcı pencere öğesini yeniden boyutlandırdığında platform sağlayıcıya yeni boyutu bildirir ve uygulamadan yeni bir görünüm bekler. Bu çağrı bir güncelleme isteğidir ve aralığa bağlı değildir; kullanıcı ne zaman boyut değiştirirse o an gelir. Uygulama yeni boyuta uygun bir tarif üretmezse eski tarif yeni boyuta sığmayabilir: metin kesilir, görsel taşar ya da pencere öğesi boş görünür.

Bu, ezilen teslimin ikinci bir kaynağıdır. Aralıktan gelen güncelleme ile boyuttan gelen güncelleme aynı anahtarı taşır, çünkü ikisi de aynı pencere öğesinin durumudur. Boyut değişikliği hemen ardından aralıktan bir güncelleme gelirse, ikisinden yalnız sonuncusu çizilir. Sonuncu yeni boyutu bilmiyorsa kullanıcı boyutlandırmanın etkisiz kaldığını görür. Bu yüzden her tarif, o anki boyuta göre üretilmelidir; boyutu bir kez okuyup saklayan uygulama, ardıl güncellemelerde eski boyutu kullanır.

## Yaygın Yanılgılar

**"Yenileme aralığı bir sözdür."** Aralık bir istektir. Platform onu uzatabilir ve pencere görünür değilse görünümü yalnızca saklar. Her güncellemenin çizilmesini bekleyen bir uygulama, ölçümdeki ilk bloktaki gibi ezilen güncellemeler bulur.

**"Ezilen güncelleme bir hatadır."** Pencere öğesi için son durum eskisinden değerlidir. Çizilmeyen ara durum, kullanıcının hiç görmeyeceği bir şeydir ve kaybı değil, tasarımı gösterir. Hata, son durumun hiç çizilmediği durumdur: bu kayıptır.

**"Ertelenen güncelleme ayrı bir teslimdir."** Bu kursun dört teslimi vardır. Ertelenen güncelleme ulaşırsa birebir, bir sonraki güncellemeyle yer değiştirirse ezilen, hiç ulaşmazsa kayıptır. Erteleme bir teslim türü değil, ulaşma zamanına dair bir özelliktir.

**"Kaldırılan pencere öğesine güncelleme göndermek zararsızdır."** Güncelleme zarar vermez ama boşunadır: çizilecek görünüm kalmamıştır. Pil harcayan ve hiçbir yere ulaşmayan bu güncellemelerin durdurulması için uygulama, kaldırma çağrısını dinlemelidir.

**"Pencere öğesi uygulama kapalıyken güncellenemez."** Sağlayıcı, uygulamanın ön planda olmasından bağımsız çalışır. Platform sağlayıcıyı güncelleme için uyandırır ve iş bitince süreç yeniden uykuya geçebilir. Bu yüzden güncelleme için gereken veri sağlayıcının çağrısında hazır olmalı ya da hızlıca alınabilmelidir.

**"Her pencere öğesi aynı görünümü gösterir."** Aynı sağlayıcıdan eklenmiş iki pencere öğesi farklı boyutta ve farklı ayarda olabilir; her birinin kendi anahtarı ve kendi güncelleme dizisi vardır.

## Sınırlayıcı Ölçüm

Kullanıcı pencere öğesini ana ekrandan kaldırdığında sağlayıcı artık güncelleme alıcısı değildir. Uygulama güncellemeleri üretmeye devam eder, ama çizilecek bir görünüm kalmamıştır.

```kotlin
// Removed.kt — ana ekrandan kaldirilan pencere ogesine guncelleme ulasmaz
fun removed(drawn: List<Signal>, removedAt: Int): List<Signal> =
    drawn.filter { it.seq < removedAt }
```

```kotlin
// Main.kt — ana ekrandan kaldirilan pencere ogesine guncelleme ulasmaz
fun main() {
    val sent = (13..18).map { Signal("pencere.hava", it) }
    val received = removed(drawn(sent, openAt = 15), removedAt = 17)
    println("ulasan siralar: ${received.map { it.seq }}")

    val arrivals = sent.map { Arrival("olay-${it.seq}", it, received) }
    arrivals.forEach { it.line() }
    countArrivals(arrivals)
}
```

```text
ulasan siralar: [14, 15, 16]
olay-13: anahtar=pencere.hava | kopya=0 -> ezilen
olay-14: anahtar=pencere.hava | kopya=1 -> birebir
olay-15: anahtar=pencere.hava | kopya=1 -> birebir
olay-16: anahtar=pencere.hava | kopya=1 -> birebir
olay-17: anahtar=pencere.hava | kopya=0 -> kayip
olay-18: anahtar=pencere.hava | kopya=0 -> kayip
birebir: 3
yinelenen: 0
ezilen: 1
kayip: 2
```

13 numaralı güncelleme ezildi, 14, 15 ve 16 ulaştı. Pencere öğesi 17 numaralı adımdan önce kaldırıldığı için 17 ve 18 numaralı güncellemeler kayıp oldu: sonrasında aynı anahtarla hiçbir güncelleme ulaşmadı. Kural kaybın nedeninin kaldırılmış pencere öğesi olduğunu görmez; bunu bilmek için uygulamanın hangi pencere öğesi tanıtıcılarının yaşadığını ayrıca sorması gerekir.

**SY4.** Model, kaldırmayı anında ve tek adımda kurar. Platformda kaldırılan pencere öğesi için silme çağrısı sağlayıcıya gelir ve uygulama güncellemeyi o noktada durdurabilir; bu modelde yoktur.

## Özet

- Bu dersin teslimi: ezilen. Pencere açılana kadar biriken güncellemelerden her anahtarın yalnız sonuncusu çizilir.
- Altı güncellemeden ikisi ezildi, dördü birebir ulaştı: ezilen 2, birebir 4.
- İki pencere öğesinde ezme yalnız aynı anahtar içinde oldu: bir güncelleme ezildi, beşi birebir ulaştı.
- Ana ekrandan kaldırılan pencere öğesine iki güncelleme kayıp oldu: kayip 2.
- Ertelenen güncelleme ayrı bir kategori değildir; sessiz kanaldaki kullanıcı bildirimi ulaşır ve birebirdir.
- Yapılandırması bitmemiş pencere öğesinin iki güncellemesi, bitişten sonra aynı anahtarla gelen güncelleme yüzünden ezilen sayıldı: birebir 3, ezilen 2.

## Sonraki Adım

Bu dersle sistem yeteneklerinin sonuna geldik: kullanıcı bildirimi, bulut mesajlaşma, konum, kamera, sensör, derin bağlantı ve pencere öğesi aynı soruyla ölçüldü. Sıradaki konuda uygulamanın kendi verisi ve anahtarları konuşulur: `Şifreli Depolama ve Anahtar Deposu` dersi, saklanan verinin ve anahtarın kimin eline düşebileceğini ele alır.
