[{"channel_id":1207457473,"post_id":1835,"date":1775768764000,"views":"86","text":"<a target=\"_blank\" rel=\"noreferrer nofollow\" href=\"https:\/\/androidstudio.googleblog.com\/2026\/04\/android-studio-panda-4-canary-4-now.html\">https:\/\/androidstudio.googleblog.com\/2026\/04\/android-studio-panda-4-canary-4-now.html<\/a>","text_length":85,"media":{"root":"\/00c\/KwcAAMFW-EcAAAAAhl2zaWaja-c","webpage":{"url":"https:\/\/androidstudio.googleblog.com\/2026\/04\/android-studio-panda-4-canary-4-now.html","type":"photo","title":"Android Studio Panda 4 Canary 4 now available","site_name":"Android Studio Release Updates","display_url":"androidstudio.googleblog.com\/2026\/04\/android-studio-panda-4-canary-4-now.html","description":"Android Studio Panda 4 Canary 4 is now available in the Canary channel.   If you already have an Android Studio build on the\u00a0 Canary channe...","thumbs":{"s":{"w":83,"h":90,"hash":"O_iIdNPDTgn1ZARXJBUsAA&ts=1780145524"},"x":{"w":114,"h":124,"hash":"yKld0c_-Auh_MEe_NDz5GA&ts=1780145524"}}}}},{"channel_id":1207457473,"post_id":1834,"date":1774903626000,"forwards":"1","views":"135","text":"Nice overview of Android 17 Beta 3. CommonsWare digs into the API changes and calls out what might actually affect apps versus what\u2019s just noise<br><br><a target=\"_blank\" rel=\"noreferrer nofollow\" href=\"https:\/\/commonsware.com\/blog\/2026\/03\/27\/random-musings-android-17-beta-3.html\">https:\/\/commonsware.com\/blog\/2026\/03\/27\/random-musings-android-17-beta-3.html<\/a>","text_length":223,"media":{"root":null,"webpage":{"url":"https:\/\/commonsware.com\/blog\/2026\/03\/27\/random-musings-android-17-beta-3.html","type":"article","title":"Random Musings on the Android 17 Beta 3","site_name":"CommonsWare: Android App Development Books","display_url":"commonsware.com\/blog\/2026\/03\/27\/random-musings-android-17-beta-3.html","description":"We have our third and final(?) Android 17 beta -- let's take a look!"}}},{"channel_id":1207457473,"post_id":1833,"date":1774557451000,"views":"170","text":"<a target=\"_blank\" rel=\"noreferrer nofollow\" href=\"https:\/\/blog.jetbrains.com\/idea\/2026\/03\/intellij-idea-2026-1\/\">https:\/\/blog.jetbrains.com\/idea\/2026\/03\/intellij-idea-2026-1\/<\/a>","text_length":61,"media":{"root":"\/011\/KQcAAMFW-EcAAAAAcLLLprkb_mc","webpage":{"url":"https:\/\/blog.jetbrains.com\/idea\/2026\/03\/intellij-idea-2026-1","type":"photo","title":"IntelliJ IDEA 2026.1 Is Out! | The IntelliJ IDEA Blog","site_name":"The JetBrains Blog","display_url":"blog.jetbrains.com\/idea\/2026\/03\/intellij-idea-2026-1","description":"IntelliJ IDEA 2026.1 is here, and it comes packed with an array of new features and enhancements to elevate your coding experience!\u00a0 You can download this latest release from our\u00a0website&","thumbs":{"m":{"w":320,"h":180,"hash":"ut2PuLKYQxJjnqHHiFbRtw&ts=1780145524"},"x":{"w":800,"h":450,"hash":"TIl205zJaMuVrIDZ67gf1Q&ts=1780145524"},"y":{"w":1280,"h":720,"hash":"NgQI97HeMV_NqMqetAzK_w&ts=1780145524"},"i":{"bytes":"AXACg|DIXZ\/ED+FSjyO4k\/MUyOLeMh1HOME4p4h5AMicjPWmgFCwlgBvA\/OnlFwfKOUHU96R4fLiYhg3bikUGNfc9a0a02Lg7vUgc5bNFPZd3PQ0VkJxEjmkjGEOBnPQGkeR5CN5zRRQSSRzeV05Pv0FO+05++g\/Kiited7AhC6Hmiiiky7s\/9k="}}}}},{"channel_id":1207457473,"post_id":1832,"date":1774343938000,"forwards":"9","views":"301","text":"How a small change in a modern Compose app led to a 34% startup performance improvement. A good reminder that even small optimizations can have a big impact<br><br><a target=\"_blank\" rel=\"noreferrer nofollow\" href=\"https:\/\/levelup.gitconnected.com\/how-i-found-a-34-startup-win-in-a-modern-compose-app-84953f77ae52\">https:\/\/levelup.gitconnected.com\/how-i-found-a-34-startup-win-in-a-modern-compose-app-84953f77ae52<\/a>","text_length":256,"media":{"root":"\/00e\/KAcAAMFW-EcAAAAAjCNvd_O_LeY","webpage":{"url":"https:\/\/levelup.gitconnected.com\/how-i-found-a-34-startup-win-in-a-modern-compose-app-84953f77ae52","type":"photo","title":"How I Found a 34% Startup Win in a Modern Compose App","site_name":"Medium","display_url":"levelup.gitconnected.com\/how-i-found-a-34-startup-win-in-a-modern-compose-app-84953f77ae52","description":"It is easy to assume the big startup wins are already gone once an Android app is modern, uses Compose, has reasonable structure, and does\u2026","author":"https:\/\/jamescullimore.medium.com","thumbs":{"m":{"w":320,"h":179,"hash":"5hNcvIvmCK43o9EuWdi-HQ&ts=1780145524"},"x":{"w":800,"h":447,"hash":"GLxO5S0hJQQ8qL3edhaOzA&ts=1780145524"},"y":{"w":1200,"h":670,"hash":"bIa3YWfVKLj-3ODYpjZGgQ&ts=1780145524"},"i":{"bytes":"AWACg|DQvboWsQfbuJOAKbb30csO9yEOcEZp13ai4jZVOxyc7vWqcMaWtvOrnlWHJ\/pQBoGdApIJbHoDWffX7gJ5DbAepI605ZXJJU5yOuetSwRQzL5coDsOeaSZKdyaymae1R26nv60VMiLGgRFCqOgFFModWTuW4vJGCbgcfK546CiigCJoTb5dHwCMhR0FQR3ciOHj4OP60UUuoup0EZLRqWxkgE4ooopjP\/Z"}}}}},{"channel_id":1207457473,"post_id":1831,"date":1773947017000,"forwards":"1","views":"78","text":"Good practical article on glowing borders in Compose. Demonstrates multiple implementations using shadows, gradients, and custom drawing APIs<br><br><a target=\"_blank\" rel=\"noreferrer nofollow\" href=\"https:\/\/proandroiddev.com\/how-many-ways-do-you-know-to-draw-a-glowing-border-in-jetpack-compose-57980d049562\">https:\/\/proandroiddev.com\/how-many-ways-do-you-know-to-draw-a-glowing-border-in-jetpack-compose-57980d049562<\/a>","text_length":251,"media":{"root":"\/002\/JwcAAMFW-EcAAAAAMRpIgJ0eRK4","webpage":{"url":"https:\/\/proandroiddev.com\/how-many-ways-do-you-know-to-draw-a-glowing-border-in-jetpack-compose-57980d049562","type":"photo","title":"How Many Ways Do You Know to Draw a Glowing Border in Jetpack Compose?","site_name":"Medium","display_url":"proandroiddev.com\/how-many-ways-do-you-know-to-draw-a-glowing-border-in-jetpack-compose-57980d049562","description":"If I asked you how many ways you know to draw a glowing rounded-rectangle border in Jetpack Compose, what would your answer be? One? Two\u2026","author":"Yuriy Skul","thumbs":{"m":{"w":320,"h":213,"hash":"6q-B5TC9BdQNk9sbjOLo0w&ts=1780145524"},"x":{"w":800,"h":533,"hash":"37da_CJFvecwmenxBdONzw&ts=1780145524"},"y":{"w":1200,"h":800,"hash":"axpE0z0tHb4OtS90BxVAcA&ts=1780145524"},"i":{"bytes":"AbACg|DL2rszilWMsOEJ+lLGcpjAqY5e0UJksrdBSk7DSGfZn2lvLbA68UwIMdMEVLCskYYn5eO5p8rIeVAGeeB0oTG0V50wcjoQDRT9+IyDg+maKNhaMLeAupcnCjr602SIpnLjjtSZ4xQxwBihXuPSw1cH1p+cJyeM9Kjyd2KWTjgdKYhrvmimUUxH\/9k="}}}}},{"channel_id":1207457473,"post_id":1830,"date":1773387245000,"forwards":"3","views":"291","text":"<a target=\"_blank\" rel=\"noreferrer nofollow\" href=\"https:\/\/developer.android.com\/jetpack\/androidx\/releases\/room3#3.0.0-alpha01\">https:\/\/developer.android.com\/jetpack\/androidx\/releases\/room3#3.0.0-alpha01<\/a>","text_length":75,"media":{"root":"\/012\/JgcAAMFW-EcAAAAAYesnQK1CkIk","webpage":{"url":"https:\/\/developer.android.com\/jetpack\/androidx\/releases\/room3","type":"photo","title":"Room 3.0 \u00a0|\u00a0 Jetpack \u00a0|\u00a0 Android Developers","site_name":"Android Developers","display_url":"developer.android.com\/jetpack\/androidx\/releases\/room3","thumbs":{"m":{"w":320,"h":180,"hash":"lzsa_eoOGN8VEcO9um_8zA&ts=1780145524"},"x":{"w":800,"h":450,"hash":"9aQkQ0oXT--dEeAFWeyXRA&ts=1780145524"},"y":{"w":1201,"h":676,"hash":"4z65zxAy5AlE7Rlu-aHBXw&ts=1780145524"},"i":{"bytes":"AXACg|DZoqGRJfMLRkfd4yTjPPb8qaVuflG6P360AWKKrg3JJ\/1Ywe9KwnKEZTPGD\/OgCeioYFlBbzCDnoRRQBNRRRQAUUUUAFFFFAH\/2Q=="}}}}},{"channel_id":1207457473,"post_id":1829,"date":1773089406000,"forwards":"3","views":"167","text":"Good engineering write-up from Vinted about moving from Dagger to Metro for dependency injection. The migration brought better Kotlin K2 compatibility and noticeably faster CI builds.<br><br><a target=\"_blank\" rel=\"noreferrer nofollow\" href=\"https:\/\/vinted.engineering\/2026\/02\/12\/from-dagger-to-metro\/\">https:\/\/vinted.engineering\/2026\/02\/12\/from-dagger-to-metro\/<\/a>","text_length":244,"media":{"root":"\/012\/JQcAAMFW-EcAAAAAYesnQK1CkIk","webpage":{"url":"https:\/\/vinted.engineering\/2026\/02\/12\/from-dagger-to-metro","type":"photo","title":"From Dagger to Metro","site_name":"vinted.engineering","display_url":"vinted.engineering\/2026\/02\/12\/from-dagger-to-metro","description":"The Engineering Blog from Vinted. These are the voyages of code tailors that help create Vinted.","thumbs":{"m":{"w":320,"h":167,"hash":"1ug7znzjOBisLsezZ8YBNA&ts=1780145524"},"x":{"w":800,"h":417,"hash":"BEdbgCG0mGCiGdb0Gq-eTw&ts=1780145524"},"y":{"w":1200,"h":626,"hash":"4xOo2qV0T8PhraIfl0XnTg&ts=1780145524"},"i":{"bytes":"AVACg|CtRg4zg4oq1FcRpCqurEqT09OD\/MVZzIq0YOCcdKsrLAvSNvQ+44z\/AFpJJYjCyRqQWIzxQFivRSiimAlFFFAgooooABRRRQB\/\/9k="}}}}},{"channel_id":1207457473,"post_id":1828,"date":1772657300000,"forwards":"8","views":"832","text":"A perspective on why ViewModel may be considered deprecated in some contexts. The author presents a compose retain as an alternative approach, even though it isn\u2019t a full replacement yet<br><br><a target=\"_blank\" rel=\"noreferrer nofollow\" href=\"https:\/\/www.costafotiadis.com\/post\/viewmodel-is-deprecated\">https:\/\/www.costafotiadis.com\/post\/viewmodel-is-deprecated<\/a>","text_length":246,"media":{"root":"\/00c\/JAcAAMFW-EcAAAAAhl2zaWaja-c","webpage":{"url":"https:\/\/www.costafotiadis.com\/post\/viewmodel-is-deprecated","type":"photo","title":"ViewModel is deprecated*","site_name":"Costa Fotiadis","display_url":"costafotiadis.com\/post\/viewmodel-is-deprecated","description":"Not sure if it\u2019s just me, but ViewModel is starting to feel increasingly redundant in a Compose-first world.What if we could skip it entirely?TL;DRHousekeepingThe goal of this post is to leverage retain\u2014 a relatively new Compose API \u2014 and use it to build something that pretends to be a ViewModel, but lives entirely in compose-land.Let\u2019s lose a few braincells together, shall we.What\u2019s wrong with ViewModel, exactly?When ViewModel landed, it solved quite a few problems \u2014 configuration changes were","author":"Costa Fotiadis","thumbs":{"m":{"w":213,"h":320,"hash":"Wsvq7rSKtbBvA-zrAr0Now&ts=1780145524"},"x":{"w":358,"h":538,"hash":"CbuL4i4iGFQEf53JsLLt-Q&ts=1780145524"},"i":{"bytes":"AoABs|CqssiEfNj2qx9qdk+bPuelJtCnccEEYGPWkmjDHapJz0rNRjJXJbadkM8ySIZABX61J9sXuoB9KjA+QxhTke3akKKec1LSZajYVY\/kDqAcDrnpVh0RkB2Hd2Oe9EUZLZcfhStHJuwqsVB5DcDFS23sJxIy0+ACntnFJjbx+7GOx\/8A1VLM4CDA4z2PH+NVJHfeen\/fFO1ynfoTpIowQ2D65xUhkzxkNn+6M4oorScVcUZNoheRQV5YjpgcVXZxuPyD8TRRUpEy3P\/Z"}}}}},{"channel_id":1207457473,"post_id":1827,"date":1772358139000,"forwards":"13","views":"623","text":"Good practical read on unit testing coroutines and flows in Android. The article shows how to write tests that handle suspending functions and Flow emissions cleanly<br><br><a target=\"_blank\" rel=\"noreferrer nofollow\" href=\"https:\/\/medium.com\/@mobileatexxeta\/unit-testing-coroutines-and-flows-in-android-0e91b82cacd5\">https:\/\/medium.com\/@mobileatexxeta\/unit-testing-coroutines-and-flows-in-android-0e91b82cacd5<\/a>","text_length":259,"media":{"root":"\/00d\/IwcAAMFW-EcAAAAAVA5xyyX4WGo","webpage":{"url":"https:\/\/medium.com\/@mobileatexxeta\/unit-testing-coroutines-and-flows-in-android-0e91b82cacd5","type":"photo","title":"Unit Testing Coroutines and Flows in Android","site_name":"Medium","display_url":"levelup.gitconnected.com\/unit-testing-coroutines-and-flows-in-android-0e91b82cacd5","description":"How UnconfinedTestDispatcher Saves You From Threading Hell","author":"https:\/\/medium.com\/@mobileatexxeta","thumbs":{"m":{"w":320,"h":204,"hash":"am3_LPXHE8oFWZz4Qy-Ghg&ts=1780145524"},"x":{"w":800,"h":511,"hash":"O2lfqVBCPQY3QkTUi7RsZg&ts=1780145524"},"y":{"w":1200,"h":767,"hash":"SHZmtMjkrLJuUoKrGQaAQA&ts=1780145524"},"i":{"bytes":"AZACg|BZZVYcEf8AfP8A9eqkhPU4qV2JXA2D3AP+NRbMAs77gO1Qka8zIHNMzV1BG6ghE\/HP+NNkiDfd2L9M1VyGipmirSwKB82D+NFFxWE8xPSmyOrgDoPaoaWhA2ORtue9O8welR0lMCQyA0VEaKLCuf\/Z"}}}}},{"channel_id":1207457473,"post_id":1826,"date":1772049235000,"views":"196","text":"F-Droid published an open letter opposing Google\u2019s mandatory developer verification proposal, arguing it threatens Android\u2019s openness and could force all developers to register and verify with Google to distribute apps<br><br><a target=\"_blank\" rel=\"noreferrer nofollow\" href=\"https:\/\/f-droid.org\/en\/2026\/02\/24\/open-letter-opposing-developer-verification.html\">https:\/\/f-droid.org\/en\/2026\/02\/24\/open-letter-opposing-developer-verification.html<\/a>","text_length":302},{"channel_id":1207457473,"post_id":1825,"date":1771278398000,"forwards":"2","views":"147","text":"Good read on the new retain API in Jetpack Compose. The article explains when and how to use retain, with examples showing how it helps preserve state across recompositions.<br><br><a target=\"_blank\" rel=\"noreferrer nofollow\" href=\"https:\/\/avatsav.dev\/hello-retain\/\">https:\/\/avatsav.dev\/hello-retain\/<\/a>","text_length":208,"media":{"root":null,"webpage":{"url":"https:\/\/avatsav.dev\/hello-retain","type":"article","title":"Goodbye ViewModel. Hello retain!","site_name":"Abhi's devlog","display_url":"avatsav.dev\/hello-retain","description":"Retain is here!"}}},{"channel_id":1207457473,"post_id":1824,"date":1771152805000,"views":"126","text":"<a target=\"_blank\" rel=\"noreferrer nofollow\" href=\"https:\/\/androidstudio.googleblog.com\/2026\/02\/android-studio-panda-1-202531-now.html\">https:\/\/androidstudio.googleblog.com\/2026\/02\/android-studio-panda-1-202531-now.html<\/a>","text_length":83,"media":{"root":"\/002\/IAcAAMFW-EcAAAAAMRpIgJ0eRK4","webpage":{"url":"https:\/\/androidstudio.googleblog.com\/2026\/02\/android-studio-panda-1-202531-now.html","type":"photo","title":"Android Studio Panda 1 | 2025.3.1 now available","site_name":"Android Studio Release Updates","display_url":"androidstudio.googleblog.com\/2026\/02\/android-studio-panda-1-202531-now.html","description":"Android Studio Panda 1 | 2025.3.1 is now available in the Stable channel.   If you already have an Android Studio build on the\u00a0 Stable chan...","thumbs":{"s":{"w":83,"h":90,"hash":"Oy8rdLZXLcKey52hG5eDhg&ts=1780145524"},"x":{"w":114,"h":124,"hash":"mnxLmFXKc_W0ls7dvRvOqw&ts=1780145524"}}}}},{"channel_id":1207457473,"post_id":1823,"date":1771013430000,"forwards":"4","views":"189","text":"Good overview of the new shadows API in Jetpack Compose. The post breaks down the updated API design and how you can use it to improve UI depth and visual polish<br><br><a target=\"_blank\" rel=\"noreferrer nofollow\" href=\"https:\/\/www.sinasamaki.com\/new-shadow-api-for-jetpack-compose\/\">https:\/\/www.sinasamaki.com\/new-shadow-api-for-jetpack-compose\/<\/a>","text_length":225,"media":{"root":"\/012\/HwcAAMFW-EcAAAAAYesnQK1CkIk","webpage":{"url":"https:\/\/www.sinasamaki.com\/new-shadow-api-for-jetpack-compose","type":"photo","title":"New Shadow API for Jetpack Compose","site_name":"sinasamaki","display_url":"sinasamaki.com\/new-shadow-api-for-jetpack-compose","description":"How to build realistic UI with the latest shadow API","thumbs":{"m":{"w":320,"h":180,"hash":"_3FjxWL3FbsMOnYnEvQzrw&ts=1780145524"},"x":{"w":800,"h":450,"hash":"iZfHziakdOF4vNYGlIj0ig&ts=1780145524"},"y":{"w":1200,"h":675,"hash":"gow_V_Wmuwa9O55xgoKr_w&ts=1780145524"},"i":{"bytes":"AXACg|DUAzS7TSA4Bqms9wrkCGUjp83Pc\/8A1qALu00hFUjdXBZW+zy5APGOD9aJLy6wdts34j\/69OwFuikzkA9KKAHUZoopAGaSiimAlFFFAH\/\/2Q=="}}}}},{"channel_id":1207457473,"post_id":1822,"date":1770145643000,"forwards":"3","views":"111","text":"Interesting read on hacking with Ktor, a blog post from Paul Samuels that explores using Ktor to build a tiny reverse proxy that forwards Snowplow events and pushes notifications over WebSockets so a debug UI can react in real time.<br><br><a target=\"_blank\" rel=\"noreferrer nofollow\" href=\"https:\/\/paul-samuels.com\/blog\/2026\/02\/02\/hacking-with-ktor\/\">https:\/\/paul-samuels.com\/blog\/2026\/02\/02\/hacking-with-ktor\/<\/a>","text_length":293},{"channel_id":1207457473,"post_id":1821,"date":1769542553000,"forwards":"12","views":"1.1K","text":"Solid reminder about Kotlin coroutines: don\u2019t call blocking code inside suspend functions. The article shows how that can freeze your coroutine scheduler and what rules the author follows to avoid it.<br><br><a target=\"_blank\" rel=\"noreferrer nofollow\" href=\"https:\/\/publicobject.com\/2026\/01\/22\/dont-block-suspend-functions\/\">https:\/\/publicobject.com\/2026\/01\/22\/dont-block-suspend-functions\/<\/a>","text_length":267,"media":{"root":null,"webpage":{"url":"https:\/\/publicobject.com\/2026\/01\/22\/dont-block-suspend-functions","type":"article","title":"Don\u2019t Block Suspend Functions","site_name":"Public Object","display_url":"publicobject.com\/2026\/01\/22\/dont-block-suspend-functions","description":"Here\u2019s a program that launches 3 jobs. The first runs forever and the other two exchange a value. @Test fun test() = runTest {   val channel = Channel<String>()   val deferredA = async {     while (isActive) {       delay(1_000)     }   }   val deferredB = async {     channel.send(\"hello\")   }   val deferredC = async {     channel.receive()   }   deferredB.await("}}}]