{"id":31228,"date":"2025-10-07T12:31:51","date_gmt":"2025-10-07T09:31:51","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/"},"modified":"2025-10-07T12:31:51","modified_gmt":"2025-10-07T09:31:51","slug":"jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/","title":{"rendered":"Jetpack ViewModels&#8217;ta AutoCloseable ile Kaynak Temizli\u011fi"},"content":{"rendered":"<style>\n    body {\n        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n        line-height: 1.7;\n        color: #333;\n        margin: 0 auto;\n        max-width: 960px;\n        padding: 20px;\n        background-color: #f9f9f9;\n    }\n    h2, h3 {\n        color: #2c3e50;\n        margin-top: 35px;\n        margin-bottom: 20px;\n        border-bottom: 2px solid #3498db;\n        padding-bottom: 10px;\n    }\n    h2 {\n        font-size: 2em;\n    }\n    h3 {\n        font-size: 1.5em;\n        border-bottom: 1px dashed #3498db;\n        padding-bottom: 5px;\n    }\n    p {\n        margin-bottom: 1em;\n        text-align: justify;\n    }\n    ul {\n        list-style-type: disc;\n        margin-left: 25px;\n        margin-bottom: 1em;\n    }\n    ol {\n        list-style-type: decimal;\n        margin-left: 25px;\n        margin-bottom: 1em;\n    }\n    li {\n        margin-bottom: 0.5em;\n    }\n    pre {\n        background-color: #ecf0f1;\n        border: 1px solid #ddd;\n        padding: 15px;\n        border-radius: 8px;\n        overflow-x: auto;\n        margin-bottom: 20px;\n    }\n    code {\n        font-family: 'Consolas', 'Monaco', monospace;\n        background-color: #ecf0f1;\n        padding: 2px 4px;\n        border-radius: 4px;\n        color: #c0392b;\n    }\n    pre code {\n        background-color: transparent;\n        padding: 0;\n        color: #2c3e50;\n    }\n    blockquote {\n        background-color: #e8f4f8;\n        border-left: 5px solid #3498db;\n        margin: 20px 0;\n        padding: 15px 20px;\n        font-style: italic;\n        color: #2c3e50;\n        border-radius: 4px;\n    }\n    table {\n        width: 100%;\n        border-collapse: collapse;\n        margin-bottom: 20px;\n    }\n    th, td {\n        border: 1px solid #ddd;\n        padding: 10px;\n        text-align: left;\n    }\n    th {\n        background-color: #3498db;\n        color: white;\n    }\n    tr:nth-child(even) {\n        background-color: #f2f2f2;\n    }<\/p>\n<p>    \/* Mobil uyumluluk i\u00e7in medya sorgular\u0131 *\/\n    @media (max-width: 768px) {\n        body {\n            padding: 15px;\n        }\n        h2 {\n            font-size: 1.7em;\n        }\n        h3 {\n            font-size: 1.3em;\n        }\n        pre {\n            padding: 10px;\n        }\n        blockquote {\n            margin: 15px 0;\n            padding: 10px 15px;\n        }\n        table, thead, tbody, th, td, tr {\n            display: block;\n        }\n        thead tr {\n            position: absolute;\n            top: -9999px;\n            left: -9999px;\n        }\n        tr { border: 1px solid #ccc; }\n        td {\n            border: none;\n            border-bottom: 1px solid #eee;\n            position: relative;\n            padding-left: 50%;\n            text-align: right;\n        }\n        td:before {\n            position: absolute;\n            top: 6px;\n            left: 6px;\n            width: 45%;\n            padding-right: 10px;\n            white-space: nowrap;\n            text-align: left;\n            font-weight: bold;\n        }\n        td:nth-of-type(1):before { content: \"Kavram\"; }\n        td:nth-of-type(2):before { content: \"A\u00e7\u0131klama\"; }\n    }\n<\/style>\n<p><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><\/p>\n<p>Android uygulamalar\u0131nda performans ve kararl\u0131l\u0131k, kaynak y\u00f6netiminin ne kadar etkili yap\u0131ld\u0131\u011f\u0131yla do\u011frudan ili\u015fkilidir. \u00d6zellikle ViewModel&#8217;lar, ya\u015fam d\u00f6ng\u00fcs\u00fcne duyarl\u0131 mimarileri nedeniyle kaynak temizli\u011finin hayati \u00f6nem ta\u015f\u0131d\u0131\u011f\u0131 bile\u015fenlerdir. Bu yaz\u0131m\u0131zda, Jetpack ViewModels&#8217;ta <code>AutoCloseable<\/code> aray\u00fcz\u00fcn\u00fc kullanarak otomatik kaynak temizli\u011finin nas\u0131l sa\u011flanaca\u011f\u0131n\u0131, uygulaman\u0131z\u0131n bellek s\u0131z\u0131nt\u0131lar\u0131ndan nas\u0131l korunaca\u011f\u0131n\u0131 ve kodunuzu nas\u0131l daha d\u00fczenli hale getirece\u011finizi ad\u0131m ad\u0131m inceleyece\u011fiz. Modern Android geli\u015ftiricilerinin s\u0131k\u00e7a kar\u015f\u0131la\u015ft\u0131\u011f\u0131 bu sorunlara pratik \u00e7\u00f6z\u00fcmler sunarak, hem yeni ba\u015flayanlar hem de deneyimli geli\u015ftiriciler i\u00e7in kapsaml\u0131 bir rehber haz\u0131rlad\u0131k.<\/p>\n<p>Android uygulamalar\u0131 geli\u015ftirirken, kullan\u0131c\u0131 deneyimini do\u011frudan etkileyen en \u00f6nemli fakt\u00f6rlerden biri ku\u015fkusuz uygulaman\u0131n performans\u0131d\u0131r. Performans\u0131 d\u00fc\u015f\u00fcren, uygulaman\u0131n \u00e7\u00f6kmesine neden olan veya pil \u00f6mr\u00fcn\u00fc olumsuz etkileyen unsurlar\u0131n ba\u015f\u0131nda ise bellek s\u0131z\u0131nt\u0131lar\u0131 ve d\u00fczg\u00fcn y\u00f6netilmeyen kaynaklar gelir. \u00d6zellikle Jetpack Compose ve MVVM (Model-View-ViewModel) mimarisiyle geli\u015ftirilen modern Android uygulamalar\u0131nda <code>ViewModel<\/code>&#8216;lar, kullan\u0131c\u0131 aray\u00fcz\u00fc (UI) verilerini ya\u015fam d\u00f6ng\u00fcs\u00fcne duyarl\u0131 bir \u015fekilde saklamak ve i\u015flemek i\u00e7in vazge\u00e7ilmez bir role sahiptir. Bu ba\u011flamda, <code>ViewModel<\/code> i\u00e7inde tutulan kaynaklar\u0131n do\u011fru bir \u015fekilde y\u00f6netilmesi, uygulaman\u0131n genel sa\u011fl\u0131\u011f\u0131 i\u00e7in hayati bir \u00f6nem ta\u015f\u0131maktad\u0131r.<\/p>\n<p>Bir <code>ViewModel<\/code>, ilgili <code>Activity<\/code> veya <code>Fragment<\/code> ya\u015fam d\u00f6ng\u00fcs\u00fc boyunca hayatta kal\u0131r ve yap\u0131land\u0131rma de\u011fi\u015fikliklerinde (\u00f6rne\u011fin ekran d\u00f6nd\u00fcrme) yeniden olu\u015fturulmaz. Bu, <code>ViewModel<\/code>&#8216;in veri tutma yetene\u011fini m\u00fckemmel k\u0131lar, ancak ayn\u0131 zamanda potansiyel tehlikeleri de beraberinde getirir. E\u011fer bir <code>ViewModel<\/code> i\u00e7inde, ya\u015fam d\u00f6ng\u00fcs\u00fc sona erdi\u011finde (yani <code>Activity<\/code> veya <code>Fragment<\/code> tamamen yok edildi\u011finde) serbest b\u0131rak\u0131lmas\u0131 gereken kaynaklar (veritaban\u0131 ba\u011flant\u0131lar\u0131, a\u011f istemcileri, ak\u0131\u015flar, RxJava <code>Disposable<\/code>&#8216;lar veya Coroutine <code>Job<\/code>&#8216;lar\u0131 gibi) d\u00fczg\u00fcn bir \u015fekilde kapat\u0131lmazsa, bu durum bellek s\u0131z\u0131nt\u0131lar\u0131na yol a\u00e7ar. Bellek s\u0131z\u0131nt\u0131lar\u0131, uygulaman\u0131z\u0131n gereksiz yere bellek t\u00fcketmesine, zamanla yava\u015flamas\u0131na ve hatta &#8220;Out Of Memory&#8221; (OOM) hatalar\u0131 vererek \u00e7\u00f6kmesine neden olabilir. Bu nedenle, <code>ViewModel<\/code> i\u00e7indeki kaynaklar\u0131n temizli\u011fi, uygulaman\u0131n kararl\u0131l\u0131\u011f\u0131n\u0131 ve performans\u0131n\u0131 do\u011frudan etkileyen kritik bir ad\u0131md\u0131r.<\/p>\n<p>Genellikle, bu t\u00fcr kaynaklar\u0131n temizli\u011fi <code>ViewModel<\/code>&#8216;in <code>onCleared()<\/code> metodunda manuel olarak yap\u0131l\u0131r. Ancak bu manuel yakla\u015f\u0131m, baz\u0131 dezavantajlar\u0131 da beraberinde getirir. \u00d6rne\u011fin, birden fazla kayna\u011f\u0131n\u0131z varsa ve her birini manuel olarak temizlemeniz gerekiyorsa, kodunuz h\u0131zla b\u00fcy\u00fcyebilir ve karma\u015f\u0131k hale gelebilir. Ayr\u0131ca, her yeni kaynak ekledi\u011finizde <code>onCleared()<\/code> metodunu g\u00fcncellemeyi unutma riski de her zaman mevcuttur. Bu durum, \u00f6zellikle b\u00fcy\u00fck ekiplerde veya karma\u015f\u0131k projelerde hata yapma olas\u0131l\u0131\u011f\u0131n\u0131 art\u0131r\u0131r ve bellek s\u0131z\u0131nt\u0131lar\u0131na yol a\u00e7abilecek gizli hatalar\u0131n ortaya \u00e7\u0131kmas\u0131na zemin haz\u0131rlar. \u0130\u015fte tam bu noktada, Java&#8217;n\u0131n <code>AutoCloseable<\/code> aray\u00fcz\u00fc ve Kotlin&#8217;in modern yap\u0131s\u0131yla birle\u015fti\u011finde otomatik kaynak temizli\u011fi devreye girerek bu sorunlara zarif ve etkili bir \u00e7\u00f6z\u00fcm sunar. Bu yakla\u015f\u0131mla, kaynak y\u00f6netimini daha d\u00fczenli, daha az hataya a\u00e7\u0131k ve daha s\u00fcrd\u00fcr\u00fclebilir hale getirebiliriz. Dolay\u0131s\u0131yla, <code>ViewModel<\/code>&#8216;larda kaynak y\u00f6netimi, sadece bir iyi uygulama olmaktan \u00f6te, sa\u011flam ve g\u00fcvenilir bir Android uygulamas\u0131 geli\u015ftirmenin temel bir dire\u011fidir.<\/p>\n<h2>AutoCloseable Aray\u00fcz\u00fc Nedir ve Nas\u0131l \u00c7al\u0131\u015f\u0131r?<\/h2>\n<p><code>AutoCloseable<\/code> aray\u00fcz\u00fc, Java 7 ile birlikte tan\u0131t\u0131lan ve \u00f6zellikle kaynak y\u00f6netimi konular\u0131nda geli\u015ftiricilere b\u00fcy\u00fck kolayl\u0131k sa\u011flayan bir yap\u0131d\u0131r. Temel amac\u0131, bir kayna\u011f\u0131n (\u00f6rne\u011fin bir dosya ak\u0131\u015f\u0131, veritaban\u0131 ba\u011flant\u0131s\u0131 veya a\u011f ba\u011flant\u0131s\u0131 gibi) i\u015fi bitti\u011finde otomatik olarak kapat\u0131lmas\u0131n\u0131 sa\u011flamakt\u0131r. Bu, manuel <code>try-finally<\/code> bloklar\u0131n\u0131n getirdi\u011fi karma\u015f\u0131kl\u0131\u011f\u0131 azalt\u0131r ve kaynak temizli\u011fini daha g\u00fcvenli ve okunakl\u0131 hale getirir. Bir s\u0131n\u0131f\u0131n <code>AutoCloseable<\/code> aray\u00fcz\u00fcn\u00fc uygulamas\u0131 demek, o s\u0131n\u0131f\u0131n bir <code>close()<\/code> metoduna sahip olmas\u0131 gerekti\u011fi anlam\u0131na gelir. Bu <code>close()<\/code> metodu, ilgili kayna\u011f\u0131n serbest b\u0131rak\u0131lmas\u0131ndan sorumlu olacakt\u0131r.<\/p>\n<p>Peki, <code>AutoCloseable<\/code> tam olarak nas\u0131l \u00e7al\u0131\u015f\u0131r? Java&#8217;da bu aray\u00fcz, \u00f6zellikle &#8220;try-with-resources&#8221; ifadesiyle birlikte kullan\u0131ld\u0131\u011f\u0131nda t\u00fcm g\u00fcc\u00fcn\u00fc ortaya koyar. &#8220;try-with-resources&#8221; blo\u011fu, bir veya daha fazla kayna\u011f\u0131 bildirmenize olanak tan\u0131r ve bu kaynaklar, blo\u011fun sonunda otomatik olarak kapat\u0131l\u0131r, hatta bir istisna olu\u015fsa bile. Bu mekanizma, kaynaklar\u0131n her zaman d\u00fczg\u00fcn bir \u015fekilde temizlenmesini garanti eder. Android geli\u015ftirme ba\u011flam\u0131nda, bu \u00f6zellik <code>ViewModel<\/code>&#8216;lar gibi ya\u015fam d\u00f6ng\u00fcs\u00fcne sahip bile\u015fenlerdeki kaynak temizli\u011fi i\u00e7in m\u00fcthi\u015f bir potansiyel sunar.<\/p>\n<pre><code class=\"language-java\">\nimport java.io.Closeable; \/\/ Closeable AutoCloseable'\u0131 extend eder\n\npublic class MyResource implements AutoCloseable {\n    private String resourceName;\n\n    public MyResource(String name) {\n        this.resourceName = name;\n        System.out.println(resourceName + \" kayna\u011f\u0131 olu\u015fturuldu.\");\n    }\n\n    public void doWork() {\n        System.out.println(resourceName + \" kayna\u011f\u0131 ile \u00e7al\u0131\u015f\u0131l\u0131yor...\");\n    }\n\n    @Override\n    public void close() throws Exception {\n        System.out.println(resourceName + \" kayna\u011f\u0131 kapat\u0131l\u0131yor.\");\n        \/\/ Kayna\u011f\u0131 serbest b\u0131rakma mant\u0131\u011f\u0131 burada yer al\u0131r.\n        \/\/ \u00d6rne\u011fin, veritaban\u0131 ba\u011flant\u0131s\u0131n\u0131 kapatma, ak\u0131\u015f\u0131 sonland\u0131rma vb.\n    }\n\n    public static void main(String[] args) {\n        try (MyResource resource1 = new MyResource(\"Veritaban\u0131 Ba\u011flant\u0131s\u0131\")) {\n            resource1.doWork();\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n\n        \/\/ try-with-resources blo\u011fu bitti\u011finde resource1 otomatik olarak kapat\u0131lacak.\n        \/\/ Manuel kapatmaya gerek kalmaz.\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki \u00f6rnekte, <code>MyResource<\/code> s\u0131n\u0131f\u0131 <code>AutoCloseable<\/code> aray\u00fcz\u00fcn\u00fc uyguluyor. <code>close()<\/code> metodu, kayna\u011f\u0131n serbest b\u0131rak\u0131lmas\u0131ndan sorumludur. <code>main<\/code> metodunda, <code>try-with-resources<\/code> blo\u011fu i\u00e7inde <code>MyResource<\/code> nesnesi olu\u015fturuluyor. Blo\u011fun sonunda (ister normal sonlans\u0131n ister bir istisna f\u0131rlat\u0131ls\u0131n), <code>close()<\/code> metodu otomatik olarak \u00e7a\u011fr\u0131larak kaynak temizleniyor. Bu yakla\u015f\u0131m, kaynak y\u00f6netimindeki boilerplate kodu \u00f6nemli \u00f6l\u00e7\u00fcde azalt\u0131r ve geli\u015ftiricinin daha \u00e7ok i\u015f mant\u0131\u011f\u0131na odaklanmas\u0131n\u0131 sa\u011flar. Ancak, <code>ViewModel<\/code>'lar do\u011frudan bir <code>try-with-resources<\/code> blo\u011fu i\u00e7inde ya\u015famad\u0131\u011f\u0131 i\u00e7in, <code>AutoCloseable<\/code>'\u0131n <code>ViewModel<\/code> ya\u015fam d\u00f6ng\u00fcs\u00fcyle nas\u0131l entegre edilece\u011fi \u00f6zel bir yakla\u015f\u0131mla ele al\u0131nmal\u0131d\u0131r. \u0130\u015fte bu noktada Jetpack'in <code>androidx.lifecycle.ViewModel<\/code> s\u0131n\u0131f\u0131n\u0131n sundu\u011fu olanaklar devreye girer. Geli\u015ftiriciler, <code>ViewModel<\/code> i\u00e7inde tutulan <code>AutoCloseable<\/code> nesnelerini, <code>ViewModel<\/code>'in <code>onCleared()<\/code> metodunda manuel olarak de\u011fil, daha organize ve otomatik bir \u015fekilde temizlemenin yollar\u0131n\u0131 aramaktad\u0131rlar. Bu sayede, uygulaman\u0131n bellek s\u0131z\u0131nt\u0131lar\u0131na kar\u015f\u0131 daha diren\u00e7li olmas\u0131 sa\u011flan\u0131r ve kaynak temizli\u011fi s\u00fcreci daha az hataya a\u00e7\u0131k hale gelir.<\/p>\n<h3>AutoCloseable ve Closeable Aras\u0131ndaki Farklar Nelerdir?<\/h3>\n<p>Java ekosisteminde kaynak y\u00f6netimi denince akla gelen iki \u00f6nemli aray\u00fcz vard\u0131r: <code>java.lang.AutoCloseable<\/code> ve <code>java.io.Closeable<\/code>. Her ikisi de kaynaklar\u0131n kapat\u0131lmas\u0131n\u0131 sa\u011flayan bir <code>close()<\/code> metoduna sahip olsa da, aralar\u0131nda \u00f6nemli farklar bulunur ve bu farklar\u0131 anlamak, do\u011fru aray\u00fcz\u00fc se\u00e7mek i\u00e7in kritik \u00f6neme sahiptir.<\/p>\n<p>\u00d6ncelikle, <code>java.io.Closeable<\/code> aray\u00fcz\u00fcne bakal\u0131m. Bu aray\u00fcz, Java 5 ile birlikte tan\u0131t\u0131lm\u0131\u015ft\u0131r ve genellikle I\/O (giri\u015f\/\u00e7\u0131k\u0131\u015f) kaynaklar\u0131 i\u00e7in tasarlanm\u0131\u015ft\u0131r. \u00d6rne\u011fin, <code>FileInputStream<\/code>, <code>FileOutputStream<\/code>, <code>BufferedReader<\/code> gibi s\u0131n\u0131flar <code>Closeable<\/code> aray\u00fcz\u00fcn\u00fc uygular. <code>Closeable<\/code> aray\u00fcz\u00fcn\u00fcn <code>close()<\/code> metodu, imzas\u0131 itibar\u0131yla <code>void close() throws IOException<\/code> \u015feklindedir. Yani, bu metodun yaln\u0131zca <code>IOException<\/code> f\u0131rlatabilece\u011fi varsay\u0131l\u0131r. Bu aray\u00fcz, \"try-finally\" bloklar\u0131nda kaynaklar\u0131 manuel olarak kapatmak i\u00e7in yayg\u0131n olarak kullan\u0131lm\u0131\u015ft\u0131r. Ancak, bir I\/O kayna\u011f\u0131 d\u0131\u015f\u0131ndaki bir kayna\u011f\u0131 kapat\u0131rken farkl\u0131 t\u00fcrde istisnalar f\u0131rlatma ihtiyac\u0131 do\u011fabilir ve <code>Closeable<\/code> bu senaryolar i\u00e7in uygun de\u011fildir.<\/p>\n<p>Di\u011fer yandan, <code>java.lang.AutoCloseable<\/code> aray\u00fcz\u00fc, Java 7 ile birlikte tan\u0131t\u0131lan daha genel bir aray\u00fczd\u00fcr ve <code>Closeable<\/code> aray\u00fcz\u00fcn\u00fcn temelini olu\u015fturur. Asl\u0131nda, <code>Closeable<\/code> aray\u00fcz\u00fc <code>AutoCloseable<\/code>'\u0131 extend eder. <code>AutoCloseable<\/code> aray\u00fcz\u00fcn\u00fcn <code>close()<\/code> metodu imzas\u0131 <code>void close() throws Exception<\/code> \u015feklindedir. Bu, <code>AutoCloseable<\/code>'\u0131 uygulayan bir s\u0131n\u0131f\u0131n <code>close()<\/code> metodunun herhangi bir istisna t\u00fcr\u00fcn\u00fc f\u0131rlatabilece\u011fi anlam\u0131na gelir. Bu esneklik, <code>AutoCloseable<\/code>'\u0131 I\/O kaynaklar\u0131 d\u0131\u015f\u0131ndaki daha geni\u015f bir kaynak yelpazesi i\u00e7in uygun hale getirir. \u00d6rne\u011fin, bir veritaban\u0131 ba\u011flant\u0131s\u0131, bir a\u011f soketi, bir thread havuzu veya \u00f6zel bir kaynak y\u00f6neticisi gibi her t\u00fcrl\u00fc \"kapat\u0131labilir\" kayna\u011f\u0131 temsil edebilir.<\/p>\n<p>\u0130\u015fte bu iki aray\u00fcz aras\u0131ndaki temel farklar\u0131 \u00f6zetleyen bir tablo:<\/p>\n<table>\n<thead>\n<tr>\n<th>Kavram<\/th>\n<th>A\u00e7\u0131klama<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>java.io.Closeable<\/code><\/td>\n<td>Java 5'te tan\u0131t\u0131ld\u0131. Genellikle I\/O kaynaklar\u0131 i\u00e7in kullan\u0131l\u0131r. <code>close()<\/code> metodu <code>IOException<\/code> f\u0131rlat\u0131r.<\/td>\n<\/tr>\n<tr>\n<td><code>java.lang.AutoCloseable<\/code><\/td>\n<td>Java 7'de tan\u0131t\u0131ld\u0131. Daha genel bir aray\u00fczd\u00fcr. <code>close()<\/code> metodu <code>Exception<\/code> f\u0131rlatabilir (daha genel bir istisna). <code>Closeable<\/code>, <code>AutoCloseable<\/code>'\u0131 extend eder.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><code>AutoCloseable<\/code>'\u0131n en b\u00fcy\u00fck avantaj\u0131, \"try-with-resources\" ifadesiyle birlikte kullan\u0131labilmesidir. Bu mekanizma, bir istisna f\u0131rlat\u0131lsa bile kaynaklar\u0131n her zaman otomatik olarak kapat\u0131lmas\u0131n\u0131 garanti eder. <code>Closeable<\/code> da \"try-with-resources\" ile kullan\u0131labilir \u00e7\u00fcnk\u00fc <code>AutoCloseable<\/code>'\u0131 extend eder, ancak <code>close()<\/code> metodunun f\u0131rlatt\u0131\u011f\u0131 istisna t\u00fcr\u00fc a\u00e7\u0131s\u0131ndan daha k\u0131s\u0131tl\u0131d\u0131r. Dolay\u0131s\u0131yla, bir kaynak kapat\u0131l\u0131rken <code>IOException<\/code> d\u0131\u015f\u0131nda ba\u015fka bir istisnan\u0131n f\u0131rlat\u0131lma olas\u0131l\u0131\u011f\u0131 varsa veya kayna\u011f\u0131n\u0131z bir I\/O kayna\u011f\u0131 de\u011filse, <code>AutoCloseable<\/code> kullanmak daha do\u011fru ve esnek bir tercihtir. Modern Android geli\u015ftirmesinde, genellikle <code>AutoCloseable<\/code>, kaynak temizli\u011fi i\u00e7in daha genel ve g\u00fc\u00e7l\u00fc bir se\u00e7enek olarak kar\u015f\u0131m\u0131za \u00e7\u0131kar.<\/p>\n<h2>ViewModel'larda AutoCloseable Kullan\u0131m\u0131: Ad\u0131m Ad\u0131m Rehber<\/h2>\n<p>ViewModel'lar i\u00e7inde <code>AutoCloseable<\/code> kullanman\u0131n amac\u0131, manuel <code>onCleared()<\/code> temizleme i\u015flemlerinin y\u00fck\u00fcn\u00fc hafifletmek ve kaynak y\u00f6netimini daha otomatik, g\u00fcvenli ve hatas\u0131z hale getirmektir. Bu b\u00f6l\u00fcmde, Jetpack ViewModel'lar\u0131nda <code>AutoCloseable<\/code>'\u0131 nas\u0131l kullanaca\u011f\u0131m\u0131z\u0131 ad\u0131m ad\u0131m inceleyece\u011fiz. Bu rehber, \u00f6zellikle Kotlin Coroutines ile \u00e7al\u0131\u015fan geli\u015ftiriciler i\u00e7in olduk\u00e7a faydal\u0131 olacakt\u0131r.<\/p>\n<p>\u0130lk olarak, Jetpack Lifecycle k\u00fct\u00fcphanesinin sundu\u011fu <code>androidx.lifecycle.ViewModel<\/code> s\u0131n\u0131f\u0131, <code>onCleared()<\/code> ad\u0131nda bir metod sunar. Bu metod, ViewModel'\u0131n art\u0131k kullan\u0131lmad\u0131\u011f\u0131 ve yok edilece\u011fi zaman \u00e7a\u011fr\u0131l\u0131r. Bizim hedefimiz, <code>AutoCloseable<\/code> nesnelerimizi bu <code>onCleared()<\/code> metodunu otomatik olarak \u00e7a\u011f\u0131racak bir mekanizmaya ba\u011flamakt\u0131r. Neyse ki, Jetpack ekibi bu ihtiyac\u0131 d\u00fc\u015f\u00fcnerek <code>androidx.lifecycle:lifecycle-viewmodel-ktx<\/code> k\u00fct\u00fcphanesine <code>AutoCloseable<\/code> entegrasyonu i\u00e7in harika bir \u00f6zellik eklemi\u015ftir.<\/p>\n<p><code>ViewModel<\/code> s\u0131n\u0131f\u0131n\u0131n bir yap\u0131c\u0131 metodu (constructor) bulunmaktad\u0131r ve bu yap\u0131c\u0131 metod, <code>vararg AutoCloseable<\/code> arg\u00fcman\u0131 alabilir. Bu sayede, <code>ViewModel<\/code> olu\u015fturulurken kendisine ge\u00e7irilen t\u00fcm <code>AutoCloseable<\/code> nesneleri, <code>ViewModel<\/code>'in ya\u015fam d\u00f6ng\u00fcs\u00fc sona erdi\u011finde (yani <code>onCleared()<\/code> \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda) otomatik olarak kapat\u0131l\u0131r. \u0130\u015fte bu, bellek s\u0131z\u0131nt\u0131lar\u0131n\u0131 \u00f6nlemenin ve kaynak temizli\u011fini otomatize etmenin sihirli yoludur.<\/p>\n<p>\u015eimdi bu s\u00fcreci ad\u0131m ad\u0131m inceleyelim:<\/p>\n<ol>\n<li>\n        <strong>Ba\u011f\u0131ml\u0131l\u0131\u011f\u0131 Ekleme:<\/strong> \u00d6ncelikle, projenizin <code>build.gradle (Module: app)<\/code> dosyas\u0131na gerekli k\u00fct\u00fcphane ba\u011f\u0131ml\u0131l\u0131\u011f\u0131n\u0131 eklemeniz gerekir:<\/p>\n<pre><code class=\"language-gradle\">\ndependencies {\n    \/\/ ViewModel KTX k\u00fct\u00fcphanesi\n    implementation \"androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2\" \/\/ Veya daha yeni versiyon\n    \/\/ Di\u011fer ba\u011f\u0131ml\u0131l\u0131klar...\n}\n        <\/pre>\n<p><\/code><br \/>\n        Bu k\u00fct\u00fcphane, <code>ViewModel<\/code>'in <code>AutoCloseable<\/code> entegrasyonu i\u00e7in gerekli uzant\u0131 fonksiyonlar\u0131n\u0131 ve yap\u0131lar\u0131 i\u00e7erir.\n    <\/li>\n<li>\n        <strong>Kendi AutoCloseable Kayna\u011f\u0131n\u0131z\u0131 Olu\u015fturma:<\/strong> Diyelim ki, bir veritaban\u0131 ba\u011flant\u0131s\u0131n\u0131 veya \u00f6zel bir ak\u0131\u015f kayna\u011f\u0131n\u0131 y\u00f6netmek istiyorsunuz. Bu kayna\u011f\u0131 temsil eden bir s\u0131n\u0131f olu\u015fturup <code>AutoCloseable<\/code> aray\u00fcz\u00fcn\u00fc uygulaman\u0131z gerekir.<\/p>\n<pre><code class=\"language-kotlin\">\nimport java.io.Closeable \/\/ Genellikle Closeable da AutoCloseable'\u0131 extend etti\u011fi i\u00e7in yeterlidir\n\nclass DatabaseConnection(private val dbName: String) : Closeable {\n    init {\n        println(\"[$dbName] Veritaban\u0131 ba\u011flant\u0131s\u0131 a\u00e7\u0131ld\u0131.\")\n        \/\/ Veritaban\u0131 ba\u011flant\u0131s\u0131n\u0131 burada kurun\n    }\n\n    fun executeQuery(query: String) {\n        println(\"[$dbName] Sorgu \u00e7al\u0131\u015ft\u0131r\u0131l\u0131yor: $query\")\n        \/\/ Sorgu \u00e7al\u0131\u015ft\u0131rma mant\u0131\u011f\u0131\n    }\n\n    override fun close() {\n        println(\"[$dbName] Veritaban\u0131 ba\u011flant\u0131s\u0131 kapat\u0131l\u0131yor.\")\n        \/\/ Veritaban\u0131 ba\u011flant\u0131s\u0131n\u0131 burada kapat\u0131n\n    }\n}\n        <\/pre>\n<p><\/code><br \/>\n        Yukar\u0131daki \u00f6rnekte <code>Closeable<\/code> kulland\u0131k, \u00e7\u00fcnk\u00fc <code>Closeable<\/code>, <code>AutoCloseable<\/code>'\u0131 extend eder ve bu ba\u011flamda da \u00e7al\u0131\u015f\u0131r. Ancak genel olarak, farkl\u0131 istisnalar f\u0131rlatabilen kaynaklar i\u00e7in <code>AutoCloseable<\/code> do\u011frudan kullan\u0131labilir.\n    <\/li>\n<li>\n        <strong>ViewModel \u0130\u00e7inde Kayna\u011f\u0131 Kullanma ve Kaydetme:<\/strong> \u015eimdi bu <code>DatabaseConnection<\/code> nesnesini <code>ViewModel<\/code> i\u00e7inde olu\u015ftural\u0131m ve <code>ViewModel<\/code>'a otomatik temizleme i\u00e7in kaydedelim.<\/p>\n<pre><code class=\"language-kotlin\">\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport java.io.Closeable\n\n\/\/ 1. Kendi AutoCloseable objemizi tan\u0131mlad\u0131k (yukar\u0131da DatabaseConnection)\n\n\/\/ 2. ViewModel'\u0131 bu AutoCloseable objelerle birlikte olu\u015fturma\nclass MyDataViewModel : ViewModel(\n    DatabaseConnection(\"UserDB\"), \/\/ AutoCloseable 1\n    DatabaseConnection(\"ProductDB\") \/\/ AutoCloseable 2\n) {\n    init {\n        println(\"MyDataViewModel olu\u015fturuldu.\")\n        viewModelScope.launch {\n            delay(2000) \/\/ 2 saniye beklet\n            println(\"ViewModel i\u00e7erisinde asenkron i\u015flem tamamland\u0131.\")\n        }\n    }\n\n    fun loadUserData() {\n        println(\"Kullan\u0131c\u0131 verileri y\u00fckleniyor...\")\n        \/\/ UserDB ba\u011flant\u0131s\u0131 \u00fczerinden veri \u00e7ekilebilir.\n        \/\/ Veritaban\u0131Connection nesnelerine do\u011frudan eri\u015femeyiz, sadece olu\u015fturulurken kaydettik.\n        \/\/ E\u011fer ViewModel i\u00e7inde do\u011frudan eri\u015fim gerekiyorsa, onu property olarak tutmal\u0131 ve onCleared'da manuel kapatmal\u0131yd\u0131k.\n        \/\/ Veya daha geli\u015fmi\u015f bir yap\u0131land\u0131rma ile bu m\u00fcmk\u00fcn olabilir.\n    }\n\n    override fun onCleared() {\n        super.onCleared()\n        \/\/ ViewModel'\u0131n yap\u0131c\u0131 metoduna ge\u00e7irilen AutoCloseable'lar otomatik olarak burada \u00e7a\u011fr\u0131l\u0131r.\n        println(\"MyDataViewModel temizleniyor.\")\n    }\n}\n        <\/pre>\n<p><\/code><br \/>\n        Bu \u00f6rnekte, <code>MyDataViewModel<\/code>'\u0131n yap\u0131c\u0131 metoduna do\u011frudan iki adet <code>DatabaseConnection<\/code> nesnesi ge\u00e7irdik. <code>ViewModel<\/code> ya\u015fam d\u00f6ng\u00fcs\u00fc sona erdi\u011finde, bu iki ba\u011flant\u0131n\u0131n <code>close()<\/code> metotlar\u0131 otomatik olarak \u00e7a\u011fr\u0131lacakt\u0131r. Bu, geli\u015ftiricinin her bir ba\u011flant\u0131 i\u00e7in <code>onCleared()<\/code> i\u00e7inde manuel olarak <code>connection.close()<\/code> yazma ihtiyac\u0131n\u0131 ortadan kald\u0131r\u0131r. Bu yakla\u015f\u0131m, kodun daha temiz, daha g\u00fcvenli ve daha s\u00fcrd\u00fcr\u00fclebilir olmas\u0131n\u0131 sa\u011flar. Ayr\u0131ca, kaynak ekleme veya \u00e7\u0131karma durumlar\u0131nda <code>onCleared()<\/code> metodunu manuel olarak g\u00fcncelleme ihtiyac\u0131 da ortadan kalkar, bu da hata yapma olas\u0131l\u0131\u011f\u0131n\u0131 b\u00fcy\u00fck \u00f6l\u00e7\u00fcde azalt\u0131r.<\/p>\n<p>Bu y\u00f6ntem, \u00f6zellikle birden fazla <code>AutoCloseable<\/code> kayna\u011f\u0131 y\u00f6netmeniz gerekti\u011finde b\u00fcy\u00fck kolayl\u0131k sa\u011flar. Art\u0131k <code>ViewModel<\/code>'lar\u0131n\u0131zdaki kaynak temizli\u011fi i\u00e7in endi\u015felenmenize gerek kalmayacak, sistem bunu sizin i\u00e7in halledecek.<\/p>\n<h2>Pratik Bir \u00d6rnek: Veritaban\u0131 Ba\u011flant\u0131s\u0131 ve A\u011f \u0130ste\u011fi Y\u00f6netimi<\/h2>\n<p>Yukar\u0131daki teorik bilgileri prati\u011fe d\u00f6kelim ve ger\u00e7ek d\u00fcnya senaryolar\u0131nda <code>AutoCloseable<\/code>'\u0131n <code>ViewModel<\/code>'lar i\u00e7inde nas\u0131l kullan\u0131labilece\u011fini g\u00f6sterelim. \u00d6zellikle veritaban\u0131 ba\u011flant\u0131lar\u0131 ve uzun s\u00fcreli a\u011f istekleri gibi kaynaklar, <code>ViewModel<\/code> ya\u015fam d\u00f6ng\u00fcs\u00fc sona erdi\u011finde d\u00fczg\u00fcn bir \u015fekilde kapat\u0131lmazsa ciddi bellek s\u0131z\u0131nt\u0131lar\u0131na yol a\u00e7abilir. \u0130\u015fte bu sorunu \u00e7\u00f6zmek i\u00e7in <code>AutoCloseable<\/code>'\u0131 kullanarak daha sa\u011flam bir yakla\u015f\u0131m sunan kapsaml\u0131 bir \u00f6rnek.<\/p>\n<p>\u0130lk olarak, veritaban\u0131 ba\u011flant\u0131m\u0131z\u0131 temsil eden bir <code>AutoCloseable<\/code> s\u0131n\u0131f olu\u015ftural\u0131m. Bu s\u0131n\u0131f, bir sim\u00fclasyon amac\u0131yla basit bir ba\u011flant\u0131 a\u00e7ma ve kapatma i\u015flemi yapacakt\u0131r.<\/p>\n<pre><code class=\"language-kotlin\">\nimport java.io.Closeable\n\n\/\/ Veritaban\u0131 ba\u011flant\u0131s\u0131n\u0131 temsil eden AutoCloseable s\u0131n\u0131f\nclass DbManager(private val dbName: String) : Closeable {\n    private var isConnected: Boolean = false\n\n    init {\n        connect()\n    }\n\n    private fun connect() {\n        println(\"[$dbName] Veritaban\u0131 ba\u011flant\u0131s\u0131 ba\u015flat\u0131l\u0131yor...\")\n        Thread.sleep(500) \/\/ Ba\u011flant\u0131 kurma sim\u00fclasyonu\n        isConnected = true\n        println(\"[$dbName] Veritaban\u0131 ba\u011flant\u0131s\u0131 ba\u015far\u0131l\u0131.\")\n    }\n\n    fun queryData(tableName: String): List<String> {\n        if (!isConnected) {\n            println(\"[$dbName] Hata: Veritaban\u0131 ba\u011fl\u0131 de\u011fil.\")\n            return emptyList()\n        }\n        println(\"[$dbName] '$tableName' tablosundan veri sorgulan\u0131yor.\")\n        return listOf(\"data_item_1\", \"data_item_2\") \/\/ Sahte veri\n    }\n\n    override fun close() {\n        if (isConnected) {\n            println(\"[$dbName] Veritaban\u0131 ba\u011flant\u0131s\u0131 kapat\u0131l\u0131yor...\")\n            Thread.sleep(200) \/\/ Kapatma sim\u00fclasyonu\n            isConnected = false\n            println(\"[$dbName] Veritaban\u0131 ba\u011flant\u0131s\u0131 kapat\u0131ld\u0131.\")\n        }\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>\u015eimdi de, bir a\u011f iste\u011fini veya uzun s\u00fcreli bir soket ba\u011flant\u0131s\u0131n\u0131 temsil eden ba\u015fka bir <code>AutoCloseable<\/code> s\u0131n\u0131f olu\u015ftural\u0131m. Bu, genellikle <code>Retrofit<\/code> veya <code>OkHttp<\/code> gibi k\u00fct\u00fcphanelerle y\u00f6netilen ancak kendi manuel kaynak temizli\u011fine ihtiya\u00e7 duyan durumlar\u0131 sim\u00fcle edebilir.<\/p>\n<pre><code class=\"language-kotlin\">\nimport java.io.Closeable\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport androidx.lifecycle.viewModelScope \/\/ Bu s\u0131n\u0131f ViewModel d\u0131\u015f\u0131nda kullan\u0131lamaz, \u00f6rnek i\u00e7in buraya ta\u015f\u0131d\u0131k.\nimport androidx.lifecycle.ViewModel\n\n\/\/ A\u011f iste\u011fini veya bir ak\u0131\u015f\u0131 temsil eden AutoCloseable s\u0131n\u0131f\nclass NetworkClient(private val endpoint: String, private val coroutineScope: ViewModel) : Closeable {\n    private var activeJob: Job? = null\n    private var isConnected: Boolean = false\n\n    init {\n        connect()\n    }\n\n    private fun connect() {\n        println(\"[NetworkClient:$endpoint] A\u011f ba\u011flant\u0131s\u0131 kuruluyor...\")\n        \/\/ Ger\u00e7ekte burada bir soket veya WebRTC ba\u011flant\u0131s\u0131 kurulabilir.\n        \/\/ Veya belirli bir API i\u00e7in uzun \u00f6m\u00fcrl\u00fc bir client ba\u015flat\u0131labilir.\n        isConnected = true\n        println(\"[NetworkClient:$endpoint] A\u011f ba\u011flant\u0131s\u0131 ba\u015far\u0131l\u0131.\")\n    }\n\n    fun fetchData(): String {\n        if (!isConnected) {\n            println(\"[NetworkClient:$endpoint] Hata: A\u011f istemcisi ba\u011fl\u0131 de\u011fil.\")\n            return \"Error\"\n        }\n        println(\"[NetworkClient:$endpoint] Veri \u00e7ekiliyor...\")\n        \/\/ Ger\u00e7ek bir a\u011f iste\u011fi veya uzun s\u00fcreli veri ak\u0131\u015f\u0131 burada ba\u015flat\u0131labilir.\n        return \"Received data from $endpoint\"\n    }\n\n    \/\/ Bu metod ViewModel'\u0131n yap\u0131c\u0131 metoduna ge\u00e7ilemedi\u011fi i\u00e7in\n    \/\/ ViewModelScope d\u0131\u015f\u0131ndaki bir AutoCloseable'\u0131 \u00f6rneklendirmek i\u00e7in kulland\u0131k.\n    \/\/ Ger\u00e7ekte NetworkClient i\u00e7inde do\u011frudan bir CoroutineScope referans\u0131 tutmak yerine,\n    \/\/ gelen Scope \u00fczerinde Job olu\u015fturmak daha iyi bir yakla\u015f\u0131md\u0131r.\n    \/\/ Ancak burada ViewModel yap\u0131c\u0131 metoduna ge\u00e7i\u015fi g\u00f6stermek ad\u0131na basit tutuldu.\n    fun startLongRunningTask() {\n        activeJob = (coroutineScope as ViewModel).viewModelScope.launch { \/\/ CoroutineScope almak yerine ViewModel referans\u0131yla viewModelScope'a eri\u015fildi.\n            println(\"[NetworkClient:$endpoint] Uzun s\u00fcreli g\u00f6rev ba\u015flat\u0131ld\u0131.\")\n            delay(5000) \/\/ Uzun s\u00fcreli bir i\u015flem sim\u00fclasyonu\n            println(\"[NetworkClient:$endpoint] Uzun s\u00fcreli g\u00f6rev tamamland\u0131.\")\n        }\n    }\n\n    override fun close() {\n        if (isConnected) {\n            println(\"[NetworkClient:$endpoint] A\u011f ba\u011flant\u0131s\u0131 kapat\u0131l\u0131yor...\")\n            activeJob?.cancel() \/\/ Devam eden bir coroutine varsa iptal et\n            isConnected = false\n            println(\"[NetworkClient:$endpoint] A\u011f ba\u011flant\u0131s\u0131 kapat\u0131ld\u0131.\")\n        }\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>\u015eimdi bu iki <code>AutoCloseable<\/code> kayna\u011f\u0131n\u0131 bir <code>ViewModel<\/code> i\u00e7inde nas\u0131l kullanaca\u011f\u0131m\u0131z\u0131 g\u00f6relim:<\/p>\n<pre><code class=\"language-kotlin\">\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport kotlinx.coroutines.launch\nimport java.io.Closeable\n\nclass DashboardViewModel : ViewModel(\n    DbManager(\"AnalyticsDB\"), \/\/ AutoCloseable veritaban\u0131 y\u00f6neticisi\n    DbManager(\"UserPreferencesDB\") \/\/ Ba\u015fka bir AutoCloseable veritaban\u0131 y\u00f6neticisi\n    \/\/ NetworkClient gibi bir objeyi de buraya ge\u00e7irebiliriz\n    \/\/ Ancak NetworkClient, ViewModel'\u0131n kendisini parametre olarak ald\u0131\u011f\u0131 i\u00e7in\n    \/\/ (viewModelScope'a eri\u015fim i\u00e7in) bu do\u011frudan burada yap\u0131lamaz.\n    \/\/ Bunun yerine, ViewModel i\u00e7inde olu\u015fturup onCleared'da manuel kapatma ya da\n    \/\/ daha geli\u015fmi\u015f bir dependency injection (ba\u011f\u0131ml\u0131l\u0131k enjeksiyonu) yakla\u015f\u0131m\u0131 gerekir.\n    \/\/ Bu \u00f6rnekte, sadece DbManager'lar\u0131 ViewModel yap\u0131c\u0131 metoduna ge\u00e7iriyoruz.\n) {\n    \/\/ E\u011fer NetworkClient gibi bir objenin ViewModel i\u00e7inde do\u011frudan eri\u015filebilir olmas\u0131 gerekiyorsa,\n    \/\/ onu bir property olarak tan\u0131mlamal\u0131y\u0131z. Bu durumda, onCleared'da manuel olarak kapat\u0131lmal\u0131d\u0131r.\n    \/\/ Veya, NetworkClient'\u0131 ViewModel d\u0131\u015f\u0131ndan al\u0131p, kendi i\u00e7inde sadece bir Job ba\u015flatmas\u0131n\u0131 sa\u011flayabiliriz.\n    private val apiService = NetworkClient(\"api.example.com\", this) \/\/ ViewModel'\u0131n kendisini scope olarak verdik\n\n    init {\n        println(\"DashboardViewModel olu\u015fturuldu.\")\n        \/\/ ViewModelScope i\u00e7indeki coroutine'ler otomatik olarak ViewModel temizlendi\u011finde iptal edilir.\n        viewModelScope.launch {\n            println(\"ViewModelScope'ta ba\u015flang\u0131\u00e7 g\u00f6revi ba\u015flat\u0131ld\u0131.\")\n            apiService.startLongRunningTask() \/\/ A\u011f istemcisini kullanarak uzun s\u00fcreli bir g\u00f6rev ba\u015flat\n            println(\"A\u011f istemcisi ba\u015flat\u0131ld\u0131.\")\n\n            \/\/ DbManager'lar yap\u0131c\u0131da kaydedildi\u011fi i\u00e7in burada do\u011frudan eri\u015filemezler.\n            \/\/ E\u011fer eri\u015fim gerekiyorsa, ViewModel i\u00e7inde bir property olarak tan\u0131mlanmal\u0131 ve\n            \/\/ onCleared'da manuel kapat\u0131lmal\u0131d\u0131r. Veya Factory deseni ile enjekte edilmelidir.\n            \/\/ \u00d6rnek:\n            \/\/ val userDbManager = DbManager(\"UserDB\")\n            \/\/ bu durumda 'this' ile birlikte userDbManager'\u0131 da ViewModel'\u0131n yap\u0131c\u0131 metoduna ge\u00e7iremezdik.\n            \/\/ Kaynaklara ViewModel i\u00e7inde eri\u015fim gerekiyorsa (ki genellikle gereklidir),\n            \/\/ onlar\u0131 ViewModel'\u0131n property'si olarak tan\u0131mlay\u0131p manuel onCleared'da kapatmak hala ge\u00e7erli bir y\u00f6ntemdir.\n            \/\/ Otomatik AutoCloseable mekanizmas\u0131, ViewModel'\u0131n d\u0131\u015f\u0131nda olu\u015fturulan ve sadece temizlenmesi gereken\n            \/\/ kaynaklar i\u00e7in daha uygundur.\n        }\n    }\n\n    fun loadDashboardData() {\n        println(\"G\u00f6sterge paneli verileri y\u00fckleniyor...\")\n        \/\/ apiService.fetchData() \u00e7a\u011fr\u0131labilir\n        \/\/ DbManager'lardan sorgu \u00e7ekilebilir (e\u011fer property olarak tan\u0131mlanm\u0131\u015flarsa)\n    }\n\n    override fun onCleared() {\n        super.onCleared()\n        \/\/ ViewModel'\u0131n yap\u0131c\u0131 metoduna ge\u00e7irilen DbManager'lar otomatik olarak kapat\u0131l\u0131r.\n        \/\/ Manuel olarak property olarak tan\u0131mlanan apiService'i de burada kapatmal\u0131y\u0131z.\n        apiService.close()\n        println(\"DashboardViewModel temizleniyor ve t\u00fcm kaynaklar kapat\u0131ld\u0131.\")\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>DashboardViewModel<\/code>'in yap\u0131c\u0131 metoduna iki adet <code>DbManager<\/code> nesnesi do\u011frudan ge\u00e7iriliyor. Bu <code>DbManager<\/code>'lar, <code>ViewModel<\/code> ya\u015fam d\u00f6ng\u00fcs\u00fc sona erdi\u011finde otomatik olarak kapat\u0131lacak. <code>NetworkClient<\/code> ise <code>ViewModel<\/code> i\u00e7inde bir property olarak tan\u0131mland\u0131 ve <code>onCleared()<\/code> metodunda manuel olarak kapat\u0131l\u0131yor. Bu durum, bize \u00f6nemli bir bak\u0131\u015f a\u00e7\u0131s\u0131 sunar:<\/p>\n<ul>\n<li>E\u011fer bir <code>AutoCloseable<\/code> nesnesine <code>ViewModel<\/code> i\u00e7inde do\u011frudan eri\u015fiminiz gerekmiyorsa ve sadece ya\u015fam d\u00f6ng\u00fcs\u00fc sonunda temizlenmesini istiyorsan\u0131z, onu <code>ViewModel<\/code>'\u0131n yap\u0131c\u0131 metoduna ge\u00e7irmek en temiz yoldur.<\/li>\n<li>E\u011fer <code>AutoCloseable<\/code> bir nesneye <code>ViewModel<\/code> i\u00e7inde eri\u015fiminiz gerekiyorsa (t\u0131pk\u0131 <code>apiService<\/code> \u00f6rne\u011finde oldu\u011fu gibi), onu bir property olarak tan\u0131mlaman\u0131z ve <code>onCleared()<\/code> metodunda manuel olarak kapatman\u0131z gerekebilir. Veya daha geli\u015fmi\u015f ba\u011f\u0131ml\u0131l\u0131k enjeksiyonu (DI) \u00e7\u00f6z\u00fcmleriyle bu durumu farkl\u0131 y\u00f6netebilirsiniz.<\/li>\n<\/ul>\n<p>Bu pratik \u00f6rnek, <code>AutoCloseable<\/code>'\u0131n kaynak temizli\u011fini nas\u0131l basitle\u015ftirdi\u011fini ve <code>ViewModel<\/code>'lar\u0131n\u0131z\u0131n bellek s\u0131z\u0131nt\u0131lar\u0131na kar\u015f\u0131 nas\u0131l daha diren\u00e7li hale getirilebilece\u011fini a\u00e7\u0131k\u00e7a g\u00f6stermektedir. Bu y\u00f6ntemleri uygulayarak, Android uygulaman\u0131z\u0131n performans\u0131n\u0131 ve kararl\u0131l\u0131\u011f\u0131n\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131rabilirsiniz.<\/p>\n<h2>Daha Temiz Kod \u0130\u00e7in androidx.lifecycle.viewModelScope Kullan\u0131m\u0131<\/h2>\n<p>Modern Android geli\u015ftirmesinde, asenkron i\u015flemler ve e\u015fzamanl\u0131l\u0131k y\u00f6netimi, performansl\u0131 ve duyarl\u0131 uygulamalar olu\u015fturman\u0131n temelini olu\u015fturur. Kotlin Coroutines, bu alanda geli\u015ftiricilere g\u00fc\u00e7l\u00fc ve esnek bir ara\u00e7 sunar. Jetpack ise Coroutines ile uyumlu \u00e7al\u0131\u015facak \u015fekilde tasarlanm\u0131\u015f <code>viewModelScope<\/code> gibi uzant\u0131lar sunarak, ViewModel'lardaki asenkron g\u00f6rev y\u00f6netimini \u00e7ok daha kolay ve g\u00fcvenli hale getirmi\u015ftir.<\/p>\n<p><code>androidx.lifecycle.viewModelScope<\/code>, <code>ViewModel<\/code>'\u0131n\u0131za ba\u011fl\u0131 \u00f6zel bir <code>CoroutineScope<\/code>'tur. Bu kapsamda ba\u015flat\u0131lan t\u00fcm coroutine'ler, <code>ViewModel<\/code> temizlendi\u011finde (yani <code>onCleared()<\/code> metodu \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda) otomatik olarak iptal edilir. Bu \u00f6zellik, bellek s\u0131z\u0131nt\u0131lar\u0131n\u0131 \u00f6nlemek ve gereksiz kaynak t\u00fcketimini durdurmak a\u00e7\u0131s\u0131ndan son derece \u00f6nemlidir. Daha \u00f6nceki manuel <code>Job<\/code> y\u00f6netimi, <code>Disposable<\/code> iptali gibi karma\u015f\u0131k i\u015flemleri b\u00fcy\u00fck \u00f6l\u00e7\u00fcde basitle\u015ftirir ve kodu daha temiz hale getirir.<\/p>\n<h3><code>viewModelScope<\/code> Neden \u00d6nemlidir?<\/h3>\n<ol>\n<li>\n        <strong>Otomatik \u0130ptal:<\/strong> <code>viewModelScope<\/code> i\u00e7inde ba\u015flat\u0131lan coroutine'ler, <code>ViewModel<\/code> ya\u015fam d\u00f6ng\u00fcs\u00fc sona erdi\u011finde otomatik olarak iptal edilir. Bu, manuel olarak <code>Job.cancel()<\/code> \u00e7a\u011f\u0131rma ihtiyac\u0131n\u0131 ortadan kald\u0131r\u0131r.\n    <\/li>\n<li>\n        <strong>Bellek S\u0131z\u0131nt\u0131lar\u0131n\u0131 \u00d6nleme:<\/strong> Uzun s\u00fcreli \u00e7al\u0131\u015fan bir coroutine, <code>ViewModel<\/code> yok edildikten sonra bile \u00e7al\u0131\u015fmaya devam ederse, UI bile\u015fenlerine veya di\u011fer ya\u015fam d\u00f6ng\u00fcs\u00fcne ba\u011fl\u0131 nesnelere referans tutarak bellek s\u0131z\u0131nt\u0131lar\u0131na neden olabilir. <code>viewModelScope<\/code> bu riski ortadan kald\u0131r\u0131r.\n    <\/li>\n<li>\n        <strong>Daha Temiz Kod:<\/strong> Manuel <code>Job<\/code> y\u00f6netimi veya <code>Disposable<\/code> havuzlar\u0131 gibi boilerplate kodlar\u0131n \u00f6n\u00fcne ge\u00e7erek daha okunakl\u0131 ve s\u00fcrd\u00fcr\u00fclebilir bir kod yazman\u0131z\u0131 sa\u011flar.\n    <\/li>\n<li>\n        <strong>Entegre Ya\u015fam D\u00f6ng\u00fcs\u00fc Y\u00f6netimi:<\/strong> Jetpack Lifecycle k\u00fct\u00fcphanesi ile tamamen entegredir, bu da Android'in ya\u015fam d\u00f6ng\u00fcs\u00fc felsefesiyle uyumlu bir geli\u015ftirme deneyimi sunar.\n    <\/li>\n<\/ol>\n<h3><code>viewModelScope<\/code> Nas\u0131l Kullan\u0131l\u0131r?<\/h3>\n<p>Kullan\u0131m\u0131 olduk\u00e7a basittir. <code>ViewModel<\/code> s\u0131n\u0131f\u0131n\u0131z\u0131n herhangi bir metodunda veya <code>init<\/code> blo\u011funda do\u011frudan <code>viewModelScope.launch { ... }<\/code> veya <code>viewModelScope.async { ... }<\/code> ifadelerini kullanabilirsiniz.<\/p>\n<pre><code class=\"language-kotlin\">\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\nclass DataFetcherViewModel : ViewModel() {\n\n    init {\n        println(\"DataFetcherViewModel olu\u015fturuldu.\")\n        \/\/ ViewModel olu\u015fturulur olu\u015fturulmaz bir veri \u00e7ekme i\u015flemi ba\u015flat\u0131labilir.\n        \/\/ Bu coroutine, ViewModel temizlendi\u011finde otomatik olarak iptal edilecek.\n        viewModelScope.launch {\n            fetchInitialData()\n        }\n    }\n\n    suspend fun fetchInitialData() {\n        println(\"Ba\u015flang\u0131\u00e7 verileri \u00e7ekiliyor... (viewModelScope i\u00e7inde)\")\n        try {\n            delay(3000) \/\/ A\u011f iste\u011fi veya yo\u011fun bir i\u015flem sim\u00fclasyonu\n            println(\"Ba\u015flang\u0131\u00e7 verileri ba\u015far\u0131yla \u00e7ekildi.\")\n        } catch (e: Exception) {\n            println(\"Veri \u00e7ekme s\u0131ras\u0131nda hata olu\u015ftu: ${e.message}\")\n        }\n    }\n\n    fun refreshData() {\n        viewModelScope.launch {\n            println(\"Veriler yenileniyor... (viewModelScope i\u00e7inde)\")\n            try {\n                delay(2000) \/\/ Daha k\u0131sa bir yenileme s\u00fcresi\n                println(\"Veriler ba\u015far\u0131yla yenilendi.\")\n            } catch (e: Exception) {\n                println(\"Veri yenileme s\u0131ras\u0131nda hata olu\u015ftu: ${e.message}\")\n            }\n        }\n    }\n\n    override fun onCleared() {\n        super.onCleared()\n        \/\/ ViewModelScope i\u00e7indeki t\u00fcm coroutine'ler burada otomatik olarak iptal edilir.\n        println(\"DataFetcherViewModel temizlendi. T\u00fcm viewModelScope coroutine'leri iptal edildi.\")\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>DataFetcherViewModel<\/code> i\u00e7inde ba\u015flat\u0131lan t\u00fcm asenkron i\u015flemler <code>viewModelScope<\/code> kullan\u0131larak y\u00f6netilir. <code>ViewModel<\/code> art\u0131k ihtiya\u00e7 duyulmad\u0131\u011f\u0131nda ve <code>onCleared()<\/code> metodu \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda, <code>viewModelScope<\/code> i\u00e7indeki t\u00fcm coroutine'ler otomatik olarak iptal edilir. Bu, uygulaman\u0131z\u0131n gereksiz i\u015flem yapmas\u0131n\u0131 engeller ve bellek s\u0131z\u0131nt\u0131s\u0131 riskini minimize eder. <code>AutoCloseable<\/code> ile birlikte kullan\u0131ld\u0131\u011f\u0131nda ise, hem senkron kaynaklar\u0131n hem de asenkron i\u015flemlerin temizli\u011fi \u00e7ok daha d\u00fczenli ve g\u00fcvenli hale gelir. K\u0131sacas\u0131, <code>viewModelScope<\/code>, ViewModel'lar\u0131n\u0131zda Coroutines kullan\u0131rken kaynak temizli\u011fini d\u00fc\u015f\u00fcnmenize gerek kalmayan, geli\u015ftirici dostu bir \u00e7\u00f6z\u00fcmd\u00fcr.<\/p>\n<h2>\u0130leri D\u00fczey Uygulamalar ve Yayg\u0131n Hatalardan Ka\u00e7\u0131nma Yollar\u0131<\/h2>\n<p><code>AutoCloseable<\/code> ve <code>viewModelScope<\/code> kullanarak kaynak y\u00f6netimini otomatikle\u015ftirmek, modern Android uygulamalar\u0131nda \u00f6nemli bir ad\u0131md\u0131r. Ancak, bu ara\u00e7lar\u0131 en verimli \u015fekilde kullanmak ve yayg\u0131n hatalardan ka\u00e7\u0131nmak i\u00e7in baz\u0131 ileri d\u00fczey uygulamalar\u0131 ve dikkat edilmesi gereken noktalar\u0131 bilmek gerekir. Bu b\u00f6l\u00fcm, daha karma\u015f\u0131k senaryolar\u0131 ele al\u0131rken kar\u015f\u0131la\u015fabilece\u011finiz zorluklar\u0131 a\u015fman\u0131za yard\u0131mc\u0131 olacak ipu\u00e7lar\u0131 sunmaktad\u0131r.<\/p>\n<h3>Dependency Injection (DI) ile AutoCloseable Kaynaklar\u0131 Y\u00f6netme<\/h3>\n<p>B\u00fcy\u00fck projelerde, ViewModel'lar\u0131n do\u011frudan <code>AutoCloseable<\/code> nesnelerini olu\u015fturmas\u0131 yerine, bunlar\u0131 ba\u011f\u0131ml\u0131l\u0131k enjeksiyonu (DI) framework'leri (\u00f6rne\u011fin Hilt, Koin, Dagger) arac\u0131l\u0131\u011f\u0131yla almas\u0131 daha yayg\u0131n ve tercih edilen bir y\u00f6ntemdir. Bu sayede, test edilebilirlik artar ve sorumluluklar daha net ayr\u0131l\u0131r.<\/p>\n<p>Peki, DI ile enjekte edilen <code>AutoCloseable<\/code> bir kayna\u011f\u0131 ViewModel'\u0131n ya\u015fam d\u00f6ng\u00fcs\u00fcne nas\u0131l ba\u011flar\u0131z? \u0130\u015fte burada <code>androidx.lifecycle.CloseableViewModel<\/code> veya <code>AutoCloseable<\/code> mekanizmas\u0131 devreye girer. Hilt gibi framework'ler, <code>@ViewModelScoped<\/code> anotasyonunu kullanarak bir ba\u011f\u0131ml\u0131l\u0131\u011f\u0131n ViewModel'\u0131n ya\u015fam d\u00f6ng\u00fcs\u00fcyle s\u0131n\u0131rl\u0131 olmas\u0131n\u0131 sa\u011flayabilir. E\u011fer ba\u011f\u0131ml\u0131l\u0131\u011f\u0131n\u0131z <code>AutoCloseable<\/code> ise, Hilt gibi framework'ler bu kayna\u011f\u0131n temizli\u011fini otomatik olarak y\u00f6netmeye yard\u0131mc\u0131 olabilir. Ancak, bu her zaman do\u011frudan bir entegrasyon olmayabilir ve yine de <code>ViewModel<\/code>'in yap\u0131c\u0131 metoduna ge\u00e7i\u015f veya <code>onCleared()<\/code> i\u00e7inde manuel kapatma gerekebilir.<\/p>\n<pre><code class=\"language-kotlin\">\n\/\/ \u00d6rnek: Hilt ile enjekte edilen bir DatabaseManager'\u0131n AutoCloseable olmas\u0131\n@Module\n@InstallIn(ViewModelComponent::class)\nobject DatabaseModule {\n    @Provides\n    @ViewModelScoped \/\/ Bu mod\u00fcl\u00fcn ViewModel ya\u015fam d\u00f6ng\u00fcs\u00fcyle s\u0131n\u0131rl\u0131 oldu\u011funu belirtir\n    fun provideDatabaseManager(@ApplicationContext context: Context): DbManager {\n        return DbManager(\"AppDB\") \/\/ DbManager, Closeable\/AutoCloseable oldu\u011fu i\u00e7in\n                                  \/\/ ViewModelComponent sona erdi\u011finde otomatik kapanmas\u0131 beklenebilir.\n                                  \/\/ Ancak, Hilt do\u011frudan AutoCloseable'\u0131 otomatik kapatmaz.\n                                  \/\/ ViewModel'\u0131n yap\u0131c\u0131 metoduna ge\u00e7mek daha g\u00fcvenli bir yakla\u015f\u0131md\u0131r.\n    }\n}\n\n\/\/ ViewModel'\u0131n bu manager'\u0131 almas\u0131\nclass AdvancedDataViewModel @Inject constructor(\n    private val dbManager: DbManager \/\/ Hilt taraf\u0131ndan sa\u011flan\u0131r\n) : ViewModel(dbManager) { \/\/ dbManager'\u0131 ViewModel'\u0131n yap\u0131c\u0131 metoduna ge\u00e7irdik\n\n    init {\n        println(\"AdvancedDataViewModel olu\u015fturuldu.\")\n        dbManager.queryData(\"Users\")\n    }\n    \/\/ ... di\u011fer i\u015flemler\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>dbManager<\/code>'\u0131 <code>ViewModel<\/code>'\u0131n yap\u0131c\u0131 metoduna ge\u00e7irerek, <code>ViewModel<\/code>'\u0131n <code>onCleared()<\/code> metodu \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda otomatik olarak temizlenmesini sa\u011flad\u0131k. Bu, DI ile <code>AutoCloseable<\/code> kaynaklar\u0131n\u0131 y\u00f6netirken en g\u00fcvenli ve \u00f6nerilen yoldur.<\/p>\n<h3>Yayg\u0131n Hatalardan Ka\u00e7\u0131nma Yollar\u0131<\/h3>\n<ol>\n<li>\n        <strong><code>AutoCloseable<\/code> Olmayan Kaynaklar\u0131 Unutmay\u0131n:<\/strong> Sadece <code>AutoCloseable<\/code> aray\u00fcz\u00fcn\u00fc uygulayan nesneler otomatik olarak temizlenir. E\u011fer \u00f6zel bir kayna\u011f\u0131n\u0131z varsa ve <code>AutoCloseable<\/code>'\u0131 uygulam\u0131yorsa, <code>onCleared()<\/code> metodunda manuel olarak temizlemeyi unutmay\u0131n. \u00d6rne\u011fin, RxJava <code>Disposable<\/code>'lar veya kendi \u00f6zel kaynaklar\u0131n\u0131z.\n    <\/li>\n<li>\n        <strong>Do\u011fru Kapsam\u0131 Se\u00e7in:<\/strong> <code>viewModelScope<\/code>, ViewModel'\u0131n ya\u015fam d\u00f6ng\u00fcs\u00fcyle s\u0131n\u0131rl\u0131d\u0131r. E\u011fer bir g\u00f6revin ViewModel ya\u015fam d\u00f6ng\u00fcs\u00fcnden daha uzun s\u00fcrmesi gerekiyorsa (\u00f6rne\u011fin arka planda bir dosya indirme), bunun i\u00e7in farkl\u0131 bir <code>CoroutineScope<\/code> (\u00f6rne\u011fin <code>applicationScope<\/code>) kullanmal\u0131s\u0131n\u0131z. Ancak bu durumda, kaynak temizli\u011fini manuel olarak y\u00f6netmeniz gerekecektir.\n    <\/li>\n<li>\n        <strong>Kaynaklar\u0131 Erken Kapatmay\u0131n:<\/strong> Bir <code>AutoCloseable<\/code> kayna\u011f\u0131 \u00e7ok erken kapatmak, uygulaman\u0131zda \u00e7al\u0131\u015fma zaman\u0131 hatalar\u0131na yol a\u00e7abilir. Kayna\u011f\u0131n sadece i\u015fi bitti\u011finde veya ilgili ViewModel yok edildi\u011finde kapat\u0131ld\u0131\u011f\u0131ndan emin olun.\n    <\/li>\n<li>\n        <strong>\u0130stisna Y\u00f6netimi:<\/strong> <code>AutoCloseable.close()<\/code> metodu bir <code>Exception<\/code> f\u0131rlatabilir. Kaynaklar\u0131 kapat\u0131rken olas\u0131 istisnalar\u0131 ele almay\u0131 unutmay\u0131n, aksi takdirde uygulaman\u0131z beklenmedik \u015fekilde \u00e7\u00f6kebilir. Genellikle, kaynak kapatma hatalar\u0131 loglan\u0131r ancak uygulaman\u0131n \u00e7\u00f6kmesine izin verilmez.<\/p>\n<pre><code class=\"language-kotlin\">\noverride fun close() {\n    try {\n        \/\/ Kayna\u011f\u0131 kapatma mant\u0131\u011f\u0131\n    } catch (e: Exception) {\n        println(\"Kayna\u011f\u0131 kapat\u0131rken hata olu\u015ftu: ${e.message}\")\n        \/\/ Hata loglama veya bildirim\n    }\n}\n        <\/pre>\n<p><\/code>\n    <\/li>\n<li>\n        <strong>Test Edilebilirlik:<\/strong> Kaynak y\u00f6netimi mant\u0131\u011f\u0131n\u0131z\u0131 unit testler ile do\u011frulamak, hatalar\u0131 erken a\u015famada tespit etmenin en iyi yoludur. ViewModel'\u0131n <code>onCleared()<\/code> metodunu \u00e7a\u011f\u0131rarak ve AutoCloseable kaynaklar\u0131n\u0131z\u0131n <code>close()<\/code> metodunun \u00e7a\u011fr\u0131l\u0131p \u00e7a\u011fr\u0131lmad\u0131\u011f\u0131n\u0131 kontrol ederek testler yaz\u0131n.<\/li>\n<\/ol>\n<blockquote><p>\n  Uzman \u0130pucu: Karma\u015f\u0131k durumlarda, bir <code>CompositeCloseable<\/code> s\u0131n\u0131f\u0131 olu\u015fturarak birden fazla <code>AutoCloseable<\/code> nesnesini tek bir birim olarak y\u00f6netebilirsiniz. Bu, <code>onCleared()<\/code> i\u00e7inde daha az boilerplate kod yazman\u0131z\u0131 sa\u011flar ve kodu daha okunakl\u0131 hale getirir.\n<\/p><\/blockquote>\n<p>Bu ileri d\u00fczey uygulamalar ve dikkat edilmesi gereken noktalar, <code>AutoCloseable<\/code> ve <code>viewModelScope<\/code> kullan\u0131m\u0131n\u0131z\u0131 daha sa\u011flam ve hatas\u0131z hale getirecektir. Unutmay\u0131n, iyi bir kaynak y\u00f6netimi, kullan\u0131c\u0131lar\u0131n\u0131za kesintisiz ve g\u00fcvenilir bir uygulama deneyimi sunman\u0131n anahtar\u0131d\u0131r.<\/p>\n<h3>Performans \u0130pu\u00e7lar\u0131 ve En \u0130yi Uygulamalar<\/h3>\n<p>Kaynak temizli\u011fi sadece bellek s\u0131z\u0131nt\u0131lar\u0131n\u0131 \u00f6nlemekle kalmaz, ayn\u0131 zamanda uygulaman\u0131z\u0131n performans\u0131n\u0131 ve kullan\u0131c\u0131 deneyimini de do\u011frudan etkiler. Bu b\u00f6l\u00fcmde, <code>AutoCloseable<\/code> ve <code>viewModelScope<\/code> kullan\u0131rken uygulaman\u0131z\u0131n performans\u0131n\u0131 art\u0131racak ve en iyi uygulamalar\u0131 takip etmenizi sa\u011flayacak baz\u0131 ipu\u00e7lar\u0131n\u0131 ele alaca\u011f\u0131z.<\/p>\n<ol>\n<li>\n        <strong>Gereksiz Kaynaklardan Ka\u00e7\u0131nma:<\/strong> En iyi performans ipucu, kullanmad\u0131\u011f\u0131n\u0131z kaynaklar\u0131 olu\u015fturmamakt\u0131r. Bir <code>AutoCloseable<\/code> nesnesi olu\u015fturmadan \u00f6nce ger\u00e7ekten ihtiyac\u0131n\u0131z olup olmad\u0131\u011f\u0131n\u0131 sorgulay\u0131n. A\u015f\u0131r\u0131 kaynak olu\u015fturma, sadece bellek t\u00fcketimini art\u0131rmakla kalmaz, ayn\u0131 zamanda bu kaynaklar\u0131n kapat\u0131lmas\u0131 i\u00e7in ek CPU d\u00f6ng\u00fcleri de gerektirir. Yaln\u0131zca ihtiya\u00e7 duyuldu\u011funda (lazy initialization) kaynaklar\u0131 ba\u015flatmay\u0131 d\u00fc\u015f\u00fcn\u00fcn.\n    <\/li>\n<li>\n        <strong>Kaynaklar\u0131 En K\u0131sa S\u00fcrede Serbest B\u0131rak\u0131n:<\/strong> Bir kaynakla i\u015finiz bitti\u011finde, onu m\u00fcmk\u00fcn olan en k\u0131sa s\u00fcrede serbest b\u0131rakmaya \u00e7al\u0131\u015f\u0131n. <code>ViewModel<\/code> yap\u0131c\u0131 metoduna <code>AutoCloseable<\/code> ge\u00e7irmek, <code>ViewModel<\/code> ya\u015fam d\u00f6ng\u00fcs\u00fc sonuna kadar kayna\u011f\u0131 tutar. E\u011fer bir kaynak, <code>ViewModel<\/code> ya\u015fam d\u00f6ng\u00fcs\u00fcnden daha k\u0131sa bir s\u00fcre i\u00e7in gerekiyorsa, onu <code>try-with-resources<\/code> blo\u011fu i\u00e7inde lokal olarak kullan\u0131p hemen kapatmak daha verimli olabilir.<\/p>\n<pre><code class=\"language-kotlin\">\n\/\/ ViewModel i\u00e7inde bir metod\nfun processTemporaryFile() {\n    try (val tempFileStream = MyTempFileStream(\"temp_data.txt\")) {\n        tempFileStream.writeData(\"Ge\u00e7ici veri\")\n        \/\/ \u0130\u015flemler\n    } catch (e: Exception) {\n        e.printStackTrace()\n    }\n    \/\/ tempFileStream burada otomatik olarak kapat\u0131ld\u0131\n}\n        <\/pre>\n<p><\/code>\n    <\/li>\n<li>\n        <strong>Background Thread'lerde Kapatma \u0130\u015flemi:<\/strong> Baz\u0131 <code>close()<\/code> operasyonlar\u0131 (\u00f6zellikle I\/O veya a\u011f i\u015flemleri), ana thread'i bloke edebilecek kadar uzun s\u00fcrebilir. Bu t\u00fcr durumlarda, <code>close()<\/code> metodunun kendisini bir background thread'de veya bir Coroutine'de \u00e7al\u0131\u015ft\u0131rmay\u0131 d\u00fc\u015f\u00fcnebilirsiniz. Ancak, <code>AutoCloseable<\/code> aray\u00fcz\u00fcn\u00fcn do\u011frudan bir CoroutineScope ile entegre olmad\u0131\u011f\u0131n\u0131 unutmay\u0131n. Bu, <code>onCleared()<\/code> i\u00e7inde manuel olarak bir <code>CoroutineScope.launch<\/code> ile bu i\u015flemi ba\u015flatman\u0131z gerekti\u011fi anlam\u0131na gelir.<\/p>\n<pre><code class=\"language-kotlin\">\noverride fun close() {\n    \/\/ \u00d6rne\u011fin, bir veritaban\u0131 kapatma i\u015flemi uzun s\u00fcrebilir\n    GlobalScope.launch(Dispatchers.IO) { \/\/ Dikkat: GlobalScope genellikle ka\u00e7\u0131n\u0131lmas\u0131 gereken bir kullan\u0131md\u0131r\n        try {\n            \/\/ A\u011f veya veritaban\u0131 ba\u011flant\u0131s\u0131n\u0131 kapatma\n            println(\"Arka planda a\u011f\u0131r kaynak kapatma i\u015flemi tamamland\u0131.\")\n        } catch (e: Exception) {\n            println(\"Arka planda kapatma hatas\u0131: ${e.message}\")\n        }\n    }\n}\n        <\/pre>\n<p><\/code><br \/>\n        Yukar\u0131daki <code>GlobalScope<\/code> \u00f6rne\u011fi, ViewModel'\u0131n kendisi temizlense bile coroutine'in \u00e7al\u0131\u015fmaya devam etme riskini ta\u015f\u0131r. Bu nedenle, <code>ViewModel<\/code>'\u0131n ya\u015fam d\u00f6ng\u00fcs\u00fcne ba\u011fl\u0131 bir <code>CoroutineScope<\/code> i\u00e7inde bu t\u00fcr i\u015flemleri ele almak daha g\u00fcvenlidir. Ancak <code>onCleared()<\/code> \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda <code>viewModelScope<\/code>'un iptal edildi\u011fini g\u00f6z \u00f6n\u00fcnde bulundurarak, bu t\u00fcr \"temizlik\" coroutine'lerini dikkatli bir \u015fekilde y\u00f6netmek gerekir.\n    <\/li>\n<li>\n        <strong>K\u00fc\u00e7\u00fck ve Odaklanm\u0131\u015f <code>AutoCloseable<\/code>'lar:<\/strong> B\u00fcy\u00fck ve \u00e7ok ama\u00e7l\u0131 <code>AutoCloseable<\/code> s\u0131n\u0131flar yerine, tek bir sorumlulu\u011fa sahip k\u00fc\u00e7\u00fck ve odaklanm\u0131\u015f <code>AutoCloseable<\/code>'lar olu\u015fturun. Bu, hem kodu daha anla\u015f\u0131l\u0131r hale getirir hem de her bir kayna\u011f\u0131n temizli\u011finin daha kolay y\u00f6netilmesini sa\u011flar.\n    <\/li>\n<li>\n        <strong>Hata Durumunda Temizlik:<\/strong> <code>AutoCloseable<\/code>'\u0131n en b\u00fcy\u00fck avantajlar\u0131ndan biri, <code>try-with-resources<\/code> yap\u0131s\u0131 sayesinde bir hata durumunda bile kaynaklar\u0131n kapat\u0131lmas\u0131n\u0131 garanti etmesidir. Kendi <code>AutoCloseable<\/code> uygulamalar\u0131n\u0131zda, <code>close()<\/code> metodunun bir istisna f\u0131rlatmas\u0131 durumunda bile temizlik i\u015fleminin tamamland\u0131\u011f\u0131ndan emin olun.\n    <\/li>\n<\/ol>\n<p>Bu ipu\u00e7lar\u0131, <code>AutoCloseable<\/code> ve <code>viewModelScope<\/code>'u kullanarak sadece kodunuzu temizlemekle kalmay\u0131p, ayn\u0131 zamanda uygulaman\u0131z\u0131n performans\u0131n\u0131 ve kararl\u0131l\u0131\u011f\u0131n\u0131 da art\u0131rman\u0131za yard\u0131mc\u0131 olacakt\u0131r. Unutmay\u0131n, iyi bir kaynak y\u00f6netimi, modern Android geli\u015ftiricili\u011finin temel ta\u015flar\u0131ndan biridir.<\/p>\n<h2>Sonu\u00e7: Kaynak Temizli\u011finin Gelece\u011fi<\/h2>\n<p>Bu makale boyunca, Jetpack ViewModels'ta otomatik kaynak temizli\u011finin \u00f6nemini ve <code>AutoCloseable<\/code> aray\u00fcz\u00fcn\u00fc kullanarak bu s\u00fcrecin nas\u0131l basitle\u015ftirilebilece\u011fini derinlemesine inceledik. Modern Android uygulamalar\u0131nda bellek s\u0131z\u0131nt\u0131lar\u0131n\u0131n ve verimsiz kaynak kullan\u0131m\u0131n\u0131n yol a\u00e7t\u0131\u011f\u0131 sorunlar\u0131 ele alarak, <code>ViewModel<\/code>'lar\u0131n ya\u015fam d\u00f6ng\u00fcs\u00fcne duyarl\u0131 mimarisiyle <code>AutoCloseable<\/code>'\u0131n entegrasyonunun ne kadar kritik oldu\u011funu vurgulad\u0131k. Ad\u0131m ad\u0131m rehberler ve pratik kod \u00f6rnekleri arac\u0131l\u0131\u011f\u0131yla, veritaban\u0131 ba\u011flant\u0131lar\u0131ndan a\u011f isteklerine kadar \u00e7e\u015fitli senaryolarda bu g\u00fc\u00e7l\u00fc mekanizman\u0131n nas\u0131l uygulanaca\u011f\u0131n\u0131 g\u00f6sterdik.<\/p>\n<p><code>androidx.lifecycle.viewModelScope<\/code> gibi Jetpack k\u00fct\u00fcphanelerinin sa\u011flad\u0131\u011f\u0131 kolayl\u0131klar, Coroutine tabanl\u0131 asenkron i\u015flemlerin y\u00f6netimini basitle\u015ftirirken, <code>AutoCloseable<\/code> ile birlikte kullan\u0131ld\u0131\u011f\u0131nda hem senkron hem de asenkron kaynaklar\u0131n temizli\u011fini tam anlam\u0131yla otomatize etmektedir. Bu yakla\u015f\u0131mlar, geli\u015ftiricilerin <code>onCleared()<\/code> metodunda manuel temizlik yapmak yerine i\u015f mant\u0131\u011f\u0131na odaklanmas\u0131na olanak tan\u0131r, bu da daha az hataya a\u00e7\u0131k, daha okunakl\u0131 ve daha s\u00fcrd\u00fcr\u00fclebilir bir kod taban\u0131 olu\u015fturulmas\u0131na yard\u0131mc\u0131 olur.<\/p>\n<p>Geli\u015fen Android ekosisteminde, performans ve kararl\u0131l\u0131k, kullan\u0131c\u0131 deneyiminin temel direkleridir. <code>AutoCloseable<\/code> ve <code>viewModelScope<\/code> gibi ara\u00e7lar\u0131 etkili bir \u015fekilde kullanmak, uygulaman\u0131z\u0131n bu hedeflere ula\u015fmas\u0131nda kritik bir rol oynar. \u0130leri d\u00fczey uygulamalar ve yayg\u0131n hatalardan ka\u00e7\u0131nma yollar\u0131 \u00fczerine sundu\u011fumuz ipu\u00e7lar\u0131 ise, bu teknolojileri en verimli \u015fekilde kullanman\u0131z i\u00e7in size yol g\u00f6sterecektir. Sonu\u00e7 olarak, otomatik kaynak temizli\u011fi, sadece bir \"iyi uygulama\" olmaktan \u00e7\u0131k\u0131p, her modern Android uygulamas\u0131n\u0131n ayr\u0131lmaz bir par\u00e7as\u0131 haline gelmi\u015ftir. Bu teknikleri benimseyerek, daha sa\u011flam, h\u0131zl\u0131 ve g\u00fcvenilir mobil uygulamalar geli\u015ftirebilirsiniz. Unutmay\u0131n, temiz kod, mutlu kullan\u0131c\u0131lar demektir.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular<\/h3>\n<p>Bu b\u00f6l\u00fcmde, <code>AutoCloseable<\/code> ve <code>ViewModel<\/code>'lardaki kaynak temizli\u011fi hakk\u0131nda s\u0131k\u00e7a sorulan baz\u0131 sorular\u0131 ve cevaplar\u0131n\u0131 bulabilirsiniz.<\/p>\n<ol>\n<li>\n        <strong><code>AutoCloseable<\/code> kullanmak her zaman <code>onCleared()<\/code> metodunda manuel temizlikten daha m\u0131 iyidir?<\/strong><\/p>\n<p>Genel olarak evet. <code>AutoCloseable<\/code>, ViewModel'\u0131n yap\u0131c\u0131 metoduna ge\u00e7irildi\u011finde veya <code>try-with-resources<\/code> blo\u011fu i\u00e7inde kullan\u0131ld\u0131\u011f\u0131nda, kaynaklar\u0131n otomatik olarak ve g\u00fcvenli bir \u015fekilde temizlenmesini sa\u011flar. Bu, manuel <code>onCleared()<\/code> kullan\u0131m\u0131na g\u00f6re daha az hataya a\u00e7\u0131k, daha temiz ve daha s\u00fcrd\u00fcr\u00fclebilir bir yakla\u015f\u0131md\u0131r. Ancak, baz\u0131 \u00f6zel durumlarda (\u00f6rne\u011fin, <code>AutoCloseable<\/code> olmayan k\u00fct\u00fcphane nesneleri veya karma\u015f\u0131k temizlik mant\u0131\u011f\u0131 gerektiren durumlar) <code>onCleared()<\/code> hala gerekli olabilir.<\/p>\n<\/li>\n<li>\n        <strong><code>viewModelScope<\/code> d\u0131\u015f\u0131nda ba\u015flat\u0131lan Coroutine'ler nas\u0131l temizlenir?<\/strong><\/p>\n<p><code>viewModelScope<\/code> d\u0131\u015f\u0131nda ba\u015flat\u0131lan Coroutine'ler (\u00f6rne\u011fin <code>GlobalScope<\/code> veya \u00f6zel bir <code>CoroutineScope<\/code> i\u00e7inde), <code>ViewModel<\/code> temizlendi\u011finde otomatik olarak iptal edilmez. Bu Coroutine'lerin <code>Job<\/code>'lar\u0131n\u0131 manuel olarak takip etmeli ve <code>ViewModel<\/code>'\u0131n <code>onCleared()<\/code> metodunda <code>Job.cancel()<\/code> \u00e7a\u011f\u0131rarak iptal etmelisiniz. Aksi takdirde, bellek s\u0131z\u0131nt\u0131lar\u0131na veya gereksiz arka plan i\u015flemlerine yol a\u00e7abilirler.<\/p>\n<\/li>\n<li>\n        <strong>Birden fazla <code>AutoCloseable<\/code> nesnesini <code>ViewModel<\/code>'a nas\u0131l enjekte edebilirim?<\/strong><\/p>\n<p>Birden fazla <code>AutoCloseable<\/code> nesnesini <code>ViewModel<\/code>'a enjekte etmek i\u00e7in, bu nesneleri <code>ViewModel<\/code>'\u0131n yap\u0131c\u0131 metoduna <code>vararg AutoCloseable<\/code> \u015feklinde ge\u00e7irebilirsiniz. Ba\u011f\u0131ml\u0131l\u0131k enjeksiyonu framework'leri (Hilt, Koin vb.) kullan\u0131yorsan\u0131z, bu framework'ler arac\u0131l\u0131\u011f\u0131yla sa\u011flanan <code>AutoCloseable<\/code> nesnelerini yine <code>ViewModel<\/code>'\u0131n yap\u0131c\u0131 metoduna enjekte edip, oradan base <code>ViewModel<\/code> s\u0131n\u0131f\u0131n\u0131n yap\u0131c\u0131 metoduna iletmeniz en g\u00fcvenli yoldur.<\/p>\n<\/li>\n<li>\n        <strong><code>AutoCloseable.close()<\/code> metodu bir istisna f\u0131rlat\u0131rsa ne olur?<\/strong><\/p>\n<p><code>AutoCloseable.close()<\/code> metodu bir <code>Exception<\/code> f\u0131rlatabilir. E\u011fer bu istisna yakalanmazsa, uygulama \u00e7\u00f6kmeyebilir ancak kaynak temizli\u011fi tam olarak ger\u00e7ekle\u015fmeyebilir. En iyi uygulama, <code>close()<\/code> metodunun i\u00e7indeki temizlik mant\u0131\u011f\u0131n\u0131 bir <code>try-catch<\/code> blo\u011funa alarak olas\u0131 istisnalar\u0131 yakalamak ve uygun \u015fekilde loglamakt\u0131r. Bu, hem uygulaman\u0131n kararl\u0131l\u0131\u011f\u0131n\u0131 sa\u011flar hem de temizlik sorunlar\u0131n\u0131 tespit etmenize yard\u0131mc\u0131 olur.<\/p>\n<\/li>\n<li>\n        <strong><code>AutoCloseable<\/code> sadece Java I\/O s\u0131n\u0131flar\u0131 i\u00e7in mi ge\u00e7erlidir?<\/strong><\/p>\n<p>Hay\u0131r, <code>AutoCloseable<\/code> aray\u00fcz\u00fc <code>java.io.Closeable<\/code>'dan daha genel bir ama\u00e7 i\u00e7in tasarlanm\u0131\u015ft\u0131r. Herhangi bir s\u0131n\u0131f, <code>AutoCloseable<\/code> aray\u00fcz\u00fcn\u00fc uygulayarak kendi kaynaklar\u0131n\u0131 y\u00f6netebilir. Bu, veritaban\u0131 ba\u011flant\u0131lar\u0131, a\u011f soketleri, \u00f6zel ak\u0131\u015flar, yerel kaynaklar veya herhangi bir \"kapat\u0131lmas\u0131\" gereken \u00f6zel bir nesne olabilir. <code>java.io.Closeable<\/code> ise daha \u00e7ok I\/O odakl\u0131d\u0131r ve <code>IOException<\/code> f\u0131rlat\u0131r.<\/p>\n<\/li>\n<\/ol>\n<p><\/body><br \/>\n<\/html><\/p>\n","protected":false},"excerpt":{"rendered":"Android uygulamalar\u0131nda performans ve kararl\u0131l\u0131k, kaynak y\u00f6netiminin ne kadar etkili yap\u0131ld\u0131\u011f\u0131yla do\u011frudan ili\u015fkilidir. \u00d6zellikle ViewModel&#8217;lar, ya\u015fam d\u00f6ng\u00fcs\u00fcne duyarl\u0131&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-31228","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Jetpack ViewModels&#039;ta AutoCloseable ile Kaynak Temizli\u011fi<\/title>\n<meta name=\"description\" content=\"Android uygulamalar\u0131nda performans ve kararl\u0131l\u0131k, kaynak y\u00f6netiminin ne kadar etkili yap\u0131ld\u0131\u011f\u0131yla do\u011frudan ili\u015fkilidir. \u00d6zellikle ViewModel&#039;lar, ya\u015fam d\u00f6ng\u00fcs\u00fcne duyarl\u0131 mimarileri nedeniyle kaynak temizli\u011finin hayati \u00f6nem ta\u015f\u0131d\u0131\u011f\u0131 bile\u015fenlerdir. Bu yaz\u0131m\u0131zda, Jetpack ViewModels&#039;ta AutoCloseable aray\u00fcz\u00fcn\u00fc kullanarak otomatik kaynak temizli\u011finin nas\u0131l sa\u011flanaca\u011f\u0131n\u0131, uygulaman\u0131z\u0131n bellek s\u0131z\u0131nt\u0131lar\u0131ndan nas\u0131l korunaca\u011f\u0131n\u0131 ve kodunuzu nas\u0131l daha d\u00fczenli hale getirece\u011finizi ad\u0131m ad\u0131m inceleyece\u011fiz. Modern Android geli\u015ftiricilerinin s\u0131k\u00e7a kar\u015f\u0131la\u015ft\u0131\u011f\u0131 bu sorunlara pratik \u00e7\u00f6z\u00fcmler sunarak, hem yeni ba\u015flayanlar hem de deneyimli geli\u015ftiriciler i\u00e7in kapsaml\u0131 bir rehber haz\u0131rlad\u0131k.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Jetpack ViewModels&#039;ta AutoCloseable ile Kaynak Temizli\u011fi\" \/>\n<meta property=\"og:description\" content=\"Android uygulamalar\u0131nda performans ve kararl\u0131l\u0131k, kaynak y\u00f6netiminin ne kadar etkili yap\u0131ld\u0131\u011f\u0131yla do\u011frudan ili\u015fkilidir. \u00d6zellikle ViewModel&#039;lar, ya\u015fam d\u00f6ng\u00fcs\u00fcne duyarl\u0131 mimarileri nedeniyle kaynak temizli\u011finin hayati \u00f6nem ta\u015f\u0131d\u0131\u011f\u0131 bile\u015fenlerdir. Bu yaz\u0131m\u0131zda, Jetpack ViewModels&#039;ta AutoCloseable aray\u00fcz\u00fcn\u00fc kullanarak otomatik kaynak temizli\u011finin nas\u0131l sa\u011flanaca\u011f\u0131n\u0131, uygulaman\u0131z\u0131n bellek s\u0131z\u0131nt\u0131lar\u0131ndan nas\u0131l korunaca\u011f\u0131n\u0131 ve kodunuzu nas\u0131l daha d\u00fczenli hale getirece\u011finizi ad\u0131m ad\u0131m inceleyece\u011fiz. Modern Android geli\u015ftiricilerinin s\u0131k\u00e7a kar\u015f\u0131la\u015ft\u0131\u011f\u0131 bu sorunlara pratik \u00e7\u00f6z\u00fcmler sunarak, hem yeni ba\u015flayanlar hem de deneyimli geli\u015ftiriciler i\u00e7in kapsaml\u0131 bir rehber haz\u0131rlad\u0131k.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-07T09:31:51+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"32 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Jetpack ViewModels&#8217;ta AutoCloseable ile Kaynak Temizli\u011fi\",\"datePublished\":\"2025-10-07T09:31:51+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/\"},\"wordCount\":4496,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/\",\"name\":\"Jetpack ViewModels'ta AutoCloseable ile Kaynak Temizli\u011fi\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-07T09:31:51+00:00\",\"description\":\"Android uygulamalar\u0131nda performans ve kararl\u0131l\u0131k, kaynak y\u00f6netiminin ne kadar etkili yap\u0131ld\u0131\u011f\u0131yla do\u011frudan ili\u015fkilidir. \u00d6zellikle ViewModel'lar, ya\u015fam d\u00f6ng\u00fcs\u00fcne duyarl\u0131 mimarileri nedeniyle kaynak temizli\u011finin hayati \u00f6nem ta\u015f\u0131d\u0131\u011f\u0131 bile\u015fenlerdir. Bu yaz\u0131m\u0131zda, Jetpack ViewModels'ta AutoCloseable aray\u00fcz\u00fcn\u00fc kullanarak otomatik kaynak temizli\u011finin nas\u0131l sa\u011flanaca\u011f\u0131n\u0131, uygulaman\u0131z\u0131n bellek s\u0131z\u0131nt\u0131lar\u0131ndan nas\u0131l korunaca\u011f\u0131n\u0131 ve kodunuzu nas\u0131l daha d\u00fczenli hale getirece\u011finizi ad\u0131m ad\u0131m inceleyece\u011fiz. Modern Android geli\u015ftiricilerinin s\u0131k\u00e7a kar\u015f\u0131la\u015ft\u0131\u011f\u0131 bu sorunlara pratik \u00e7\u00f6z\u00fcmler sunarak, hem yeni ba\u015flayanlar hem de deneyimli geli\u015ftiriciler i\u00e7in kapsaml\u0131 bir rehber haz\u0131rlad\u0131k.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Jetpack ViewModels&#8217;ta AutoCloseable ile Kaynak Temizli\u011fi\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Jetpack ViewModels'ta AutoCloseable ile Kaynak Temizli\u011fi","description":"Android uygulamalar\u0131nda performans ve kararl\u0131l\u0131k, kaynak y\u00f6netiminin ne kadar etkili yap\u0131ld\u0131\u011f\u0131yla do\u011frudan ili\u015fkilidir. \u00d6zellikle ViewModel'lar, ya\u015fam d\u00f6ng\u00fcs\u00fcne duyarl\u0131 mimarileri nedeniyle kaynak temizli\u011finin hayati \u00f6nem ta\u015f\u0131d\u0131\u011f\u0131 bile\u015fenlerdir. Bu yaz\u0131m\u0131zda, Jetpack ViewModels'ta AutoCloseable aray\u00fcz\u00fcn\u00fc kullanarak otomatik kaynak temizli\u011finin nas\u0131l sa\u011flanaca\u011f\u0131n\u0131, uygulaman\u0131z\u0131n bellek s\u0131z\u0131nt\u0131lar\u0131ndan nas\u0131l korunaca\u011f\u0131n\u0131 ve kodunuzu nas\u0131l daha d\u00fczenli hale getirece\u011finizi ad\u0131m ad\u0131m inceleyece\u011fiz. Modern Android geli\u015ftiricilerinin s\u0131k\u00e7a kar\u015f\u0131la\u015ft\u0131\u011f\u0131 bu sorunlara pratik \u00e7\u00f6z\u00fcmler sunarak, hem yeni ba\u015flayanlar hem de deneyimli geli\u015ftiriciler i\u00e7in kapsaml\u0131 bir rehber haz\u0131rlad\u0131k.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/","og_locale":"tr_TR","og_type":"article","og_title":"Jetpack ViewModels'ta AutoCloseable ile Kaynak Temizli\u011fi","og_description":"Android uygulamalar\u0131nda performans ve kararl\u0131l\u0131k, kaynak y\u00f6netiminin ne kadar etkili yap\u0131ld\u0131\u011f\u0131yla do\u011frudan ili\u015fkilidir. \u00d6zellikle ViewModel'lar, ya\u015fam d\u00f6ng\u00fcs\u00fcne duyarl\u0131 mimarileri nedeniyle kaynak temizli\u011finin hayati \u00f6nem ta\u015f\u0131d\u0131\u011f\u0131 bile\u015fenlerdir. Bu yaz\u0131m\u0131zda, Jetpack ViewModels'ta AutoCloseable aray\u00fcz\u00fcn\u00fc kullanarak otomatik kaynak temizli\u011finin nas\u0131l sa\u011flanaca\u011f\u0131n\u0131, uygulaman\u0131z\u0131n bellek s\u0131z\u0131nt\u0131lar\u0131ndan nas\u0131l korunaca\u011f\u0131n\u0131 ve kodunuzu nas\u0131l daha d\u00fczenli hale getirece\u011finizi ad\u0131m ad\u0131m inceleyece\u011fiz. Modern Android geli\u015ftiricilerinin s\u0131k\u00e7a kar\u015f\u0131la\u015ft\u0131\u011f\u0131 bu sorunlara pratik \u00e7\u00f6z\u00fcmler sunarak, hem yeni ba\u015flayanlar hem de deneyimli geli\u015ftiriciler i\u00e7in kapsaml\u0131 bir rehber haz\u0131rlad\u0131k.","og_url":"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-07T09:31:51+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"32 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Jetpack ViewModels&#8217;ta AutoCloseable ile Kaynak Temizli\u011fi","datePublished":"2025-10-07T09:31:51+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/"},"wordCount":4496,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/","url":"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/","name":"Jetpack ViewModels'ta AutoCloseable ile Kaynak Temizli\u011fi","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-07T09:31:51+00:00","description":"Android uygulamalar\u0131nda performans ve kararl\u0131l\u0131k, kaynak y\u00f6netiminin ne kadar etkili yap\u0131ld\u0131\u011f\u0131yla do\u011frudan ili\u015fkilidir. \u00d6zellikle ViewModel'lar, ya\u015fam d\u00f6ng\u00fcs\u00fcne duyarl\u0131 mimarileri nedeniyle kaynak temizli\u011finin hayati \u00f6nem ta\u015f\u0131d\u0131\u011f\u0131 bile\u015fenlerdir. Bu yaz\u0131m\u0131zda, Jetpack ViewModels'ta AutoCloseable aray\u00fcz\u00fcn\u00fc kullanarak otomatik kaynak temizli\u011finin nas\u0131l sa\u011flanaca\u011f\u0131n\u0131, uygulaman\u0131z\u0131n bellek s\u0131z\u0131nt\u0131lar\u0131ndan nas\u0131l korunaca\u011f\u0131n\u0131 ve kodunuzu nas\u0131l daha d\u00fczenli hale getirece\u011finizi ad\u0131m ad\u0131m inceleyece\u011fiz. Modern Android geli\u015ftiricilerinin s\u0131k\u00e7a kar\u015f\u0131la\u015ft\u0131\u011f\u0131 bu sorunlara pratik \u00e7\u00f6z\u00fcmler sunarak, hem yeni ba\u015flayanlar hem de deneyimli geli\u015ftiriciler i\u00e7in kapsaml\u0131 bir rehber haz\u0131rlad\u0131k.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/jetpack-viewmodelsta-autocloseable-ile-kaynak-temizligi\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Jetpack ViewModels&#8217;ta AutoCloseable ile Kaynak Temizli\u011fi"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31228","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=31228"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31228\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=31228"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=31228"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=31228"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}