<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Manuel Vivo on Medium]]></title>
        <description><![CDATA[Stories by Manuel Vivo on Medium]]></description>
        <link>https://medium.com/@manuelvicnt?source=rss-3b5622dd813c------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*jIuNkwfzLBQ_EolcjHYSNg.jpeg</url>
            <title>Stories by Manuel Vivo on Medium</title>
            <link>https://medium.com/@manuelvicnt?source=rss-3b5622dd813c------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 05:55:10 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@manuelvicnt/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Mobile System Design Interview book]]></title>
            <link>https://medium.com/@manuelvicnt/mobile-system-design-interview-book-b5874008d941?source=rss-3b5622dd813c------2</link>
            <guid isPermaLink="false">https://medium.com/p/b5874008d941</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[system-design-interview]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[mobile]]></category>
            <dc:creator><![CDATA[Manuel Vivo]]></dc:creator>
            <pubDate>Mon, 09 Jun 2025 15:51:08 GMT</pubDate>
            <atom:updated>2025-06-09T15:52:09.411Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Emg4mNBTxqXuNswsqM7BPg.png" /></figure><h4>Now available worldwide with doorstep delivery 🛒✨ <a href="https://geni.us/bbg-msd">https://geni.us/bbg-msd</a></h4><p>The Mobile System Design Interview book is finally here! 🤩📚 Now available worldwide with doorstep delivery 🛒✨ <a href="https://geni.us/bbg-msd"><strong>https://geni.us/bbg-msd</strong></a></p><p>Nail your next mobile system design interview! Whether you’re facing questions like “Design YouTube” or “Build a chat app,” you’ll learn a proven framework that works for both Android and iOS platforms. Real-world case studies walk you through complete solutions step by step, covering a broad range of mobile system design topics.</p><p>This book is perfect for mobile engineers preparing for interviews and for engineering leaders, including managers and CTOs, who want to refine their architecture skills. You’ll tackle mobile-specific challenges like offline sync, performance optimization, and scalable data flow. Each chapter breaks down complex problems into manageable pieces, giving you the confidence to tackle any mobile system design question that comes your way.</p><h3><strong>Why dive in right away?</strong></h3><ul><li>🏆 Built for YOU — whether you’re a mobile engineer gearing up for interviews, a tech lead sharpening architecture skills, or an industry leader curious about mobile internals.</li><li>🔧 Practical to the core — real-world case studies, reusable checklists, and trade-off cheat sheets you can plug straight into your workflow.</li><li>💡 5-step playbook — turns any “Design X” prompt into a structured answer that speaks the interviewer’s language.</li><li>📝 7 fully solved questions — every decision, diagram, and pitfall exposed.</li><li>🔢 175 topics covering the full spectrum of mobile system design principles.</li></ul><h3><strong>Table of Contents</strong></h3><p>Chapter 1 Introduction<br>Chapter 2 A Framework for Mobile System Design Interviews<br>Chapter 3 Design a News Feed App<br>Chapter 4 Design a Chat App<br>Chapter 5 Design a Stock Trading App<br>Chapter 6 Design a Pagination Library<br>Chapter 7 Design a Hotel Reservation App<br>Chapter 8 Design the Google Drive App<br>Chapter 9 Design the YouTube app<br>Chapter 10 Mobile System Design Building Blocks<br>Quick Reference Cheat Sheet for MSD Interview</p><p>Grab your copy now ➡️ <a href="https://geni.us/bbg-msd">https://geni.us/bbg-msd</a> ➡️ Open the book ➡️ Master the framework ➡️ Tackle complex mobile design with clarity and confidence. 🚀</p><p>If it helps you land that dream role, tag me — I’ll celebrate with you! 🥂🎉</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*tX2LRQsDmXfXPq-lar1TQg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*LJH8Dki4LNDBPJ5XQ7UVtA.jpeg" /></figure><p>#MobileSystemDesign #SystemDesign #TechInterviews #AndroidDev #iOSDev #SoftwareEngineering #MobileDev #Interviews</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b5874008d941" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Interviewing at Staff+ level]]></title>
            <link>https://medium.com/@manuelvicnt/interviewing-at-staff-level-7a31836285e6?source=rss-3b5622dd813c------2</link>
            <guid isPermaLink="false">https://medium.com/p/7a31836285e6</guid>
            <category><![CDATA[technical-interview]]></category>
            <category><![CDATA[mobile-development]]></category>
            <category><![CDATA[interview-preparation]]></category>
            <category><![CDATA[staff-engineering]]></category>
            <category><![CDATA[interviewing]]></category>
            <dc:creator><![CDATA[Manuel Vivo]]></dc:creator>
            <pubDate>Tue, 12 Mar 2024 15:33:21 GMT</pubDate>
            <atom:updated>2024-03-12T15:33:21.898Z</atom:updated>
            <content:encoded><![CDATA[<p>Interviewing for Staff+ Individual Contributor (IC) level positions can be both challenging and exhilarating. As you aspire to get hired in these positions, you may find yourself grappling with uncertainties about your adaptability to new company cultures, tech stacks, and business domains. So… how should you prepare to excel at these interviews?</p><p>In this blog post, I’m covering how I prepared for various Staff level interviews at different companies. Given the versatile skill set a Staff+ position requires, each company might have their unique interview processes. You need to be flexible and ready for <em>any</em> type of interview. Staff+ positions are scarce, and there’s a fair bit of competition. Making the company wait in order to prepare for their different interviews might mean losing out to someone who was ready to impress from day one.</p><blockquote><strong>Note:</strong> It’s perfectly okay if you’re unfamiliar with Staff+ positions if you’ve recently begun your career as an IC, or if you’re simply curious about what it takes to get there. This blog post is relevant for you too <em>😊</em> Keep reading! Companies may also conduct these types of interviews at other levels.</blockquote><p>I have experience interviewing at FAANG, as well as large and medium-sized tech companies, but I won’t divulge specifics about the companies I interviewed with or the intricacies of their processes, as these can evolve rapidly. Interviewers will tell you everything you need to know at the right time. Instead, I’ll give you insights into the most common interview types: <strong>1) Data Structures and Algorithms (DS/A), 2) area of expertise </strong>(Android in my case)<strong>, 3) system design, and 4) behavioural interviews</strong>.</p><p>But in case you’re wondering… Yes, I did! I passed multiple interview processes and joined Bumble Inc. 🐝 as a Staff Android Engineer. In the upcoming sections, I’m explaining how to prepare for those 4 types of interviews, and some tips to help you nail them.</p><h3>Are you ready to be a Staff+ engineer?</h3><p>You, better than anyone, know if you’re ready to be a Staff+ engineer or if it’s a goal you’re aspiring towards. This journey to this level involves not just technical skills but also a keen understanding of leadership and impact. I wouldn’t be giving justice to the topic if I tried to give you advice in a couple of paragraphs. For that, I’m relying on amazing authors who wrote entire books about the topic.</p><p>My favourite book to understand what the role is about is <a href="https://www.goodreads.com/book/show/61058107-the-staff-engineer-s-path"><em>The Staff’s Engineer’s Path</em> by Tanya Reilly</a>. This is an authentic masterpiece. Another book you might find interesting is <a href="https://www.goodreads.com/book/show/56481725-staff-engineer"><em>Staff Engineer</em> by Will Larson</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*1A6H5s1XJEHDnLmx" /><figcaption><em>Picture of the Staff Engineer books</em></figcaption></figure><p>In a nutshell, a Staff+ IC engineer typically operates at a senior level within a company. They may have extensive technical knowledge on a particular area and often take leadership roles. They’re responsible for driving technical excellence, providing mentorship, and contributing to high-level decision-making.</p><h3>Preparing the DS/A interview</h3><p>The Data Structures and Algorithms interview is probably the most controversial one — some love it, while others hate it! I can understand why some companies choose to conduct this kind of interviews:</p><ol><li>They help refine your coding skills. You are able to translate thoughts into functional code.</li><li>A simple question can be built upon to see how the candidate reasons about, collaborates, and incorporates feedback from the interviewer.</li><li>They force you to think about a problem in a structural way.</li></ol><p>Those 3 points are crucial to succeed in a DS/A interview. Let’s go one by one.</p><h4>Improving your coding skills</h4><p>Apart from learning the different types of exercises you can face, you need to solve the problem presented to you. Getting to a working solution is indispensable. The efficiency with which you arrive at a solution and make improvements can significantly impact the depth of discussions with your interviewer, which often translates into a successful interview.</p><p>To get that efficiency, I recommend learning the most common utilities in your programming language of choice. In Kotlin, I got familiar with uncommon Collections APIs that could come in handy in some exercises. There are helpful Kotlin Collections cheat sheets you can use; for example, I used <a href="https://jussi.hallila.com/Kollections/">this one</a> by Jussi Hallila. I also refreshed my knowledge on some useful APIs like the Random API, the Mutex API, and thread-safe collections to name a few. This knowledge not only streamlines your coding but also opens avenues for more insightful discussions during the interview.</p><h4>Practising</h4><p>The best way to get better at this type of interview is by practising, practising, and more practising. Dust off that familiar green cover of <a href="https://www.goodreads.com/book/show/12544648-cracking-the-coding-interview"><em>Cracking the Coding Interview</em> by Gayle L. McDowell</a> and diligently work through the different chapters. Additionally, prove your DS/A skills on other platforms! I used <a href="https://leetcode.com/">LeetCode</a> and was quite happy with it. Go through as many exercises as possible from the <a href="https://www.techinterviewhandbook.org/grind75">Grind 75 questions</a> to gain a thorough understanding of all the possible DS/A questions. Also, do mock interviews to try those skills out in front of another human being. For this, I used <a href="https://www.pramp.com/#/">Pramp</a>: I missed some variety, but overall, it offered what I needed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*vwlAoWHJoYLo5yf-" /><figcaption><em>Picture of the Cracking the Coding Interview book and some hand-written notes in preparation for the DS/A interview</em></figcaption></figure><h4>You and the interviewer</h4><p>Different interviewers have different interview styles but the most common type I’ve seen is that interviewer who aims to understand your limits while ensuring a positive experience. In your interview, you’ll probably start with a question that has a somewhat straightforward solution using brute force.</p><p><em>How</em> you get to the solution is as important as <em>what</em> you type. Think out loud and discuss different alternatives with your interviewer: their trade-offs, their time and space complexities, possible improvements, etc. The best advice I can give you is to actively listen to your interviewer’s feedback and apply it to your approach. Unless you find yourself in an unusual circumstance, most interviewers genuinely want to see you succeed! They are likely to offer hints or guidance to help you navigate the problem.</p><h4>Structure your way to solve the problem</h4><p>To tackle a specific problem, I follow the problem-solving structure outlined in <em>Cracking the coding interview </em>book: <strong>Listen, think of edge cases, brute force, optimise, walk through your approach, implement, and test</strong>.</p><p>In my preparation for Staff positions, I found <a href="https://adambennett.dev/2021/11/on-interviewing/">Adam Bennet’s <em>On interviewing</em> blog post</a> a valuable resource. In particular, I enjoyed his Github project, containing gems like the <a href="https://github.com/ditn/interviewprep/blob/main/Common%20Strategies.md">common strategies for DS/A interview problems</a>.</p><h3>Preparing the Android (or your area of expertise) interview</h3><p>Android interviews can take diverse formats. You may be tasked with building an app on the spot, improving an existing app, identifying and fixing intentional bugs in the codebase, or completing a home assessment that you subsequently discuss during the interview.</p><p>If you need to complete a home assessment, I highly recommend reading <a href="https://blog.blundellapps.co.uk/android-job-interview-take-home-test-cheat-sheet/">Paul Blundell’s Android interviews blog post</a>. Also, look at his <a href="https://github.com/blundell/polkiemon">implementation of one of those home assessment apps</a> and learn how to implement pagination on your own.</p><p>If you’re tasked with building an app from scratch during the interview, practice creating a simple app with two screens — a list and a detail screen — using an MVx architecture. If you need to improve an existing application, I relied on the above mostly. The rest of my preparation came with my experience as an Android developer.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*0PNj8LT7bw1Xmn23" /><figcaption><em>Picture of the Head First Design Patterns book and some hand-written notes in preparation for the Android interview</em></figcaption></figure><p>Given my confidence in topics like Architecture, Dependency Injection, Jetpack Compose, or threading, I didn’t prepare much about them. However, it’s advisable to find out about the company’s Android tech stack and get to know those tools and how they align with your existing knowledge.</p><h3><strong>Preparing the System design interview</strong></h3><p>The system design interview is my favourite one by far. You might think they don’t require that much preparation, but they do if you want to nail them. Call me systematic, but I believe these interviews also benefit from a methodical strategy.</p><p>When facing a system design problem, it’s crucial to know which questions to ask upfront. The key is to ask questions in a logical sequence, adjusting your choices based on the information gathered. I usually start gathering requirements from the interviewer to understand what we’re building and for whom. Ask for both functional and non-functional requirements such as Daily Active Users (DAU), authentication, offline mode, pagination, etc.</p><p>Then, you can make informed decisions and dive into the details of choosing the right network protocol (e.g. REST, gRPC, GraphQL, etc.) and defining the data models based on the business requirements and the end points to communicate with the backend.</p><p>I had <a href="https://topmate.io/manuelvivo/799730">cheat sheets</a> with questions based on priority (i.e. what to ask first), and other cheat sheets based on topics such as performance, networking, data management, etc. Remember that system design problems might not always have a single right answer. Engage in dialogue, discuss trade-offs, and work towards a shared understanding with your interviewer.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*DNyKKiDZ0xt3iL4R" /><figcaption><em>Picture of the System Design Interview and Designing Data-Intensive Applications books and some hand-written notes in preparation for the System design interview</em></figcaption></figure><h4><strong>Mobile system design interview</strong></h4><p>If you’re in mobile app development, the go-to resource for acing the system design interview is <a href="https://github.com/weeeBox/mobile-system-design">Alex Lementuev’s<em> Mobile system design</em> Github project</a>. This comprehensive repository contains everything you need to succeed in this type of interview. Pay particular attention to the pros and cons outlined for the different topics, as that’s indispensable to justify your decision-making. Apart from learning the different choices you can make, this resource also helps you structure the way you approach the interview. To see how to apply that knowledge in an actual interview, check out the <a href="https://www.youtube.com/watch?v=PYsXmMt5Kdw&amp;list=PLaMN-JyH50OYAfxJEpiQTYTD-gxTf7x9d">mock interviews in his Youtube channel</a>. I highly recommend observing how people approach the problems.</p><p>When covering the Architecture of the mobile app, think about the <a href="https://developer.android.com/topic/architecture">recommended layered Android architecture</a> and <a href="https://developer.android.com/topic/architecture#unidirectional-data-flow">Unidirectional Data Flow (UDF)</a>.</p><p>Apart from this, I read content from the <a href="https://blog.bytebytego.com/archive">ByteByteGo newsletter</a> and the System design interview books (<a href="https://www.goodreads.com/book/show/54109255-system-design-interview-an-insider-s-guide">1</a>, <a href="https://www.goodreads.com/book/show/60631342-system-design-interview-an-insider-s-guide">2</a>) by <a href="https://twitter.com/alexxubyte">Alex Xu</a>, refresh the different design patterns, and read the <a href="https://www.goodreads.com/book/show/23463279-designing-data-intensive-applications">Designing Data-Intensive Applications book by Martin Kleppmann</a>.</p><p>As with any other interview type, you need to practice, practice, and more practice. Find a feature of your favourite app and think about how you would design it. For more inspiration, you can see the exercises listed in the <a href="https://github.com/weeeBox/mobile-system-design/tree/master/exercises">Mobile system design project</a> mentioned above.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*NaOi_jXXwtzPqge1" /><figcaption><em>Hand-written completed exercises in preparation for the Mobile system design interview</em></figcaption></figure><h3>Preparing the behavioural interview</h3><p>To prepare for the behavioural interview, you can follow the approach outlined in <em>Cracking the Coding Interview</em> book. Prepare a table with your most important projects and systematically reflect on key aspects. For example: what was most challenging, what you learned, what was most interesting, the hardest bug, what you enjoyed the most, conflicts, what you’d do differently, leadership, and failures.</p><p>Other questions can be: a time when you learned a valuable lesson, your ability to move the team forward, to have an influence outside of your team, passion for wanting to make things happen, a time when your performance exceeded expectations, a time when you received a performance review that you felt was unjustified, etc.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*DyX7T0AlrGhj5oMG" /><figcaption><em>Table with a TL;DR; of my involvement in different professional projects</em></figcaption></figure><p>Remember that the interview is a Staff+ role. Focus on expertise, leadership, and impact. You should be able to give examples of how the work you did linked to business impact, how you acted like a multiplier for other developers, and demonstrate that you’re thinking about business outcomes alongside technical expertise. This structured approach ensures that you’re well-prepared to articulate your experiences, achievements, and challenges during the behavioral interview.</p><p>Here’s the best tip ever: <strong>DO NOT LIE!</strong> Honesty is key throughout the interview process. Even if you manage to succeed by providing inaccurate information, it can lead to misunderstandings when you join the team. But don’t be shy either! It’s your interview and your moment to shine ⭐. You need to sell yourself. Focus on your personal achievements and what <em>you</em> contributed to the projects.</p><h4>Refining your leadership style</h4><p>Leadership comes with experience, but refining your leadership style can be accelerated by applying insights from relevant books. In addition to the Staff engineer books I mentioned in the introduction, consider exploring the following books that I enjoyed a lot:</p><ul><li><a href="https://www.goodreads.com/book/show/33517721-the-culture-code">The Culture Code by Daniel Coyle</a>: learn different skills to build an exceptional team. Focus on creating a culture of safety, sharing vulnerability, and establishing a clear sense of purpose.</li><li><a href="https://www.goodreads.com/book/show/15014.Crucial_Conversations">Crucial Conversations by Kerry Patterson</a>: learn essential techniques for what to do before opening your mouth, how to open your mouth, and how to bring the conversation to a constructive conclusion.</li><li><a href="https://www.goodreads.com/book/show/22085568-the-culture-map">The Culture Map by Erin Meyer</a>: understand and navigate cultural differences in this insightful and practical guide, perfect for both your work and personal life.</li><li><a href="https://www.goodreads.com/book/show/123857637-never-split-the-difference">Never Split the Difference by Chris Voss</a>: discover negotiation skills to listen, empathise, and get the most out of your conversations with people.</li><li><a href="https://www.goodreads.com/book/show/29939161-radical-candor">Radical Candor by Kim Scott</a>: learn how to care personally while challenging your team directly to get optimal performance.</li></ul><p>As you read these books, use your own judgement to select and implement the ideas that resonate with you. <strong>Authenticity is key</strong>. Adapt and apply the lessons in a way that aligns with your unique leadership style.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*DAyEHA18FFjsySLw" /><figcaption><em>Image with books to refine your leadership style</em></figcaption></figure><h3><strong>Conclusion</strong></h3><p>Preparing for Staff+ IC level interviews requires a multifaceted approach that includes technical, behavioural, and leadership aspects. The journey involves navigating through various interview formats, from DS/A to system design and behavioural assessments.</p><p>Embracing a structured preparation strategy is essential: learn about the different topics, choose your own strategy, practice with mock interviews, listen actively, and work with your interviewer toward the best possible solution.</p><p>Take the time to prepare for the 4 different interviews properly. Plan your time as it works for you. You can spend a couple of weeks on each interview to deep dive into the different aspects of it. And when the interviews are getting closer, maybe you can keep studying one type a day.</p><p>What makes you unique is your own strengths and experiences. Even if you learn a lot from external resources, tint your interviews with personal anecdotes and learnings. That will make those special, and you’ll be able to stand out from the crowd.</p><p>Lastly, when facing interviews… Have fun! Look at those problems as opportunities that you’re genuinely willing to overcome. You’re a capable and confident professional with a wealth of knowledge and skills. You got this! Best of luck on your interview journey!</p><h3>[Bonus] You got the job!</h3><p>Congratulations on landing the job! Before starting your new position, I’d recommend reading <a href="https://www.goodreads.com/book/show/15824358-the-first-90-days">The First 90 days book by Michael Watkins</a>. This book can help you onboard into your new position. Even if the company has its own onboarding plan, prepare your personal journey and run both in tandem.</p><p>Oh, and here’s a friendly reminder: show some love to your new colleagues and their code. No judgments! Everything they’ve done has a story. You’re there to level up the game, not to rain on anyone’s parade. Cheers to your new adventure! 🚀</p><p>Good luck! 🍀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7a31836285e6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Crash course on the Android UI layer | Part 2]]></title>
            <link>https://medium.com/bumble-tech/crash-course-on-the-android-ui-layer-part-2-2335171467e0?source=rss-3b5622dd813c------2</link>
            <guid isPermaLink="false">https://medium.com/p/2335171467e0</guid>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[viewmodel]]></category>
            <category><![CDATA[architecture]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[ui]]></category>
            <dc:creator><![CDATA[Manuel Vivo]]></dc:creator>
            <pubDate>Tue, 19 Dec 2023 15:58:45 GMT</pubDate>
            <atom:updated>2023-12-19T17:48:51.873Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*o9fyij_f7ruXQqxCxXL1Cg.png" /></figure><h3>Crash Course on the Android UI Layer | Part 2</h3><h4>State Holders and Saving State</h4><p>This blog post series aims to summarise the <a href="https://developer.android.com/topic/architecture/ui-layer">Android Developer guidance on the UI layer</a>. We’ll explore all the entities involved in it, understand the role each part plays, and discuss best practices.</p><blockquote>By the end of this series, you will have a general understanding of what happens on the UI layer and how to best handle state and logic within it, the various APIs involved, and how to use them. Additionally, we’ll provide decision trees to assist you when you’re in doubt.</blockquote><p><a href="https://medium.com/bumble-tech/crash-course-on-the-android-ui-layer-part-1-2094221a9be3">In <strong>part 1</strong></a>, we covered the UI and the UI state. You should already know the different entities present on the UI layer, and how to think about the UI and UI state effectively.</p><p><a href="https://medium.com/bumble-tech/crash-course-on-the-android-ui-layer-part-1-2094221a9be3">Crash course on the Android UI layer | Part 1</a></p><p>Now it’s <strong>time for Part 2</strong>! We’ll cover state holders and other UI layer-related topics such as where to hoist state and save UI state on Android.</p><p><em>If you prefer to consume this content in video format, check out the talk I delivered at Droidcon London 2023:</em></p><p><a href="https://www.droidcon.com/2023/11/15/peeling-back-the-layers-unmasking-the-ui-nknown/">Peeling Back the Layers: Unmasking the UI-nknown!</a></p><h3>State holders</h3><p>State holders simplify the UI by handling logic and/or exposing UI state. In this section, we’ll see how to implement state holders and the implementation details to consider.</p><p>To determine the implementation details, we first need to identify the types of logic commonly found in an Android app.</p><h4>Types of logic</h4><p>We have already discussed that <strong>business logic</strong> involves implementing the product requirements that specify how application data is created, stored, and modified. When business logic is present in the UI layer, it’s recommended to manage this logic at the screen level. We’ll see more of this later.</p><p>Another type of logic is the <strong>UI logic</strong>. UI logic determines <em>how</em> to display state changes on the screen. While business logic dictates <em>what</em> to do with data, UI logic determines <em>how</em> to visually display it. The UI logic is dependent on the UI configuration.</p><p>For instance, in a typical app, displaying a details screen may involve navigation when the app is running on a phone. However, it could entail showing an element next to another when running on a tablet.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*80F6wmsQwYpJBgTm" /><figcaption><em>UI logic depends on the UI configuration. Displaying a details screen may involve navigation when the app runs on a phone or showing an element next to another when running on a tablet. You can see that in the </em><a href="https://github.com/android/nowinandroid"><em>Now in Android</em></a><em> interests screen.</em></figcaption></figure><p>The different types of logic respond differently to configuration changes:</p><ul><li><strong>UI logic should re-execute</strong> if it’s affected by a configuration change.</li><li><strong>Business logic should generally continue</strong> after a configuration change.</li></ul><p>For instance, the UI logic that determines whether to display the bottom bar or the navigation rail should be re-executed or re-evaluated after a screen size configuration change. On the other hand, the business logic for following a particular interest or refreshing them shouldn’t be cancelled or restarted simply because the user rotated or unfolded the device. Such interruption wouldn’t provide a good user experience.</p><h4>Where to handle that logic</h4><p>Business logic on the UI layer should be handled as close as possible to the screen level. Most of the business logic is handled by the data layer. Thus, keeping it close to the screen makes it easier to scope the logic correctly and prevents low-level UI components from becoming tightly coupled to the business logic.</p><p><strong>Business logic should be handled by the screen level state holder</strong>, which would normally extend from <a href="https://developer.android.com/topic/libraries/architecture/viewmodel">androidX.ViewModel</a>.</p><p>When it comes to UI logic, it’s acceptable to manage it within the UI itself if the logic and state involved are relatively straightforward. However, when the UI becomes more complicated, it’s a good idea to <strong>delegate that UI logic complexity to a plain class state holder</strong>. In this case, the state holder wouldn’t extend from androidX.ViewModel.</p><p>We’ll see more of this in the upcoming sections! Now, let’s see how the different types of state and logic related to each other:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*8CXKmUDa0uS7H25f" /><figcaption><em>Diagram of how data flows in the app and the type of logic applied</em></figcaption></figure><p>As a summary of what happens on a typical screen, the data layer exposes application data to the rest of the hierarchy. The ViewModel then applies business logic to that data to produce the screen UI state. The UI itself or a plain state holder class observes the screen UI state to modify UI elements or its state.</p><h3>Handling business logic — androidX.ViewModel</h3><p>We’ve discussed the androidX.ViewModel or <a href="https://developer.android.com/topic/libraries/architecture/viewmodel">Architecture Components </a><a href="https://developer.android.com/topic/libraries/architecture/viewmodel">ViewModel</a> class quite extensively as the implementation detail of a screen-level state holder.</p><p>In the code snippet below, we can observe its main functionalities: 1) exposing the screen UI state and 2) handling business logic.</p><pre>@HiltViewModel<br>class InterestsViewModel @Inject constructor(<br>  private val userDataRepository: UserDataRepository,<br>  authorsRepository: AuthorsRepository,<br>  topicsRepository: TopicsRepository<br>) : ViewModel() {<br><br>  val uiState: StateFlow&lt;InterestsUiState&gt; = ...<br><br>  fun followTopic(followedTopicId: String, followed: Boolean) {<br>    viewModelScope.launch {<br>      userDataRepository.toggleFollowedTopicId(followedTopicId, followed)<br>    }<br>  }<br><br>  ...<br>}</pre><p>But why is the ViewModel the right place for this?</p><h4>androidX.ViewModel benefits</h4><p>The main benefit is that <strong>ViewModel survives configuration changes</strong>, offering a longer lifetime than the screen itself. You can scope a ViewModel to an Activity, Fragment, Navigation graph or the destination of a Navigation graph. When a configuration change happens, the system provides the <em>same</em> instance of the ViewModel.</p><p>Surviving configuration changes makes androidX.ViewModel the perfect place to expose the screen UI state and handle business logic. The screen UI state is also cached and instantly available before and after a configuration change. And business logic will continue executing if it was initiated with a ViewModel-scoped CoroutineScope (e.g. <a href="https://medium.com/androiddevelopers/easy-coroutines-in-android-viewmodelscope-25bffb605471">viewModelScope</a>).</p><p>Another advantage lies in its <strong>seamless integration with other Jetpack libraries</strong>, particularly with <a href="https://developer.android.com/guide/navigation">Jetpack Navigation</a>. Navigation retains the same instance of a ViewModel in memory when the destination is part of the back stack. This enables you to navigate back and forth between destinations in the back stack, with the data instantly available on the screen, without the need to reload the data every time you navigate back to that destination.</p><p>Jetpack Navigation also automatically destroys the instance of a ViewModel when the destination is no longer part of the back stack. Making it safe to go to a previous destination without seeing the previous user data on the screen.</p><p>Other Jetpack integrations include <a href="https://developer.android.com/training/dependency-injection/hilt-android">Hilt</a>. By using the @HiltViewModel annotation, you can effortlessly obtain ViewModels with dependencies from the domain or data layers.</p><h4>androidX.ViewModel best practices</h4><p>ViewModel’s scoping is what makes this type suitable as an implementation detail of a screen-level state holder. However, this power shouldn’t be abused. Here are some best practices to keep in mind when using this class:</p><ul><li><strong>Use it at the screen level</strong>. Avoid using a ViewModel to handle the complexity of <em>reusable</em> UI elements. Due to its scoping, the same UI elements under the same ViewModel scope would get the <em>same</em> instance of a ViewModel. In most cases, this is undesirable.</li><li><strong>Make the ViewModel generic enough to accommodate any UI form factor</strong>. The ViewModel should not be aware of which UI is using it. Keep the ViewModel’s API surface (exposed Screen UI state and functions exposed) representative of the application data it handles, rather than including UI-specific details. For example, when indicating that data is loading, the screen UI state might contain a field called isLoading rather than showLoadingSpinner. How the UI communicates data loading to the user is only relevant to the UI.</li><li><strong>Don’t hold references to lifecycle-related APIs</strong>. The ViewModel has a longer lifetime than the UI, and retaining references to Context or Resources objects can lead to memory leaks.</li><li><strong>Don’t pass ViewModels around</strong>. Considering all the points mentioned, keep the ViewModel class as close as possible to the screen level. Otherwise, you might inadvertently provide low-level components with access to more state and logic than they actually need.</li></ul><h4>androidX.ViewModel gotchas</h4><p>Not everything is perfect in the ViewModel realm. There are certain considerations to keep in mind when using this API, especially in regard to ViewModel’s viewModelScope:</p><ul><li>Work initiated using <strong>viewModelScope continues to execute while the ViewModel is in memory</strong>. That’s good but can also lead to issues if the work runs for an extended period. For long-running work that might take more than 10 seconds to complete, consider other alternatives such as <a href="https://developer.android.com/guide/background/persistent/getting-started">WorkManager</a>. More about <a href="https://developer.android.com/guide/background">background work in the docs</a>.</li><li>Unit testing work triggered by viewModelScope requires some additional setup in the testing environment. The MainDispatcher must be <a href="https://developer.android.com/kotlin/coroutines/test#setting-main-dispatcher">replaced</a> in tests.</li></ul><h4>Using androidX.ViewModel</h4><p>Does this section mean you always need to use ViewModel? Well, as the implementation of a screen-level state holder, yes, but only if the benefits apply to your app.</p><p>If you care about configuration changes (which, you should!) and/or you’re using other Jetpack libraries, it might make sense to use it. However, even if you decide not to, consider introducing a plain screen-level state holder class to handle the business logic complexity at the screen level.</p><h3>Handling UI logic — Plain state holder class</h3><p>You should <strong>introduce a state holder class when your UI starts growing in complexity</strong>. The threshold depends on you and your team. It’s a matter of when you feel the need to simplify the UI.</p><p>In the upcoming code snippet, there’s no immediate need to create a state holder for the UI. It merely contains an expanded boolean that is modified when the user interacts with the UI.</p><pre>@Composable<br>fun &lt;T&gt; NiaDropdownMenuButton(items: List&lt;T&gt;, ...) {<br>  var expanded by remember { mutableStateOf(false) }<br><br>  Box(modifier = modifier) {<br>    NiaOutlinedButton(<br>      onClick = { expanded = true },<br>      ...<br>    )<br>    NiaDropdownMenu(<br>      expanded = expanded,<br>      onDismissRequest = { expanded = false },<br>      ...<br>    )<br>}</pre><p>When the UI requires more state and the associated logic becomes more complex, introduce a state holder. This is precisely what the Compose library does for some of its components. The following code snippet belongs to the <a href="https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt;l=118">state holder of the various Drawer composables</a>:</p><pre>@Stable<br>class DrawerState(<br>  initialValue: DrawerValue,<br>  confirmStateChange: (DrawerValue) -&gt; Boolean = { true }<br>) {<br>  internal val swipeableState =  SwipeableState(...)<br><br>  val currentValue: DrawerValue<br>    get() { return swipeableState.currentValue }<br><br>  val isOpen: Boolean<br>    get() = currentValue == DrawerValue.Open<br><br>  suspend fun open() = animateTo(DrawerValue.Open, AnimationSpec)<br><br>  suspend fun animateTo(targetValue: DrawerValue, anim: AnimationSpec&lt;Float&gt;) {<br>    swipeableState.animateTo(targetValue, anim)<br>  }<br>}</pre><p>A few points to observe there:</p><ul><li>It holds state such as the currentValue of the Drawer.</li><li>State holders are composable. DrawerState internally depends on another state holder: SwipeableState.</li><li>It manages UI logic, including actions like opening the drawer and animating to a specific value.</li></ul><p>Just as Compose offers these state holders, you can implement similar patterns in your project to simplify the UI. The following code snippet belongs to <a href="https://github.com/android/nowinandroid/blob/main/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt">NiaAppState</a>, the state holder of the <a href="https://github.com/android/nowinandroid/blob/main/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt">NiaApp</a> composable function.</p><pre>@Stable<br>class NiaAppState(<br>  val navController: NavHostController,<br>  val windowSizeClass: WindowSizeClass<br>) {<br>  val currentDestination: NavDestination?<br>    @Composable get() = navController<br>      .currentBackStackEntryAsState().value?.destination<br><br>  val shouldShowBottomBar: Boolean<br>    get() = windowSizeClass.widthSizeClass == WindowWidthSizeClass.Compact ||<br>      windowSizeClass.heightSizeClass == WindowHeightSizeClass.Compact<br><br>  fun navigate(...) { ... }<br><br>  fun onBackClick() { ... }<br>}</pre><p>In a similar fashion, it exposes UI state such as the currentDestination and whether or not to show the bottom bar, while also managing UI logic like navigating and handling back-click events.</p><blockquote>Note: In Compose, the naming convention for state holders is to end with State. That’s why we’re naming the classes NiaAppState and DrawerState.</blockquote><h4>Plain state holder classes best practices</h4><p>It’s actually recommended to create a state holder for <em>reusable</em> UI components. This enhances the reusability of the UI and provides external control.</p><p><strong>Plain state holder classes can hold references of lifecycle-related APIs</strong>. These instances follow the UI lifecycle. When the UI goes through a configuration change, a new instance of the state holder is created. Thus, it’s acceptable to hold references to Context or Resources because there won’t be any memory leaks. In Jetpack Compose, these state holders are also scoped to the Composition.</p><p>If your plain class requires business logic, it’s a good practice to inject that functionality into the class. Whoever injects this functionality can ensure it outlives the UI scope.</p><h4>Handling large ViewModels</h4><p>If a ViewModel is handling the business logic complexity of several sizeable UI elements, it could potentially become large and challenging to manage and reason about. How could we simplify the ViewModel?</p><ol><li><strong>Introduce the domain layer</strong>. Delegate the business logic complexity of the ViewModel to <em>use cases</em> that handle interactions with different repositories. However, this approach may still result in a ViewModel with a substantial list of use cases to depend on.</li><li><strong>Create multiple state holders</strong> for the various elements of the UI and hoist them in the ViewModel so that they can get all its benefits. The ViewModel essentially becomes a state hoisting mechanism that survives configuration changes.</li><li>Instead of #2, you might consider creating <strong>multiple ViewModels</strong> to manage the complexity of those non-reusable UI elements. While this approach is acceptable, bear in mind that ViewModels operate with unbounded memory, and when you have multiple ViewModels, it can become challenging to monitor their size and memory footprint.</li></ol><h3>Where to hoist state</h3><p>You should <strong>place state in the lowest common ancestor</strong> that reads or writes the state.</p><p>As a recap: In the UI, you might 1) not have state at all, 2) have state in the UI itself, 3) have state in a state holder in order to simplify the UI, 4) hoist the state higher up in the UI tree so that other composable callers or ancestors can control the state, 5) hoist the state in a ViewModel if it’s needed by business logic.</p><p><strong>If the state is required by business logic, whether for reading or writing, it should be hoisted in the screen-level state holder. If not, it should be placed in the appropriate node of the UI tree.</strong></p><p>Let’s take a look at the UI hierarchy of a typical Chat app and discuss why certain state is placed where it is:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*xmfIjnmbUMR-Pwvs" /><figcaption><em>UI tree of a typical Chat app</em></figcaption></figure><ul><li>The screen UI state should be placed in the ViewModel (#5) because the ViewModel applies business logic to create it.</li><li>The LazyList is part of the ConversationScreen and not the MessagesList because the screen has additional functionality that require that state, such as scrolling to the most recent messages when the user sends a new message in UserInput.</li></ul><p>To learn more about this topic, check out the <a href="http://goo.gle/android-arch-hoist-state">State hoisting in Compose talk</a> by <a href="https://twitter.com/astamatok">Alejandra Stamato</a>.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FhWwZ_AuSGfo%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DhWwZ_AuSGfo&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FhWwZ_AuSGfo%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/d3229697d9d4bff8f3ff76ddb77ad895/href">https://medium.com/media/d3229697d9d4bff8f3ff76ddb77ad895/href</a></iframe><h3>Saving UI state</h3><p>In this blog post, we’ve explored the androidx.ViewModel API as a means to preserve state across configuration changes. However, Android provides additional alternatives to safeguard your state even more effectively.</p><p>The <strong>SavedState APIs enable your state to persist through configuration changes <em>and</em> </strong><a href="https://developer.android.com/topic/libraries/architecture/saving-states"><strong>system-initiated process death</strong></a>. The system stores this data in a Bundle, requiring the data to be parcelized for storage. Typically, you’d store <em>transient</em> UI state that depends on user input or navigation.</p><p>Ultimately, to survive not only the above but also unexpected app dismissals (e.g. the user killing your app), you can use <strong>persistent storage</strong>. This is subject to disk space limitations and is typically used for storing application data.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*R3WwfHCqL7YWNYkJ" /><figcaption><em>Summary of the different APIs to save UI state on Android</em></figcaption></figure><p>For more information about this topic, check out the <a href="http://goo.gle/android-arch-saving-state">Saving UI state on Android talk</a>.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FV-s4z7B_Gnc&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DV-s4z7B_Gnc&amp;image=http%3A%2F%2Fi.ytimg.com%2Fvi%2FV-s4z7B_Gnc%2Fhqdefault.jpg&amp;key=d04bfffea46d4aeda930ec88cc64b87c&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/72ea3dce3f29fb1427e9adfb463e89db/href">https://medium.com/media/72ea3dce3f29fb1427e9adfb463e89db/href</a></iframe><h3>Conclusion</h3><p>After reading this crash course on the UI layer, you should have a general understanding of the processes occurring within this layer and the tools required to manage state and logic effectively.</p><p>How Android is designed to make your app reactive to different UI Configurations and devices makes some API decision trees more complex than some Developers might like. But at the same time, it also gives you the tools to make your app behave as expected, delivering a great user experience.</p><p>Hope you enjoyed this read! Feel free to share your thoughts or ask questions in the comments section! Thank you 😊</p><p><em>Remember that if you prefer to consume this content in video format, check out the talk I delivered at Droidcon London 2023:</em></p><p><a href="https://www.droidcon.com/2023/11/15/peeling-back-the-layers-unmasking-the-ui-nknown/">Peeling Back the Layers: Unmasking the UI-nknown!</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2335171467e0" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bumble-tech/crash-course-on-the-android-ui-layer-part-2-2335171467e0">Crash course on the Android UI layer | Part 2</a> was originally published in <a href="https://medium.com/bumble-tech">Bumble Tech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Crash course on the Android UI layer | Part 1]]></title>
            <link>https://medium.com/bumble-tech/crash-course-on-the-android-ui-layer-part-1-2094221a9be3?source=rss-3b5622dd813c------2</link>
            <guid isPermaLink="false">https://medium.com/p/2094221a9be3</guid>
            <category><![CDATA[viewmodel]]></category>
            <category><![CDATA[ui]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[architecture]]></category>
            <category><![CDATA[state-management]]></category>
            <dc:creator><![CDATA[Manuel Vivo]]></dc:creator>
            <pubDate>Wed, 13 Dec 2023 17:03:40 GMT</pubDate>
            <atom:updated>2023-12-19T16:47:25.398Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VweJsmzGEFlGT7BmjIHCgg.png" /></figure><h3>Crash Course on the Android UI Layer | Part 1</h3><h4>The UI and UI State</h4><p>This blog post series aims to summarise the <a href="https://developer.android.com/topic/architecture/ui-layer">Android Developer guidance on the UI layer</a>. We’ll explore all the entities involved in it, understand the role each part plays, and discuss best practices.</p><blockquote>By the end of this series, you will have a general understanding of what happens on the UI layer and how to best handle state and logic within it, the various APIs involved, and how to use them. Additionally, we’ll provide decision trees to assist you when you’re in doubt.</blockquote><p>This is <strong>part 1</strong>, where we’re covering the UI and the UI state. <a href="https://medium.com/bumble-tech/crash-course-on-the-android-ui-layer-part-2-2335171467e0"><strong>Part 2</strong> covers state holders</a> and other UI layer-related topics such as where to hoist state and save state on Android.</p><p><em>If you prefer to consume this content in video format, check out the talk I delivered at Droidcon London 2023:</em></p><p><a href="https://www.droidcon.com/2023/11/15/peeling-back-the-layers-unmasking-the-ui-nknown/">Peeling Back the Layers: Unmasking the UI-nknown!</a></p><h3>The UI layer in the grand scheme of things</h3><p>The UI layer isn’t the only layer you can find in a <a href="https://developer.android.com/topic/architecture#modern-app-architecture">typical app architecture</a>. Alongside it, you can also find the <a href="https://developer.android.com/topic/architecture/data-layer">data layer</a> and sometimes, the <a href="https://developer.android.com/topic/architecture/domain-layer">domain layer</a>. According to the <a href="http://goo.gle/mad-architecture-guide">Android Architecture documentation</a>:</p><ul><li>The <strong>UI layer</strong> displays data on the screen.</li><li>The <strong>data layer</strong> exposes application data and contains the vast majority of the business logic of the app.</li><li>The <strong>domain layer</strong> is an <em>optional</em> layer that aims to 1) simplify and 2) reuse the potential business logic complexity of the UI layer. No less, no more.</li></ul><blockquote><strong>Note:</strong> The business logic is what gives value to your application. It’s the implementation of product requirements that determines how your app fetches, stores, and modifies data.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ZairCESe0pa1HoXi" /><figcaption><em>Architecture layers in a typical Android app: The UI, data, and domain layers</em></figcaption></figure><h3>Entities in the UI layer</h3><p>The UI layer consists of three distinct entities with clearly defined responsibilities. This distinction helps with separation of concerns, enhances testability, and promotes reusability.</p><ul><li>The <strong>UI</strong>, or<strong> UI elements</strong>, render data on the screen.</li><li>The <strong>UI state</strong> describes the data to render on the screen. If the UI represents what the user sees, the UI state is what the app specifies the user should see.</li><li>An optional <strong>state holder</strong> is introduced to simplify the UI by managing a portion of its logic, holding its UI state, and exposing it to the UI. State holders are employed when the complexity of state and logic within the UI increases, making it more challenging to reason about.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*74IE2H3R85Y5FvK7" /><figcaption><em>Entities in the UI layer: The UI, UI state, and state holder</em></figcaption></figure><h3>Unidirectional data flow</h3><p>However, an app doesn’t show static information. Users regularly interact with it to perform operations that could potentially modify the application state. User events are typically handled by the state holder, and after processing them, they may result in a change in the UI state. In such cases, the UI state is not static. The state holder would expose a stream of UI state, and its emissions would be immediately reflected in the UI. This concept is also referred to as <a href="https://developer.android.com/topic/architecture#unidirectional-data-flow"><strong>Unidirectional Data Flow</strong></a><strong> (UDF)</strong> in the documentation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YEnUkdclWHtQJ9Y-3XYQRA.png" /><figcaption><em>In Unidirectional Data Flow, Events flow from the UI to the state holder, and state flows from the state holder to the UI</em></figcaption></figure><h3>The UI</h3><p>The guidance in the <a href="https://developer.android.com/topic/architecture/ui-layer">documentation</a> and this blog post <strong>applies to both the View system and Jetpack Compose</strong>. The role of the UI in the UI layer remains independent of your choice of UI toolkit.</p><p>When considering the UI layer, Developers tend to imagine the UI layer just at the screen level — that part of the UI tree that shows application data in most parts of the available display. And typically, Developers use the <a href="https://developer.android.com/topic/libraries/architecture/viewmodel">androidx.ViewModel</a> as a state holder implementation detail.</p><p>However, just as you create “multiple” data layers for handling different types of data (e.g. PaymentsRepository, UserRepository, etc.), you have the flexibility to introduce UI layer entities at any point in the UI tree, or UI hierarchy, where they are needed. The granularity of this decision depends on the complexity of your UI.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*YHVGowVcvnfzNDX3" /><figcaption><em>You can introduce the different entities in the UI layer in any part of the UI tree. For example, in the screen, the navigation rail, or simply in a button.</em></figcaption></figure><p>As we’ll see in the state holder sections, you can introduce a state holder at any point within the UI tree to simplify the UI. In fact, this is recommended in certain scenarios.</p><h3>The UI state</h3><p>The UI state describes the information to be displayed on the screen. In this section, we’ll see how to model, produce, and observe the UI state.</p><h4>Types* of UI state</h4><p>There’s a <em>subtype</em> of UI state that usually requires special treatment—the <strong>Screen UI state</strong>. This is often derived from the application state exposed from the data layer. This shout-out is because it contains most of the information displayed on the screen, which aligns with what the user is usually most interested in.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*zkmV3EonmIUXMrvM" /><figcaption><em>As a special type of UI state, the Screen UI state usually contains application data exposed by the data layer</em></figcaption></figure><p>As a sneak peek of what’s to come later, it’s important to note that the Screen UI state should persist or be cached across configuration changes.</p><h3>How to produce UI state</h3><p>Producing UI state is the <strong>output of the state holder processing some inputs</strong>. These inputs can be: 1) events, 2) local sources of state change, or 3) external sources of state change.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*-zaIt01jYGq2txp3" /><figcaption><em>The UI state is the output of the state holder processing some inputs</em></figcaption></figure><p>Which APIs should we use in different cases?</p><ul><li>The UI state should be exposed as an <strong>observable data holder</strong> class (e.g. StateFlow, Compose State&lt;T&gt;, or LiveData). This type ensures that the UI always has a UI state to render on the screen.</li><li>Inputs can take various forms, primarily as streams of data or one-shot APIs.</li></ul><p>Let’s see some examples of this!</p><h4><strong>Producing UI state with local source of state change</strong></h4><p>Imagine we’re on a screen that allows the user to roll two dice. Besides displaying the dice values, we also want to keep track of how many times the user rolls the dice. Our UI state could look like the following:</p><pre>data class DiceRollUiState(<br>  val firstDiceValue: Int? = null<br>  val secondDiceValue: Int? = null<br>  val numberOfRolls: Int = 0<br>)</pre><p>The business logic for rolling the dice is implemented through a one-shot call to the Random API.</p><pre>firstDiceValue = Random.nextInt(1..6),<br>secondDiceValue = Random.nextInt(1..6),<br>numberOfRolls = currentUiState.numberOfRolls + 1</pre><p>So, how do we hold this UI state in the state holder? Creating an observable data holder class! In this example, we’re using the MutableStateFlow API to achieve this. To avoid direct dependencies on the Random API, which could potentially impact reusability and testability, we introduce a more generic RandomProvider interface, with its implementation being the Random API.</p><pre>class DiceRollStateHolder(<br>  private val randomProvider: RandomProvider<br>) {<br><br>  private val _uiState = MutableStateFlow(DiceRollUiState())<br>  val uiState: StateFlow&lt;DiceRollUiState&gt; = _uiState.asStateFlow()<br><br>  fun rollDice() {<br>    _uiState.update { currentState -&gt;<br>      currentState.copy(<br>        firstDiceValue = randomProvider.nextInt(1..6),<br>        secondDiceValue = randomProvider.nextInt(1..6),<br>        numberOfRolls = currentState.numberOfRolls + 1<br>      )<br>    }<br>  }<br>}</pre><p>The business logic for generating this UI state is <strong>local</strong> to the state holder. To prevent exposing a mutable version of the observable state holder that would allow direct modification of the UI state and violate the single source of truth principle, we expose the UI state as StateFlow. uiState is the read-only version of our mutable state that we convert using the .asStateFlow operator.</p><blockquote><strong>Note:</strong> Instead of MutableStateFlow, we could’ve also modelled our Ui State using Compose State&lt;T&gt; or even LiveData. For patterns and best practices concerning the use of Compose State&lt;T&gt; in this context, check out the <a href="https://developer.android.com/topic/architecture/ui-layer/state-production#compose-state">State production docs</a>.</blockquote><h4>Producing UI state with external source of state change</h4><p>Application data comes from other layers of the hierarchy in the form of streams of data. To adapt this data to UI state, we must transform it into an observable data holder type. In the following example, we greet the user by displaying their name on the screen.</p><pre>class DiceRollViewModel(<br>  userRepository: UserRepository<br>) : ViewModel() {<br><br>  val userUiState: StateFlow&lt;String&gt; =<br>    userRepository.userStream.map { user -&gt; user.name }<br>      .stateIn(<br>        scope = viewModelScope,<br>        started = SharingStarted.WhileSubscribed(5_000),<br>        initialValue = &quot;&quot;<br>      )<br>}</pre><p>The state holder gets an instance of the data layer (i.e. UserRepository) as a dependency. It then maps the userStream: Flow to extract the specific information we are interested in, which in this case, is the user’s name. Since the map operator returns a Flow, we use the .stateIn operator to convert the Flow to a StateFlow, an observable data holder type.</p><p><a href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/state-in.html">.stateIn</a> is a common operator used in state holders when dealing with Flows from other layers of the hierarchy and/or combining multiple data streams. Its method definition contains:</p><ul><li>scope: defines the lifecycle of the resulting StateFlow.</li><li>started: determines the strategy for starting and stopping sharing. In the code snippet, we use WhileSubscribed(5_000) to stop collecting data from upstream flows (e.g. the one coming from UserRepository) when there are no collectors/observers for a specific period, in this case, 5 seconds. In this way, if the UI is not visible to the user for more than 5 seconds, we can cancel those data layer flow collections and save resources to protect the device’s health.</li><li>initialValue: specifies the initial value of the StateFlow. As mentioned earlier, using an observable state holder type guarantees that the UI always has a UI state to render on the screen, and this parameter plays a crucial role in achieving that.</li></ul><h4>Summary of producing UI state</h4><p>Let’s see a summary of what types to expose based on the type of input and the source API:</p><ol><li>If you’re using one-shot APIs or local business logic, use a MutableStateFlow or Compose MutableState&lt;T&gt; to store the state in your state holder. Then, expose it as StateFlow or Compose State&lt;T&gt;.</li><li>When the source type is an external stream provided as a Flow, you should expose a StateFlow.</li><li>If you are dealing with both types of input, such as having at least one external stream, combine all the inputs and expose the UI state as a StateFlow.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*-F-wDBJ7A5xJjFtX" /><figcaption><em>Summary of the UI state exposed type given the source type and API</em></figcaption></figure><p>For more information about this topic, check out the <a href="http://goo.gle/android-arch-producing-state">State holders and state production talk</a> or the <a href="https://developer.android.com/topic/architecture/ui-layer/state-production">UI layer State production docs</a>.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FpCX9wvu-Bq0%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DpCX9wvu-Bq0&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FpCX9wvu-Bq0%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/95ffb84577516397063414dd4f0bd313/href">https://medium.com/media/95ffb84577516397063414dd4f0bd313/href</a></iframe><h3>How to model UI state</h3><p>The UI state describes the UI at a certain point in time. The UI is the visual representation of the UI state. We previously defined a UI state defined as a data class in the DiceRollUiState code snippet above. Here it is again:</p><pre>data class DiceRollUiState(<br>  val firstDiceValue: Int? = null<br>  val secondDiceValue: Int? = null<br>  val numberOfRolls: Int = 0<br>)</pre><p>It’s crucial that the fields in the UI state are immutable (i.e. vals) to ensure timing and consistency guarantees. Typically, UI state fields have sensible default values to facilitate creation and copying. However, not all UI states are that straightforward as the previous one.</p><p>Let’s consider a different scenario where we want to enable the user to roll the dice only when they are logged in. When the user lands on the screen, we check the user state and make a decision. Here’s a possible UI state for this case:</p><pre>sealed interface DiceRollUiState {<br><br>  data object Loading : DiceRollUiState<br><br>  data class DiceRoll(<br>    val username: String,<br>    val numberOfRolls: Int,<br>    val firstDiceValue: Int? = null,<br>    val secondDiceValue: Int? = null,<br>  ) : DiceRollUiState<br><br>  data object LogUserIn : DiceRollUiState<br><br>}</pre><p>The UI state would be either loading (Loading), indicating that the user needs to log in (LogUserIn), or displaying the dice roll values with the username on the screen (DiceRoll).</p><p>When should you use a data class, sealed interface/class or a combination of both?</p><ul><li>Use a sealed interface/class when the screen can be in multiple <strong>exclusive</strong> states.</li><li>Use a data class when the data inside it can mutate. This is particularly useful in screens following an <a href="https://developer.android.com/topic/architecture/data-layer/offline-first">offline-fist</a> approach where the screen might simultaneously display loading indicators, data, and error messages.</li></ul><h4>How to model complex UI state</h4><p>When dealing with complex screens, you need to make sure you don’t create UI inconsistencies. As an exercise, let’s try to model the home screen of <a href="https://github.com/android/compose-samples/tree/main/JetNews">Jetnews</a>, a Compose sample app.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*DjtYI9_j54QGk8Gz" /><figcaption><em>Home screen of Jetnews displayed on a tablet</em></figcaption></figure><p>The primary content of the screen presents a feed of articles and an open article details section where users can read the article. As a preliminary step to model the entire UI screen, one might define the following UI state:</p><pre>private data class HomeViewModelState(<br>  val postsFeed: PostsFeed? = null,<br>  val selectedPostId: String? = null,<br>  val isArticleOpen: Boolean = false,<br>  val favorites: Set&lt;String&gt; = emptySet(),<br>  val isLoading: Boolean = false,<br>  val errorMessages: List&lt;ErrorMessage&gt; = emptyList(),<br>  val searchInput: String = &quot;&quot;,<br>)</pre><p>However, there’s a problem. Can you spot it? Due to the default values, we could create UI inconsistencies! We could have a UI state with a selectedPostId <em>without</em> postsFeed. That wouldn’t be realistic, that should never occur. To resolve this issue, we need to introduce a more strongly typed state to prevent these problems. Considering that our business requirements allow either posts or nothing to be displayed on the screen, we can introduce a sealed interface on top of this state:</p><pre>sealed interface HomeUiState {<br><br>  val isLoading: Boolean<br>  val errorMessages: List&lt;ErrorMessage&gt;<br>  val searchInput: String<br><br>  data class NoPosts(<br>    override val isLoading: Boolean = false,<br>    override val errorMessages: List&lt;ErrorMessage&gt; = emptyList(),<br>    override val searchInput: String = &quot;&quot;<br>  ) : HomeUiState<br><br>  data class HasPosts(<br>    val postsFeed: PostsFeed,<br>    val selectedPost: Post,<br>    val isArticleOpen: Boolean,<br>    val favorites: Set&lt;String&gt;,<br>    override val isLoading: Boolean = false,<br>    override val errorMessages: List&lt;ErrorMessage&gt; = emptyList(),<br>    override val searchInput: String = &quot;&quot;<br>  ) : HomeUiState<br>}</pre><p>Now our UI would either show HasPosts or NoPosts. In the HasPosts variant, it’s not possible to have a selectedPost without an existing postsFeed. Problem solved! While the initial approximation of our UI state could still prove useful for modelling the entire UI state privately, this type is never exposed. Ultimately, you would map that state to HomeUiState:</p><pre>private data class HomeViewModelState(...) {<br><br>  fun toUiState(): HomeUiState =<br>    if (postsFeed == null) {<br>      HomeUiState.NoPosts(...)<br>    } else {<br>      HomeUiState.HasPosts(...)<br>    }<br>}</pre><h4>Exposing single vs multiple UI state streams</h4><p>We often engage in discussions regarding whether a state holder should expose a single or multiple streams of data.</p><p>What we’ve been advising people so far is that you’d <strong>expose a single stream of UI state if fields depend on each other</strong>. On the other hand, if those fields are independent of each other and do not lead to UI inconsistencies, it’s acceptable to expose multiple streams.</p><p>Some may argue that if they are entirely independent, it implies they affect different parts of the UI, and each of those parts could have their own state holders. Sure, I agree. But if you don’t want to create multiple state holders and expose multiple UI states from a higher level one, that’s acceptable as well.</p><h3>How to consume UI state</h3><p>Ideally, UI state should be consumed from the UI in a lifecycle-aware manner. That is, only when the UI is visible on the screen. In the Android lifecycle, that is when the lifecycle is above the STARTED and STOPPED states. There are different APIs available to do this in an easy way.</p><p>For Android Views, you can use the <a href="https://developer.android.com/reference/kotlin/androidx/lifecycle/package-summary#(androidx.lifecycle.Lifecycle).repeatOnLifecycle(androidx.lifecycle.Lifecycle.State,kotlin.coroutines.SuspendFunction1)">repeatOnLifecycle</a> or <a href="https://developer.android.com/reference/kotlin/androidx/lifecycle/package-summary#(kotlinx.coroutines.flow.Flow).flowWithLifecycle(androidx.lifecycle.Lifecycle,androidx.lifecycle.Lifecycle.State)">flowWithLifecycle</a> APIs, which are found in the androidx.lifecycle.lifecycle-runtime-ktx artifact. Here’s how you’d use repeatOnLifecycle:</p><pre>class SomeActivity : AppCompatActivity() {<br><br>  override fun onCreate(savedInstanceState: Bundle?) {<br>    // ...<br>    lifecycleScope.launch {<br>      repeatOnLifecycle(Lifecycle.State.STARTED) {<br>        viewModel.uiState.collect {<br>          // New UI state! Update the UI<br>        }<br>      }<br>    }<br>  }<br>}</pre><p>Inside the repeatOnLifecycle coroutine block, you collect from the UI state. repeatOnLifecycle automatically creates a new coroutine that executes the block when the lifecycle reaches that state, and cancels the coroutine running the block when it falls below that Lifecycle state.</p><p>In Compose, use the <a href="https://developer.android.com/reference/kotlin/androidx/lifecycle/compose/package-summary#(kotlinx.coroutines.flow.StateFlow).collectAsStateWithLifecycle(androidx.lifecycle.Lifecycle,androidx.lifecycle.Lifecycle.State,kotlin.coroutines.CoroutineContext)">collectAsStateWithLifecycle</a> API that uses the repeatOnLifecycle API under the hood. This is available in the androidx.lifecycle.lifecycle-runtime-compose artifact. This API collects the underlying flow given a certain lifecycle State, and represents the latest value of the flow as Compose State&lt;T&gt;. This allows the composable function to recompose whenever a new element is emitted.</p><pre>@Composable<br>fun SomeScreen(<br>  modifier: Modifier = Modifier,<br>  viewModel: SomeViewModel = viewModel()<br>) {<br>  val uiState: SomeUiState by viewModel.uiState<br>                  .collectAsStateWithLifecycle()<br><br>  // Emit UI given uiState. SomeScreen will recompose<br>  // whenever `viewModel.uiState` emits a new value.<br>}</pre><p>For more information about collecting in a lifecycle-aware manner, watch the <a href="http://goo.gle/android-arch-consume-state">Collect flows on Android talk</a> or read the <a href="https://medium.com/androiddevelopers/a-safer-way-to-collect-flows-from-android-uis-23080b1f8bda">repeatOnLifecycle</a> and <a href="https://medium.com/androiddevelopers/consuming-flows-safely-in-jetpack-compose-cde014d0d5a3">collectAsStateWithLifecycle</a> articles. If you’re interested in how these APIs were created, read the <a href="https://medium.com/androiddevelopers/repeatonlifecycle-api-design-story-8670d1a7d333">repeatOnLifecycle API design story blog post</a>.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F6hNXFs1fYaY%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D6hNXFs1fYaY&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F6hNXFs1fYaY%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/eb173e6801b3292b0b8d49e1eca2a879/href">https://medium.com/media/eb173e6801b3292b0b8d49e1eca2a879/href</a></iframe><p>Now that you’ve read part 1 of the crash course on the UI layer, you should have a general understanding of the different entities present on this layer, and how to think about the UI and UI state effectively.</p><p><strong>In part 2</strong>, we’ll cover state holders and other UI layer-related topics such as where to hoist state and saving state on Android.</p><p><a href="https://medium.com/bumble-tech/crash-course-on-the-android-ui-layer-part-2-2335171467e0">Crash course on the Android UI layer | Part 2</a></p><p>👋 See you there!</p><p><em>Remember that if you prefer to consume this content in video format, check out the talk I delivered at Droidcon London 2023:</em></p><p><a href="https://www.droidcon.com/2023/11/15/peeling-back-the-layers-unmasking-the-ui-nknown/">Peeling Back the Layers: Unmasking the UI-nknown!</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2094221a9be3" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bumble-tech/crash-course-on-the-android-ui-layer-part-1-2094221a9be3">Crash course on the Android UI layer | Part 1</a> was originally published in <a href="https://medium.com/bumble-tech">Bumble Tech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Now in Android #90]]></title>
            <link>https://medium.com/androiddevelopers/now-in-android-90-a852c6753fda?source=rss-3b5622dd813c------2</link>
            <guid isPermaLink="false">https://medium.com/p/a852c6753fda</guid>
            <category><![CDATA[featured]]></category>
            <category><![CDATA[ksp]]></category>
            <category><![CDATA[now-in-android]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[jetpack-compose]]></category>
            <dc:creator><![CDATA[Manuel Vivo]]></dc:creator>
            <pubDate>Thu, 07 Sep 2023 21:02:31 GMT</pubDate>
            <atom:updated>2023-09-07T21:02:31.062Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*CrszBnS4juaPcIRA" /></figure><h4><a href="https://blog.google/products/android/modern-look/">Android brand</a>, <a href="https://android-developers.googleblog.com/2023/08/latest-artwork-on-hundreds-of-millions-of-devices.html">ART updates</a>, <a href="https://github.com/google/dagger/releases/tag/dagger-2.48">Dagger KSP</a>, <a href="https://developer.android.com/jetpack/compose">Jetpack Compose</a>, documentation updates, and more!</h4><p>Welcome to Now in Android, your ongoing guide to what’s new and notable in the world of Android development.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FlEEthuvAbXg&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DlEEthuvAbXg&amp;image=http%3A%2F%2Fi.ytimg.com%2Fvi%2FlEEthuvAbXg%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=google" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/b67cb83ce9e0088a476399ef7e579dc3/href">https://medium.com/media/b67cb83ce9e0088a476399ef7e579dc3/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=%2F%2Fhtml5-player.libsyn.com%2Fembed%2Fepisode%2Fid%2F27971793%2Fheight%2F90%2Ftheme%2Fcustom%2Fthumbnail%2Fyes%2Fdirection%2Fforward%2Frender-playlist%2Fno%2Fcustom-color%2F88AA3C%2F&amp;display_name=Libsyn&amp;url=https%3A%2F%2Fnowinandroid.libsyn.com%2F90-android-brand-art-updates-dagger-ksp-and-more&amp;image=https%3A%2F%2Fassets.libsyn.com%2Fsecure%2Fcontent%2F160166913&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=libsyn" width="600" height="90" frameborder="0" scrolling="no"><a href="https://medium.com/media/fbaa909603ea6e155c23c9c0d366d950/href">https://medium.com/media/fbaa909603ea6e155c23c9c0d366d950/href</a></iframe><p>Most of the content of this post is available in the form of a <a href="https://youtu.be/lEEthuvAbXg">video</a> or <a href="https://nowinandroid.libsyn.com/90-android-brand-art-updates-dagger-ksp-and-more">podcast</a>, so feel free to <a href="https://youtu.be/lEEthuvAbXg">watch</a> or <a href="https://nowinandroid.libsyn.com/90-android-brand-art-updates-dagger-ksp-and-more">listen</a> rather than read on. (Or do all three to help you remember! There won’t be a quiz.)</p><h3>A new modern look for the Android brand 💅</h3><p>Android is updating its visual identity that better represents our Android community, and reflects Android’s core ethos of being open, iterative and inclusive.</p><p>The Android robot became a prominent fixture of our logo, and now we’re giving Bugdroid an entirely new 3D look. We wanted the bugdroid to appear as dynamic as Android itself.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JcobJ2y0zTVqMI_I83aAtQ.png" /><figcaption>Screenshot of the video introducing the new Android brand</figcaption></figure><p>You’ll start seeing the new aspects of the brand identity, like the updated logo and 3D bugdroid, appear on Android devices and in more places starting this year.</p><p><a href="https://blog.google/products/android/modern-look/">A new modern look for the Android brand</a></p><h3>Latest ARTwork on hundreds of millions of devices 🎨</h3><p>Thanks to ART Google Play system updates, hundreds of millions of devices receive the latest <strong>performance improvements, security fixes, &amp; OpenJDK APIs</strong>! Learn how we modularized Android to allow ART, the engine powering Android, to update independently.</p><p>In the coming months, we’ll be releasing ART 14 to all compatible devices. ART 14 includes OpenJDK 17 support along with new compiler and runtime optimizations that improve performance while reducing code size.</p><p><a href="https://android-developers.googleblog.com/2023/08/latest-artwork-on-hundreds-of-millions-of-devices.html">Latest ARTwork on hundreds of millions of devices</a></p><h3>Library releases 🚀</h3><p>The latest release of <a href="https://github.com/google/dagger/releases/tag/dagger-2.48">Dagger and Hilt — v2.48</a> — includes the <strong>alpha release of their KSP processors</strong>. Instructions for using them can be found in the <a href="https://dagger.dev/dev-guide/ksp">Dagger KSP guide</a>. This release contributes to getting rid of KAPT in your Gradle builds and making them faster. There are some breaking changes you should be aware of, check out the <a href="https://github.com/google/dagger/releases/tag/dagger-2.48">2.48 release notes</a> for more information.</p><p><a href="https://github.com/google/dagger/releases/tag/dagger-2.48">Release Dagger 2.48 · google/dagger</a></p><h3>Articles and documentation updates 📚</h3><p>Ben Trengrove gave <a href="https://medium.com/androiddevelopers/an-update-on-jetpack-compose-accompanist-libraries-august-2023-ac4cbbf059f1?source=rss----95b274b437c2---4">an update on <strong>Jetpack Compose Accompanist libraries</strong></a>. Some libraries will be deprecated with no replacement, including <a href="https://github.com/google/accompanist/tree/main/pager-indicators">Pager Indicators</a> and <a href="https://github.com/google/accompanist/blob/main/web">WebView</a>. <a href="https://github.com/google/accompanist/tree/main/drawablepainter">Drawable Painter</a> and <a href="https://github.com/google/accompanist/tree/main/permissions">Permissions</a> are considered feature complete. And <a href="https://github.com/google/accompanist/tree/main/adaptive">Adaptive</a>, <a href="https://github.com/google/accompanist/tree/main/testharness">Test Harness</a> and <a href="https://github.com/google/accompanist/tree/main/navigation-material">Navigation Material</a> continue to be experimental.</p><p><a href="https://medium.com/androiddevelopers/an-update-on-jetpack-compose-accompanist-libraries-august-2023-ac4cbbf059f1">An update on Jetpack Compose Accompanist libraries — August 2023</a></p><p>We updated the <a href="https://developer.android.com/topic/modularization/patterns"><strong>modularization guidance</strong></a> to include more common patterns such as <a href="https://developer.android.com/topic/modularization/patterns#test-modules">test modules</a> and <a href="https://developer.android.com/topic/modularization/patterns#dependency_inversion">dependency inversion</a>. With dependency inversion, your modules depend on abstraction modules instead of concrete implementations. Read the <a href="https://developer.android.com/topic/modularization/patterns">guide</a> to learn more about these topics.</p><p>Whether your source code is written in Java, Kotlin, or both, there are several places you must choose a JDK or Java language version for your build. The <strong>new </strong><a href="https://developer.android.com/build/jdks"><strong>Java versions in Android builds guide</strong></a> help you identify which JDK is which, how to choose the right one in different scenarios, and which Java language features you can use in your project.</p><p>If you want to <a href="https://developer.android.com/jetpack/compose/animation/quick-guide">get started with animations in Compose</a>, we created a <a href="https://developer.android.com/jetpack/compose/animation/quick-guide">new guide</a> with a list of common animation use cases and the right API to use in each scenario. Also, we improved the previous <a href="https://developer.android.com/jetpack/compose/animation/introduction">animations in Compose diagram</a> with an easier API decision tree. Doesn’t it look nice?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*b-nhGN4CHTWdYFnj" /><figcaption>Flowchart describing the decision tree for choosing the appropriate Compose animation API</figcaption></figure><h3>Sample projects 🧑‍💻</h3><p>The <a href="https://goo.gle/nia">Now in Android open source app</a> is now using <strong>screenshot tests</strong> to verify the visual appearance of certain Compose screens and components. Screenshot tests can automatically verify combinations of attributes that make sense such as different app states, screen sizes, locales, or themes.</p><p>To see that in action, <a href="https://github.com/android/nowinandroid/pull/931">this PR</a> adds some screenshot tests to the design system module in the project, and <a href="https://github.com/android/nowinandroid/pull/876">this other one</a> sets up screenshot testing in the app.</p><p><a href="https://github.com/android/nowinandroid/pull/931">Adds screenshot tests to :core:designsystem by JoseAlcerreca · Pull Request #931 · android/nowinandroid</a></p><h3>Now then… 👋</h3><p>That’s it for this time with <a href="https://blog.google/products/android/modern-look/">a new Android brand</a>, <a href="https://android-developers.googleblog.com/2023/08/latest-artwork-on-hundreds-of-millions-of-devices.html">ART updates</a>, <a href="https://github.com/google/dagger/releases/tag/dagger-2.48">the Dagger and Hilt KSP processors alpha release</a>, <a href="https://medium.com/androiddevelopers/an-update-on-jetpack-compose-accompanist-libraries-august-2023-ac4cbbf059f1?source=rss----95b274b437c2---4">Accompanist libraries updates</a>, improvements to the <a href="https://developer.android.com/topic/modularization/patterns">modularization</a> and <a href="https://developer.android.com/jetpack/compose/animation/quick-guide">Compose animations</a> guidance, and screenshot testing in the <a href="https://goo.gle/nia">Now in Android app</a>.</p><p>Come back here soon for the next update from the Android developer universe! 💫</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a852c6753fda" width="1" height="1" alt=""><hr><p><a href="https://medium.com/androiddevelopers/now-in-android-90-a852c6753fda">Now in Android #90</a> was originally published in <a href="https://medium.com/androiddevelopers">Android Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Now in Android #75]]></title>
            <link>https://medium.com/androiddevelopers/now-in-android-75-e4bbe977d33f?source=rss-3b5622dd813c------2</link>
            <guid isPermaLink="false">https://medium.com/p/e4bbe977d33f</guid>
            <category><![CDATA[wear-os]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[android-studio]]></category>
            <category><![CDATA[now-in-android]]></category>
            <category><![CDATA[kotlin-multiplatform]]></category>
            <dc:creator><![CDATA[Manuel Vivo]]></dc:creator>
            <pubDate>Wed, 18 Jan 2023 22:32:24 GMT</pubDate>
            <atom:updated>2023-01-30T05:58:33.285Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*IdylXqMS2sF3Nh30" /></figure><h4><a href="https://developer.android.com/studio">Android Studio Electric Eel</a>, <a href="http://goo.gle/mad-architecture-guide">Architecture</a>, <a href="https://kotlinlang.org/docs/multiplatform.html">Kotlin Multiplatform</a>, <a href="https://developer.android.com/wear">WearOS</a>, <a href="https://developer.android.com/training/camerax">CameraX</a>, Stylus, and more.</h4><p>Welcome to 2023 and a new episode of Now in Android, your ongoing guide to what’s new and notable in the world of Android development.</p><h3>Episode 75 Video and Podcast</h3><p><em>Now in Android</em> is also offered as a video and podcast.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fo6OQh1_PFsw&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Do6OQh1_PFsw&amp;image=http%3A%2F%2Fi.ytimg.com%2Fvi%2Fo6OQh1_PFsw%2Fhqdefault.jpg&amp;key=d04bfffea46d4aeda930ec88cc64b87c&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/c84dda35239300efa5202ea5fdc6f672/href">https://medium.com/media/c84dda35239300efa5202ea5fdc6f672/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=%2F%2Fhtml5-player.libsyn.com%2Fembed%2Fepisode%2Fid%2F25649421%2Fheight%2F90%2Ftheme%2Fcustom%2Fthumbnail%2Fyes%2Fdirection%2Fforward%2Frender-playlist%2Fno%2Fcustom-color%2F88AA3C%2F&amp;display_name=Libsyn&amp;url=https%3A%2F%2Fnowinandroid.libsyn.com%2F75-android-studio-electric-eel-architecture-kotlin-multiplatform-and-more&amp;image=https%3A%2F%2Fassets.libsyn.com%2Fsecure%2Fcontent%2F144590655&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=libsyn" width="600" height="90" frameborder="0" scrolling="no"><a href="https://medium.com/media/45893439bc808a0b6fb151652acf74e2/href">https://medium.com/media/45893439bc808a0b6fb151652acf74e2/href</a></iframe><h3>Android Studio Electric Eel is stable ⚡</h3><p><a href="https://developer.android.com/studio">This release</a> includes updates and new features that cover across design, build &amp; dependencies, emulators &amp; devices, and IntelliJ.</p><p>This version brings improvements to the <a href="https://developer.android.com/jetpack/compose/tooling/studio#preview">Compose Preview</a> that now updates automatically, the layout inspector that now displays <a href="https://developer.android.com/jetpack/compose/tooling/studio#recomposition-counts">recomposition counts</a>, visual XML linting for Views, sync performance with parallel project imports, <a href="https://developer.android.com/distribute/sdk-index">SDK Index</a> integration, a new logcat, resizable emulators, physical devices mirroring, and more!</p><p>For more information check out the blog post or the video, and <a href="https://developer.android.com/studio">download</a> the latest stable version today to try it out for yourself!</p><p><a href="https://android-developers.googleblog.com/2023/01/android-studio-electric-eel.html">Android Studio Electric Eel</a></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FbVt14IBv4NA&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DbVt14IBv4NA&amp;image=http%3A%2F%2Fi.ytimg.com%2Fvi%2FbVt14IBv4NA%2Fhqdefault.jpg&amp;key=d04bfffea46d4aeda930ec88cc64b87c&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/1dd56c429ba947895d51711d80552c64/href">https://medium.com/media/1dd56c429ba947895d51711d80552c64/href</a></iframe><h3>AndroidX releases 🚀</h3><p>Since the previous episode, there have been some <a href="https://developer.android.com/jetpack/androidx/versions/all-channel">AndroidX releases</a> worth highlighting.</p><p>Graduated to stable, we can find <a href="https://developer.android.com/jetpack/androidx/releases/appcompat#version_160_3"><strong>AppCompat 1.6.0</strong></a> that primarily supports Android 13 including <a href="https://developer.android.com/about/versions/13/features#language-support">per-language preferences</a> and predictive back, and <a href="https://developer.android.com/jetpack/androidx/releases/room#version_250_3"><strong>Room 2.5.0</strong></a> that got its runtime converted from Java to Kotlin and new features such as the Upsert annotation and room-paging support for RxJava and Guava.</p><p>The <a href="https://developer.android.com/jetpack/androidx/releases/lifecycle#2.6.0-alpha04"><strong>Lifecycle’s new 2.6.0-alpha04 version</strong></a> removes the experimental annotation from the collectAsStateWithLifecycle API and deprecates the pausing dispatcher and launchWhenX APIs.</p><p>As new libraries, we can find the <a href="https://developer.android.com/jetpack/androidx/releases/credentials#1.0.0-alpha01"><strong>androidx.credentials</strong></a> library that helps users sign into apps, using their stored credentials including passwords and passkeys. Also new privacy sandbox libraries such as the <a href="https://developer.android.com/jetpack/androidx/releases/privacysandbox-ads#1.0.0-alpha01"><strong>adservices</strong></a> one that enables integration with Privacy Preserving APIs, and <a href="https://developer.android.com/jetpack/androidx/releases/privacysandbox-sdkruntime#1.0.0-alpha01"><strong>sdkruntime</strong></a> that contains components for building and loading Runtime enabled SDKs on old versions of Android Platform.</p><h3>Articles 📚</h3><p><a href="https://medium.com/u/7f5a2cb6598e">Don Turner</a> wrote about <a href="https://medium.com/androiddevelopers/adding-a-domain-layer-bc5a708a96da">adding a domain layer</a> to an app that covers how the team added a <a href="https://developer.android.com/topic/architecture/domain-layer">domain layer</a> to the <a href="https://github.com/android/nowinandroid">Now in Android app</a> for improved readability, scalability and portability.</p><p><a href="https://medium.com/androiddevelopers/adding-a-domain-layer-bc5a708a96da">Adding a domain layer</a></p><p>Anton Hansson wrote about <a href="https://android-developers.googleblog.com/2023/01/extending-android-sdk.html">extending the Android SDK</a> that covers the Extension SDK framework that enables the team to introduce new functionality outside of major API level releases allowing faster innovations such as the new <a href="https://developer.android.com/training/data-storage/shared/photopicker">photo picker</a>, and provide backward compatibility.</p><p><a href="https://android-developers.googleblog.com/2023/01/extending-android-sdk.html">Extending the Android SDK</a></p><p><a href="https://medium.com/u/819ba96217e9">chiara chiappini</a> wrote about the <a href="https://medium.com/androiddevelopers/ease-the-development-of-media-apps-for-wear-os-with-the-media-toolkit-1b7ea06e07e5">ease the development of media apps for Wear OS with the media toolkit</a> you’ll learn how to bring your media app to Wear OS smartwatches with the help of the newly released <a href="https://google.github.io/horologist/#media">Wear media toolkit</a>.</p><p><a href="https://medium.com/androiddevelopers/ease-the-development-of-media-apps-for-wear-os-with-the-media-toolkit-1b7ea06e07e5">Ease the development of media apps for Wear OS with the media toolkit</a></p><p><a href="https://medium.com/u/1a03a9a0210b">Mozart Louis</a> wrote the first part of a HDR series, <a href="https://medium.com/androiddevelopers/android-hdr-migrating-from-textureview-to-surfaceview-part-1-how-to-migrate-6bfd7f4b970e">migrating from TextureView to SurfaceView</a>. Migrating to the preferred SurfaceView enables HDR playback on supported devices.</p><p><a href="https://medium.com/androiddevelopers/android-hdr-migrating-from-textureview-to-surfaceview-part-1-how-to-migrate-6bfd7f4b970e">Android HDR | Migrating from TextureView to SurfaceView (Part #1) — How to Migrate</a></p><p><a href="https://medium.com/u/365cec8aaa4a">Cedric Ferry</a> wrote about the <a href="https://medium.com/androiddevelopers/stylus-low-latency-d4a140a9c982">Stylus low latency</a>. The post covers two new libraries (<a href="https://developer.android.com/jetpack/androidx/releases/graphics">low latency graphics</a> and <a href="https://developer.android.com/jetpack/androidx/releases/input">motion prediction</a>) that aim to reduce the processing time between stylus input and screen rendering, explores how these libraries work, and how you can implement a best-in-class stylus experience in your app.</p><p><a href="https://medium.com/androiddevelopers/stylus-low-latency-d4a140a9c982">Stylus Low Latency</a></p><h3>Videos 🎥</h3><p>If you want to make your app grow, you should watch these two videos, <a href="https://www.youtube.com/watch?v=4OrzjJ4dTMw">optimize paywall conversion</a>, and <a href="https://www.youtube.com/watch?v=rtX3DujJPZk">engage with push notifications</a>, to learn about those topics and improve your app.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F4OrzjJ4dTMw%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D4OrzjJ4dTMw&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F4OrzjJ4dTMw%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/d55c5007152cfb4c04594716832364a7/href">https://medium.com/media/d55c5007152cfb4c04594716832364a7/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FrtX3DujJPZk%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DrtX3DujJPZk&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FrtX3DujJPZk%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/4978b5eb626777371d1ea18bf079d16f/href">https://medium.com/media/4978b5eb626777371d1ea18bf079d16f/href</a></iframe><p>Donovan recorded a video about <a href="https://www.youtube.com/watch?v=I4rDx90Nlus">CameraX concepts</a> to introduce you to its functionality through 4 use cases: Preview, ImageCapture, VideoCapture, and ImageAnalysis.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FI4rDx90Nlus%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DI4rDx90Nlus&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FI4rDx90Nlus%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/e91f007b6c4e0e38b7288d9a0781cb3d/href">https://medium.com/media/e91f007b6c4e0e38b7288d9a0781cb3d/href</a></iframe><p>Chris Shmerling recorded an in-depth walkthrough of a sample app using the FLEDGE API, a component of the Privacy Sandbox on Android.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FNoNxJidJSnk&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DNoNxJidJSnk&amp;image=http%3A%2F%2Fi.ytimg.com%2Fvi%2FNoNxJidJSnk%2Fhqdefault.jpg&amp;key=d04bfffea46d4aeda930ec88cc64b87c&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/589399e541f1240aaeeb39dbbd69b7d2/href">https://medium.com/media/589399e541f1240aaeeb39dbbd69b7d2/href</a></iframe><p>Erin recorded an <a href="https://www.youtube.com/watch?v=7DfLO5ez5bo">introduction to the Attribution Reporting API</a> that is designed to provide improved user privacy by removing reliance on cross-party user identifiers, and to support key use cases for attribution and conversion measurement. The video walks you through a sample implementation of the Attribution Reporting API on Android.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F7DfLO5ez5bo%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D7DfLO5ez5bo&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F7DfLO5ez5bo%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/0424e8c6608d9a7337a5d61fba3b64af/href">https://medium.com/media/0424e8c6608d9a7337a5d61fba3b64af/href</a></iframe><h3>ADB Podcast Episodes🎙</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/200/0*w3a3cdakNq3qtLtA" /></figure><p>In <a href="https://adbackstage.libsyn.com/episode-193-kotlin">Episode 193: Kotlin</a>, <a href="https://medium.com/u/2f292716f9ab">James Ward</a> joins <a href="https://medium.com/u/cb2c4874d3e9">Chet Haase</a>, <a href="https://medium.com/u/8251a5f98c9d">Tor Norbye</a>, and <a href="https://medium.com/u/c967b7e51f8b">Romain Guy</a> to talk about Kotlin Multiplatform (both KMP and KMM) and what’s coming for Kotlin in 2023, especially the new K2 frontend.</p><h3>Now then… 👋</h3><p>That’s it for the first Now in Android episode of 2023 with a new version of <a href="https://developer.android.com/studio">Android Studio stable</a>, AndroidX releases, articles about the <a href="https://medium.com/androiddevelopers/adding-a-domain-layer-bc5a708a96da">domain layer</a>, <a href="https://android-developers.googleblog.com/2023/01/extending-android-sdk.html">extending the Android SDK</a>, <a href="https://medium.com/androiddevelopers/ease-the-development-of-media-apps-for-wear-os-with-the-media-toolkit-1b7ea06e07e5">Wear OS</a>, <a href="https://medium.com/androiddevelopers/android-hdr-migrating-from-textureview-to-surfaceview-part-1-how-to-migrate-6bfd7f4b970e">HDR</a> and the <a href="https://medium.com/androiddevelopers/stylus-low-latency-d4a140a9c982">stylus</a>, videos about app growth, <a href="https://www.youtube.com/watch?v=I4rDx90Nlus">CameraX</a> and the <a href="https://www.youtube.com/watch?v=7DfLO5ez5bo">Attribution Reporting API</a>, a new episode of the <a href="https://adbackstage.libsyn.com/">Android Developers Backstage</a>, and more!</p><p>Come back here soon for the next update from the Android developer universe.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e4bbe977d33f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/androiddevelopers/now-in-android-75-e4bbe977d33f">Now in Android #75</a> was originally published in <a href="https://medium.com/androiddevelopers">Android Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Now in Android #71]]></title>
            <link>https://medium.com/androiddevelopers/now-in-android-71-248cd926bf7c?source=rss-3b5622dd813c------2</link>
            <guid isPermaLink="false">https://medium.com/p/248cd926bf7c</guid>
            <category><![CDATA[kotlin-multiplatform]]></category>
            <category><![CDATA[jetpack-compose]]></category>
            <category><![CDATA[now-in-android]]></category>
            <category><![CDATA[material-design]]></category>
            <category><![CDATA[android-app-development]]></category>
            <dc:creator><![CDATA[Manuel Vivo]]></dc:creator>
            <pubDate>Fri, 04 Nov 2022 22:39:54 GMT</pubDate>
            <atom:updated>2022-11-05T03:11:16.264Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*99F5VQ7eRCJivVpF" /></figure><h4><a href="https://android-developers.googleblog.com/2022/10/android-dev-summit.html">Android Dev Summit</a>, <a href="https://www.youtube.com/playlist?list=PLWz5rJ2EKKc_L3n1j4ajHjJ6QccFUvW1u">Modern Android development</a>, <a href="https://android-developers.googleblog.com/2022/10/announcing-experimental-preview-of-jetpack-multiplatform-libraries.html">Kotlin Multiplatform</a>, <a href="https://m3.material.io/">Material Design</a>, <a href="http://goo.gle/nia">Now in Android app</a>, and more!</h4><p>Welcome to Now in Android, your ongoing guide to what’s new and notable in the world of Android development.</p><h4>Episode 71 Video and Podcast</h4><p><em>Now in Android</em> is also offered as a video and podcast.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FWgxwzyMuKkQ%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DWgxwzyMuKkQ&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FWgxwzyMuKkQ%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/12ef3c740fdf8aa395b8cd24d51c203f/href">https://medium.com/media/12ef3c740fdf8aa395b8cd24d51c203f/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=%2F%2Fhtml5-player.libsyn.com%2Fembed%2Fepisode%2Fid%2F24910428%2Fheight%2F90%2Ftheme%2Fcustom%2Fthumbnail%2Fyes%2Fdirection%2Fforward%2Frender-playlist%2Fno%2Fcustom-color%2F88AA3C%2F&amp;display_name=Libsyn&amp;url=https%3A%2F%2Fnowinandroid.libsyn.com%2F71-androiddevsummit-modern-android-development-now-in-android-app-and-more&amp;image=https%3A%2F%2Fassets.libsyn.com%2Fsecure%2Fcontent%2F139650519&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=libsyn" width="600" height="90" frameborder="0" scrolling="no"><a href="https://medium.com/media/8ee3105d7975f28316687f87debf5682/href">https://medium.com/media/8ee3105d7975f28316687f87debf5682/href</a></iframe><h3>What’s new from Android at Android Dev Summit ‘22</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/683/0*wHM-jl2fnWwzOkON" /></figure><p>The first day of Android Dev Summit 2022 was a blast! You can already watch the <a href="https://www.youtube.com/watch?v=Awi4J5-tbW4">keynote</a> and dive into our <a href="https://developer.android.com/events/dev-summit/technical-talks#modern-android-development">first track on Modern Android development</a>.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FAwi4J5-tbW4%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DAwi4J5-tbW4&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FAwi4J5-tbW4%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/91c3d0329bb4a87799f05057e57117fb/href">https://medium.com/media/91c3d0329bb4a87799f05057e57117fb/href</a></iframe><p>Among the most important announcements, you can find the latest Compose release: <a href="https://android-developers.googleblog.com/2022/10/whats-new-in-jetpack-compose.html">October 22</a> (formerly known as Compose 1.3) stable! Compose for Wear OS hit its 1.0 stable release weeks ago and it’s the recommended way to build UI for Wear.</p><p>As you heard earlier this year: Google is <a href="https://developer.android.com/large-screens/stories">all in on tablets, foldables, and ChromeOS</a>. You can find updated templates for Wear OS in Android Studio, as well as a stable Android R emulator system image for WearOS. We’ve made it easier than ever to test your app on the large screen in <a href="https://developer.android.com/studio/preview">Android Studio Electric Eel</a> now in Beta, including resizable and desktops emulators and visual linting to help you adhere to best practices on any sized screen.</p><p>We also made it easier to take advantage of platform features in Android 13 such as the <a href="https://developer.android.com/guide/topics/resources/app-languages">per-app language preferences</a> and the new <a href="https://developer.android.com/training/data-storage/shared/photopicker">Photo picker</a> which is a permission free way to allow the user to browse and select photos and videos they explicitly want to share with your app.</p><p><a href="https://android-developers.googleblog.com/2022/10/new-from-android-ads-22.html">What&#39;s new from Android, at Android Dev Summit &#39;22</a></p><h3>Modern Android Development at ADS ‘22</h3><p>Modern Android Development (MAD) is our set of libraries, tools and guidance that make it faster and easier to build amazing Android apps. Here is a recap of the top 3 announcements from the conference.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FUFO8uAfcBV8%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DUFO8uAfcBV8&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FUFO8uAfcBV8%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/598c2511236dfe478a7b6d61942e64c2/href">https://medium.com/media/598c2511236dfe478a7b6d61942e64c2/href</a></iframe><p>You can find all the MAD talks in this playlist:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fvideoseries%3Flist%3DPLWz5rJ2EKKc_L3n1j4ajHjJ6QccFUvW1u&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fplaylist%3Flist%3DPLWz5rJ2EKKc_L3n1j4ajHjJ6QccFUvW1u&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FOg2p9LczE3A%2Fhqdefault.jpg%3Fsqp%3D-oaymwEWCKgBEF5IWvKriqkDCQgBFQAAiEIYAQ%3D%3D%26rs%3DAOn4CLDpEhXbSj8n4ACERT1d0kJWelgOew%26days_since_epoch%3D19298&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="853" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/5f3bafe0a79749b12853110584119173/href">https://medium.com/media/5f3bafe0a79749b12853110584119173/href</a></iframe><p>Don’t forget to check out the <a href="https://android-developers.googleblog.com/2022/10/whats-new-in-jetpack-ads-22.html"><strong>What’s new in Jetpack blog post</strong></a> that contains the released updates to three major areas of Jetpack: <a href="https://android-developers.googleblog.com/2022/10/whats-new-in-jetpack-ads-22.html#Architecture%20Libraries%20and%20Guidance">Architecture Libraries and Guidance</a>, <a href="https://android-developers.googleblog.com/2022/10/whats-new-in-jetpack-ads-22.html#Application%20Performance">Application Performance</a>, and <a href="https://android-developers.googleblog.com/2022/10/whats-new-in-jetpack-ads-22.html#User%20Interface%20Libraries%20and%20Guidance">User Interface Libraries and Guidance</a>. It includes the updates to WorkManager, Room, new Architecture guidance, Baseline profiles, recomposition tracing, and more!</p><p><a href="https://android-developers.googleblog.com/2022/10/whats-new-in-jetpack-ads-22.html">Android Dev Summit &#39;22: What&#39;s new in Jetpack</a></p><p>Also check out the <a href="https://android-developers.googleblog.com/2022/10/whats-new-in-jetpack-compose.html"><strong>What’s new in Jetpack Compose blog post</strong></a> that contains developers stories of how the community is adopting Jetpack Compose, and more information on the Compose October 22 release that’s shipped with a Bill of Materials (BOM). The new Compose features include staggered grids, variable fonts, swipe to refresh modifier, the new lookahead layout, and more!</p><p><a href="https://android-developers.googleblog.com/2022/10/whats-new-in-jetpack-compose.html">What&#39;s new in Jetpack Compose</a></p><h3>Experimental preview of Jetpack Multiplatform libraries</h3><p>Kotlin Multiplatform Mobile from JetBrains <a href="https://blog.jetbrains.com/kotlin/2022/10/kmm-beta/">is now in beta</a>, and we have been experimenting with this technology to see how it can enable code sharing across platforms. As part of these experiments, we are now sharing a preview of <a href="https://kotlinlang.org/lp/mobile/">Kotlin Multiplatform</a> libraries in Jetpack. The libraries available for multiplatform as part of this experimental preview are <a href="https://developer.android.com/jetpack/androidx/releases/collection">Collections</a> and <a href="https://developer.android.com/topic/libraries/architecture/datastore">DataStore</a>.</p><p>With this preview, we’re looking for your feedback about using these Jetpack libraries in multiplatform projects targeting Android and iOS applications. Keep in mind that these dev builds are experimental and should not be used in production. Learn more about the available APIs in the <a href="https://github.com/android/kotlin-multiplatform-samples/tree/main/DiceRoller">sample app</a>, the <a href="https://androidx.github.io/kmp-eap-docs">API reference documentation</a>, and the <a href="https://android-developers.googleblog.com/2022/10/announcing-experimental-preview-of-jetpack-multiplatform-libraries.html">blog post</a>!</p><p><a href="https://android-developers.googleblog.com/2022/10/announcing-experimental-preview-of-jetpack-multiplatform-libraries.html">Announcing an Experimental Preview of Jetpack Multiplatform Libraries</a></p><h3>MAD Skills: Compose basics 🎼</h3><p>The MAD Skills Compose basics series has come to an end with the usual <a href="https://www.youtube.com/watch?v=KEt2VA-11co&amp;t=578s">Live Q&amp;A episode</a> and the <a href="https://www.youtube.com/watch?v=QssnHu2NcCQ">community tip</a> brought to you by <a href="https://twitter.com/iateyourmic">Adam Bennet</a> that shares how you can speed up your learning with Compose.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FQssnHu2NcCQ%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DQssnHu2NcCQ&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FQssnHu2NcCQ%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/7cbe37c3081025168114f7afbd8dce2b/href">https://medium.com/media/7cbe37c3081025168114f7afbd8dce2b/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FKEt2VA-11co%3Fstart%3D578%26feature%3Doembed%26start%3D578&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DKEt2VA-11co&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FKEt2VA-11co%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/270f5137f1ab7ef040f849d5bd035d4f/href">https://medium.com/media/270f5137f1ab7ef040f849d5bd035d4f/href</a></iframe><p>If you missed any of the previous episodes, check out the wrap-up blog post where you can watch them all and find more information about them.</p><p><a href="https://medium.com/androiddevelopers/compose-basics-mad-skills-wrap-up-1a191fa842b9">Compose Basics: MAD Skills Wrap-Up</a></p><h3>Material Design releases 🎨</h3><p><a href="https://m3.material.io/">Material Design</a> components for Android 1.7.0 is now stable and brings updates to Material You styling, accessibility and size coherence and new minimum version requirements. You can find a new MaterialSwitch component, shape theming, and more!</p><p><a href="https://android-developers.googleblog.com/2022/10/material-design-components-for-android-1-7-0.html">Material Design Components for Android 1.7.0</a></p><p>Additionally, <a href="https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary">Compose Material 3</a> is stable as well. This library allows you to build Jetpack Compose UIs with Material Design 3. It supports color schemes, dynamic color, material components, typography, shapes, window size classes, window insets support, and more.</p><p><a href="https://android-developers.googleblog.com/2022/10/material-design-3-compose-stable.html">Material Design 3 for Compose hits stable</a></p><h3>Articles 📚 and videos 📹</h3><p><a href="https://medium.com/u/704bdef6f25c">Manda Edling</a> and <a href="https://medium.com/u/8fd06789585">Paris Hsu</a> wrote about <a href="https://medium.com/androiddevelopers/now-in-android-a-material-3-case-study-21e44bdfd2bc">the designs of the Now in Android app</a>. The blog post describes how the team applied Material 3 concepts to the app and explores the accompanying <a href="https://goo.gle/nia-figma">design Figma file</a> which has just been released.</p><p><a href="https://medium.com/androiddevelopers/now-in-android-a-material-3-case-study-21e44bdfd2bc">Now in Android: a Material 3 case study</a></p><p><a href="https://medium.com/u/92c44d274e60">Alejandra Stamato</a> wrote about <a href="https://medium.com/androiddevelopers/effective-state-management-for-textfield-in-compose-d6e5b070fbe5">effective state management for TextField in Compose</a>. Check out what you need to do to prevent synchronization issues and unexpected behaviors, among them, make sure to define your TextField state variables with Compose APIs such as mutableStateOf.</p><p><a href="https://medium.com/androiddevelopers/effective-state-management-for-textfield-in-compose-d6e5b070fbe5">Effective state management for TextField in Compose</a></p><p><a href="https://twitter.com/serbancon">Serban</a> wrote about <a href="https://android-developers.googleblog.com/2022/10/64-bit-only-devices.html">Pixel 7, the first 64-bit-only Android phone</a> and what that implies such as dropping OS support for 32-bit code, reducing memory usage, improving performance, and enhancing security.</p><p><a href="https://android-developers.googleblog.com/2022/10/64-bit-only-devices.html">Pixel 7, the first 64-bit-only Android phone</a></p><p>Ray recorded an episode about HDR video on Android. There you can find the requirements you need and the new Android Camera2 APIs.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FQYECzR0w9Ys%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DQYECzR0w9Ys&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FQYECzR0w9Ys%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/5931e228f803b18811db272d333420ff/href">https://medium.com/media/5931e228f803b18811db272d333420ff/href</a></iframe><p>Talking about Camera, the Android team wrote about <a href="https://android-developers.googleblog.com/2022/10/better-device-compatibility-with-camerax.html">better device compatibility with CameraX</a>. In this post, you’ll look at three ways CameraX makes developers’ lives easier when it comes to device compatibility. First, the CameraX Test Lab where we test over 150 physical phones every day. Second, Quirks, the mechanism CameraX uses to automatically handle device inconsistencies. And third, we’ll discuss the ways CameraX makes it easier to develop apps for foldable devices.</p><p><a href="https://android-developers.googleblog.com/2022/10/better-device-compatibility-with-camerax.html">Better Device Compatibility with CameraX</a></p><p><a href="https://medium.com/u/e1fb03b9ea54">Niharika Arora</a> wrote the <a href="https://android-developers.googleblog.com/2022/10/optimize-for-android-go-edition-lessons.html">third part of optimizing for Android Go edition</a>. This time, it’s about the tools which helped Google optimize their Google apps performance. When analyzing the memory footprint, they used <a href="https://perfetto.dev/docs/case-studies/memory">Perfetto</a>, the <a href="https://developer.android.com/studio/profile/memory-profiler">Memory profiler</a>, and meminfo. For monitoring startup, they also used <a href="https://perfetto.dev/docs/case-studies/memory">Perfetto</a>, the <a href="https://developer.android.com/topic/libraries/app-startup">App startup library</a>, <a href="https://developer.android.com/topic/performance/baselineprofiles">baseline profiles</a>, the <a href="https://developer.android.com/studio/profile/cpu-profiler">CPU profiler</a> and the micro and macrobenchmark libraries.</p><p><a href="https://android-developers.googleblog.com/2022/10/optimize-for-android-go-edition-lessons.html">Optimize for Android (Go edition): Lessons from Google apps Part 3</a></p><p>The Android ML platform team wrote about the <a href="https://android-developers.googleblog.com/2022/10/latest-updates-on-androids-custom-ml.html">latest updates on Android’s custom ML stack</a>. TensorFlow Lite in Google Play services is now Android’s official ML inference engine, TensorFlow Lite Delegates are now distributed via Google Play services, and the Acceleration Service will help you pick the best TensorFlow Lite Delegate for optimal performance in runtime.</p><p><a href="https://android-developers.googleblog.com/2022/10/latest-updates-on-androids-custom-ml.html">Latest updates on Android&#39;s custom ML stack</a></p><p>The Android Game Dev Show has a new episode. In this episode, <a href="https://medium.com/u/ae381ba24416">Nate Trost</a> talks about new updates in Android Games including <a href="https://goo.gle/3h5moqo">game mode</a>, game state, <a href="https://goo.gle/3Fnno63">adaptive performance</a>, <a href="https://goo.gle/3Df8qfz">Vulkan</a>, and much more!</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FzBTl5F8lCFQ&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DzBTl5F8lCFQ&amp;image=http%3A%2F%2Fi.ytimg.com%2Fvi%2FzBTl5F8lCFQ%2Fhqdefault.jpg&amp;key=d04bfffea46d4aeda930ec88cc64b87c&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/4c556bb7d28872e37e19c858ce413dad/href">https://medium.com/media/4c556bb7d28872e37e19c858ce413dad/href</a></iframe><p>Lidia wrote about <a href="https://android-developers.googleblog.com/2022/10/5-play-console-updates-to-help-you-understand-app-delivery-performance.html">5 Play Console updates to help you understand your app’s delivery performance</a>. Delivery insights help you better understand and analyze your app’s delivery performance and what contributes to it, and take action to optimize the experience for your users. The post includes five recent Play Console updates you can use to get more insight into your delivery performance.</p><p><a href="https://android-developers.googleblog.com/2022/10/5-play-console-updates-to-help-you-understand-app-delivery-performance.html">5 Play Console updates to help you understand your app&#39;s delivery performance</a></p><p>Lastly, the team wrote about <a href="https://android-developers.googleblog.com/2022/10/bringing-passkeys-to-android-and-chrome.html">Bringing passkeys to Android &amp; Chrome</a>. Google is bringing passkey support to both Android and Chrome. Passkeys are a significantly safer replacement for passwords and other phishable authentication factors. They cannot be reused, don’t leak in server breaches, and protect users from phishing attacks. This release enables two key capabilities: Users can create and use passkeys on Android devices and Developers can build passkey support on their sites for end-users using Chrome.</p><p><a href="https://android-developers.googleblog.com/2022/10/bringing-passkeys-to-android-and-chrome.html">Bringing passkeys to Android &amp; Chrome</a></p><h3>Now then… 👋</h3><p>That’s it for this week with <a href="https://android-developers.googleblog.com/2022/10/android-dev-summit.html">Android Dev Summit</a> and its <a href="https://www.youtube.com/playlist?list=PLWz5rJ2EKKc_L3n1j4ajHjJ6QccFUvW1u">Modern Android development</a> track, <a href="https://android-developers.googleblog.com/2022/10/announcing-experimental-preview-of-jetpack-multiplatform-libraries.html">Kotlin Multiplatform</a> updates, <a href="https://m3.material.io/">Material Design</a> releases, the <a href="https://medium.com/androiddevelopers/compose-basics-mad-skills-wrap-up-1a191fa842b9">Compose Basics MAD Skills series</a>, articles and videos about the <a href="http://goo.gle/nia">Now in Android app</a>, <a href="https://medium.com/androiddevelopers/effective-state-management-for-textfield-in-compose-d6e5b070fbe5">TextField state management</a>, <a href="https://android-developers.googleblog.com/2022/10/64-bit-only-devices.html">Pixel 7</a>, <a href="https://www.youtube.com/watch?v=QYECzR0w9Ys">HDR on Android</a>, <a href="https://android-developers.googleblog.com/2022/10/better-device-compatibility-with-camerax.html">CameraX</a>, <a href="https://android-developers.googleblog.com/2022/10/optimize-for-android-go-edition-lessons.html">optimizing for Android Go edition</a>, <a href="https://android-developers.googleblog.com/2022/10/latest-updates-on-androids-custom-ml.html">updates on custom machine learning</a>, the <a href="https://www.youtube.com/watch?v=zBTl5F8lCFQ">Android Game Dev Show</a>, <a href="https://android-developers.googleblog.com/2022/10/5-play-console-updates-to-help-you-understand-app-delivery-performance.html">Play delivery</a> and <a href="https://android-developers.googleblog.com/2022/10/bringing-passkeys-to-android-and-chrome.html">passkeys</a>.</p><p>Come back here soon for the next update from the Android developer universe.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=248cd926bf7c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/androiddevelopers/now-in-android-71-248cd926bf7c">Now in Android #71</a> was originally published in <a href="https://medium.com/androiddevelopers">Android Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Now in Android #68]]></title>
            <link>https://medium.com/androiddevelopers/now-in-android-68-f695e822863c?source=rss-3b5622dd813c------2</link>
            <guid isPermaLink="false">https://medium.com/p/f695e822863c</guid>
            <category><![CDATA[performance]]></category>
            <category><![CDATA[android-go]]></category>
            <category><![CDATA[now-in-android]]></category>
            <category><![CDATA[architecture]]></category>
            <category><![CDATA[android-13]]></category>
            <dc:creator><![CDATA[Manuel Vivo]]></dc:creator>
            <pubDate>Wed, 14 Sep 2022 21:31:29 GMT</pubDate>
            <atom:updated>2022-09-20T00:51:21.685Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*eRKND4qFHRslr-hT" /><figcaption>Illustration by <a href="https://twitter.com/VPoltrack">Virginia Poltrack</a></figcaption></figure><h4>Privacy Sandbox, Modularization, Architecture, Performance, Deep links, Android Go edition, Android 13, Jetpack Glance, and more!</h4><p>Welcome to Now in Android, your ongoing guide to what’s new and notable in the world of Android development.</p><h3>Episode 68 Video and Podcast</h3><p><em>Now in Android</em> is also offered as a video and podcast.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FSHEbEakgr5w%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DSHEbEakgr5w&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FSHEbEakgr5w%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/3a12628ae18bc3216ea5130b27c4353f/href">https://medium.com/media/3a12628ae18bc3216ea5130b27c4353f/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=%2F%2Fhtml5-player.libsyn.com%2Fembed%2Fepisode%2Fid%2F24375201%2Fheight%2F90%2Ftheme%2Fcustom%2Fthumbnail%2Fyes%2Fdirection%2Fforward%2Frender-playlist%2Fno%2Fcustom-color%2F88AA3C%2F&amp;display_name=Libsyn&amp;url=https%3A%2F%2Fnowinandroid.libsyn.com%2F-68-privacy-sandbox-architecture-performance-and-more&amp;image=https%3A%2F%2Fassets.libsyn.com%2Fsecure%2Fcontent%2F136340691&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=libsyn" width="600" height="90" frameborder="0" scrolling="no"><a href="https://medium.com/media/0b48b0de1f9189d40dd6ffa3b54c0330/href">https://medium.com/media/0b48b0de1f9189d40dd6ffa3b54c0330/href</a></iframe><h3>Privacy Sandbox developer preview 5 🔐</h3><p>The <a href="https://developer.android.com/design-for-safety/privacy-sandbox">Privacy Sandbox</a> aims to develop new technologies that improve user privacy and enable effective, personalized advertising experiences for mobile apps. Developer Preview 5 was released, this version is a major milestone that will become the foundation for upcoming Privacy Sandbox Beta releases. Please keep giving us your feedback! See what’s changed in the blog post:</p><p><a href="https://android-developers.googleblog.com/2022/09/privacy-sandbox-developer-preview-5-is-here.html">Privacy Sandbox: Developer Preview 5 is here!</a></p><h3>Guide to app modularization 🧩</h3><p>The team just released new <a href="https://developer.android.com/topic/modularization">guidance on modularization</a>. Guidance on this topic has been one of the top community requests and here it is! The guide is split into two parts. The <a href="https://developer.android.com/topic/modularization">overview page</a> gives you a high level, theoretical overview of the matter and its benefits. The <a href="https://developer.android.com/topic/modularization/patterns">common modularization patterns page</a> dives deep into practical examples in the context of modern Android architecture. Take a look at the guide announcement blog post to learn more about this.</p><p><a href="https://android-developers.googleblog.com/2022/09/announcing-new-guide-to-android-app-modularization.html">Announcing the new guide to Android app modularization</a></p><h3>More Architecture guidance 🏛</h3><p>Apart from modularization, the team released more Architecture content!</p><p>If you need to make your app work offline, we got you covered. The <strong>new </strong><a href="https://developer.android.com/topic/architecture/data-layer/offline-first"><strong>Build an offline-first app guide</strong></a> helps you design your app to properly handle reads and writes, and deal with synchronization and conflict resolution in a device with no Internet connectivity.</p><p>Another new guide is the <a href="https://developer.android.com/topic/architecture/ui-layer/stateholders"><strong>State holders and UI state page</strong></a><strong> in the UI layer docs</strong>. Not everything needs to be present in ViewModel classes. This page goes through the different types of state holders you can find in the UI layer and what their responsibilities are.</p><p>Lastly, if you want to learn all about Architecture and be up-to-date with our current best practices, <strong>check out the </strong><a href="https://developer.android.com/courses/pathways/android-architecture"><strong>Architecture pathway</strong></a>, that got updated with all the videos of the Architecture MAD Skills series we produced early this year and the new docs.</p><h3>Mad Skills: Performance ⚡️</h3><p>The MAD Skills series has come to an end with the usual Live Q&amp;A where <a href="https://twitter.com/keyboardsurfer">Ben Weiss</a>, <a href="https://twitter.com/mlykotom">Tomáš Mlynarič</a>, Carmen Jackson, and <a href="https://twitter.com/chris_craik">Chris Craik</a> answered your questions.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FhsK5kggwIcM%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DhsK5kggwIcM&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FhsK5kggwIcM%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/b7ba307eaa9e25d0d94068ac757b7166/href">https://medium.com/media/b7ba307eaa9e25d0d94068ac757b7166/href</a></iframe><p>To wrap up the series, Ben wrote this blog post that contains a summary of all the videos! Don’t miss it out!</p><p><a href="https://medium.com/androiddevelopers/mad-skills-performance-wrap-up-33688abfc51f">MAD Skills Performance — Wrap Up</a></p><h3>AndroidX releases 🚀</h3><p>Since the previous episode, there are some AndroidX releases worth highlighting.</p><p><a href="https://developer.android.com/jetpack/androidx/releases/core">Core and core-ktx</a> made it to 1.9.0 <strong>stable</strong>. This version improves compatibility with Android 13 adding parity between the accessibility framework and compat APIs, and some other additions. Other releases include <strong>new in beta</strong> <a href="https://developer.android.com/jetpack/androidx/releases/car-app#1.3.0-beta01">Car app</a> 1.3, and <strong>new in alpha</strong> <a href="https://developer.android.com/jetpack/androidx/releases/navigation#2.6.0-alpha01">Navigation</a> 2.6 and <a href="https://developer.android.com/jetpack/androidx/releases/test-uiautomator#2.3.0-alpha01">Test Ui Automator</a> 2.3.</p><p>See the rest of AndroidX releases in this <a href="https://developer.android.com/jetpack/androidx/versions/all-channel">link</a>.</p><h3>Articles 📚 and videos 🎥</h3><p>The Developer Relations team wrote about <a href="https://android-developers.googleblog.com/2022/08/precise-improvements-how-tiktok-enhanced-its-social-experience-on-android.html">how TikTok Enhanced its Video Social Experience on Android</a>. They were able to significantly improve their overall performance by following Android’s <a href="https://developer.android.com/topic/performance">performance guidance</a>, and employing their deep understanding of development tools such as <a href="https://developer.android.com/studio/build/dependencies">Android Gradle Plugin</a> and <a href="https://developer.android.com/jetpack/androidx/explorer">Jetpack libraries</a>. Read more here!</p><p><a href="https://android-developers.googleblog.com/2022/08/precise-improvements-how-tiktok-enhanced-its-social-experience-on-android.html">Precise Improvements: How TikTok Enhanced its Video Social Experience on Android</a></p><p><a href="https://medium.com/@iamsabs">Sabs</a> started a crash course series about deep links. The first part is an introduction to deep links with a <a href="https://medium.com/androiddevelopers/the-deep-links-crash-course-part-1-introduction-to-deep-links-2189e509e269">blog post</a> and a <a href="https://www.youtube.com/watch?v=1qFIg-lz4Ys">video</a>. Get to know what a deep link is, go from URIs to app links, and more!</p><p><a href="https://medium.com/androiddevelopers/the-deep-links-crash-course-part-1-introduction-to-deep-links-2189e509e269">The deep links crash course, Part 1: Introduction to deep links</a></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F1qFIg-lz4Ys%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D1qFIg-lz4Ys&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F1qFIg-lz4Ys%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/9d2d8037f58985d37dc8e887684967b5/href">https://medium.com/media/9d2d8037f58985d37dc8e887684967b5/href</a></iframe><p>The second part goes over the different types of deep links. How to set them up, test them, and build the best user experience around them.</p><p><a href="https://medium.com/androiddevelopers/the-deep-links-crash-course-part2-deep-links-from-zero-to-hero-37f94cc8fb88">The deep links crash course, Part2: Deep links from Zero to Hero</a></p><p><a href="https://medium.com/@marxallski">Marcel</a> wrote about <a href="https://medium.com/androiddevelopers/experimenting-with-jetpack-glance-35fbffe520f4">experimenting with Jetpack Glance</a> that covers a <a href="https://github.com/google/glance-experimental-tools">standalone experimental repository</a> to supplement Jetpack Glance with tools that are commonly required for development but not yet available. At the moment, it includes a composable to display RemoteViews inside your app (enabling <a href="https://developer.android.com/jetpack/compose/tooling#live-edit">Live Edit</a>), a debug tool to view and interact with AppWidget snapshots embedded inside the app, and a Material3 Scaffold for AppWidgets.</p><p><a href="https://medium.com/androiddevelopers/experimenting-with-jetpack-glance-35fbffe520f4">Experimenting with Jetpack Glance</a></p><p><a href="https://medium.com/@bentrengrove">Ben Trengove</a> wrote about <a href="https://medium.com/androiddevelopers/jetpack-compose-debugging-recomposition-bfcf4a6f8d37">Debugging recomposition in Compose</a>. Check it out because it also contains a <a href="https://www.youtube.com/watch?v=SWBN0y0lFNY">screencast</a> of Ben fixing a performance issue in Jetsnack, a Compose sample. For this, Ben also uses the layout inspector in Android Studio where you can see the <a href="https://developer.android.com/jetpack/compose/tooling#recomposition-counts">recomposition and skip counts</a> of composable functions.</p><p><a href="https://medium.com/androiddevelopers/jetpack-compose-debugging-recomposition-bfcf4a6f8d37">Jetpack Compose: Debugging Recomposition</a></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FSWBN0y0lFNY&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DSWBN0y0lFNY&amp;image=http%3A%2F%2Fi.ytimg.com%2Fvi%2FSWBN0y0lFNY%2Fhqdefault.jpg&amp;key=d04bfffea46d4aeda930ec88cc64b87c&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/a97bb1a2108e4ff1a91e44649a80b80f/href">https://medium.com/media/a97bb1a2108e4ff1a91e44649a80b80f/href</a></iframe><p><a href="https://twitter.com/theDroidLady">Nikariha</a> started another blog post series about optimizing for Android Go edition. The first part introduces Android Go edition, why you’d want to build for it, and some best practices based on experience building the Gboard and Camera from Google apps.</p><p><a href="https://android-developers.googleblog.com/2022/09/optimize-for-android-go-lessons-from-google-apps-part-1.html">Optimize for Android (Go edition): Lessons from Google apps - Part 1</a></p><h3>ADB Podcast Episodes🎙</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/200/0*NXPIsT7j6pCqxAHO" /></figure><p>There has been one episode of <a href="https://adbackstage.libsyn.com/">Android Developers Backstage</a> posted since the last Now in Android. Check it out at the link below, or in your favorite podcast client:</p><p>In <a href="https://adbackstage.libsyn.com/episode-188-android-13">Episode 188: Android 13</a>, Chet, Romain, and Tor talk about some of their favorite new features and changes of the new version of Android, both for users and developers.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=%2F%2Fhtml5-player.libsyn.com%2Fembed%2Fepisode%2Fid%2F24242235%2Fheight%2F90%2Ftheme%2Fcustom%2Fthumbnail%2Fyes%2Fdirection%2Fforward%2Frender-playlist%2Fno%2Fcustom-color%2F88AA3C%2F&amp;display_name=Libsyn&amp;url=https%3A%2F%2Fadbackstage.libsyn.com%2Fepisode-188-android-13&amp;image=https%3A%2F%2Fassets.libsyn.com%2Fsecure%2Fitem%2F24242235&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=libsyn" width="600" height="90" frameborder="0" scrolling="no"><a href="https://medium.com/media/e662f173d047817d6be9e4317e9a56ac/href">https://medium.com/media/e662f173d047817d6be9e4317e9a56ac/href</a></iframe><h3>Now then… 👋</h3><p>That’s it for this time, with a new developer preview of the <a href="https://android-developers.googleblog.com/2022/09/privacy-sandbox-developer-preview-5-is-here.html">privacy sandbox</a>, <a href="https://developer.android.com/topic/modularization">modularization</a>, <a href="https://developer.android.com/topic/architecture/data-layer/offline-first">offline-first</a>, and <a href="https://developer.android.com/topic/architecture/ui-layer/stateholders">state holder</a> Architecture guidance, the end of the <a href="https://medium.com/androiddevelopers/mad-skills-performance-wrap-up-33688abfc51f">Performance MAD Skills series</a>, <a href="https://developer.android.com/jetpack/androidx/versions/all-channel">AndroidX releases</a>, articles on <a href="https://android-developers.googleblog.com/2022/08/precise-improvements-how-tiktok-enhanced-its-social-experience-on-android.html">performance</a>, <a href="https://medium.com/androiddevelopers/the-deep-links-crash-course-part-1-introduction-to-deep-links-2189e509e269">deep links</a>, <a href="https://medium.com/androiddevelopers/experimenting-with-jetpack-glance-35fbffe520f4">Jetpack Glance</a>, <a href="https://medium.com/androiddevelopers/jetpack-compose-debugging-recomposition-bfcf4a6f8d37">debugging recomposition</a>, <a href="https://android-developers.googleblog.com/2022/09/optimize-for-android-go-lessons-from-google-apps-part-1.html">building for Android Go edition</a>, and a <a href="https://adbackstage.libsyn.com/episode-187-system-ui-a-retrospective">new episode of ADB</a>! <strong>Come back here soon for the next update from the Android developer universe!</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f695e822863c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/androiddevelopers/now-in-android-68-f695e822863c">Now in Android #68</a> was originally published in <a href="https://medium.com/androiddevelopers">Android Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Consuming flows safely in Jetpack Compose]]></title>
            <link>https://medium.com/androiddevelopers/consuming-flows-safely-in-jetpack-compose-cde014d0d5a3?source=rss-3b5622dd813c------2</link>
            <guid isPermaLink="false">https://medium.com/p/cde014d0d5a3</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[jetpack-compose]]></category>
            <category><![CDATA[android-development]]></category>
            <category><![CDATA[architecture]]></category>
            <category><![CDATA[resources]]></category>
            <dc:creator><![CDATA[Manuel Vivo]]></dc:creator>
            <pubDate>Wed, 10 Aug 2022 17:01:35 GMT</pubDate>
            <atom:updated>2023-03-07T14:16:23.122Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LL7FLWzjT4c6bQdGlvdz7w.png" /></figure><p>Collecting flows in a lifecycle-aware manner is the <a href="https://developer.android.com/topic/architecture/ui-layer#consume-ui-state">recommended way</a> to collect flows on Android. If you’re building an Android app with Jetpack Compose, use the collectAsStateWithLifecycle API to collect flows in a lifecycle-aware manner from your UI.</p><p>collectAsStateWithLifecycle allows your app to save app resources when not needed, such as when the app is in the background. Keeping resources alive unnecessarily can impact the user’s device health. Such resources may include firebase queries, location or network updates, and database connections.</p><p>Keep reading to know more about this API, why you should collect in a lifecycle-aware manner, and how it compares to the collectAsState API.</p><h3>collectAsStateWithLifecycle</h3><p>collectAsStateWithLifecycle is a composable function that collects values from a flow and represents the latest value as Compose <a href="https://developer.android.com/reference/kotlin/androidx/compose/runtime/State">State</a> in a lifecycle-aware manner. Every time a new flow emission occurs, the value of this State object updates. This causes a recomposition of every State.value usage in the Composition.</p><p>By default, collectAsStateWithLifecycle uses <a href="https://developer.android.com/reference/android/arch/lifecycle/Lifecycle.State#started">Lifecycle.State.STARTED</a> to start and stop collecting values from the flow. This occurs when the Lifecycle moves in and out of the target state. This lifecycle state is something you can configure in the minActiveState parameter.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*_X0J2wnopl_wNEU8" /><figcaption><em>collectAsStateWithLifecycle cancels the flow collection when the app is in the background by default</em></figcaption></figure><p>The following snippet demonstrates is how to use collectAsStateWithLifecycle to collect a StateFlow’s uiState field that a ViewModel in your composable function has exposed:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/873057a87e137a7ef05726a233a5e09d/href">https://medium.com/media/873057a87e137a7ef05726a233a5e09d/href</a></iframe><p>Every time the <a href="https://github.com/android/nowinandroid/blob/main/feature-author/src/main/java/com/google/samples/apps/nowinandroid/feature/author/AuthorViewModel.kt">AuthorViewModel</a>’s uiState emits a new AuthorScreenUiState value, <a href="https://github.com/android/nowinandroid/blob/main/feature-author/src/main/java/com/google/samples/apps/nowinandroid/feature/author/AuthorScreen.kt">AuthorRoute</a> will be recomposed. For more usages of collectAsStateWithLifecycle, check out the <a href="https://github.com/android/nowinandroid/search?q=collectAsStateWithLifecycle">Now in Android app</a>, and <a href="https://github.com/android/nowinandroid/pull/166">its migration PR</a>.</p><p>To start using the collectAsStateWithLifecycle API in your project, add the androidx.lifecycle.lifecycle-runtime-compose artifact to your project.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/debac1beb15e76c44c4057336f84eac9/href">https://medium.com/media/debac1beb15e76c44c4057336f84eac9/href</a></iframe><h3>Under the hood</h3><p>Under the hood, the <a href="https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:lifecycle/lifecycle-runtime-compose/src/main/java/androidx/lifecycle/compose/FlowExt.kt;l=168">implementation of </a><a href="https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:lifecycle/lifecycle-runtime-compose/src/main/java/androidx/lifecycle/compose/FlowExt.kt;l=168">collectAsStateWithLifecycle</a> uses the <a href="https://developer.android.com/reference/kotlin/androidx/lifecycle/package-summary#(androidx.lifecycle.Lifecycle).repeatOnLifecycle(androidx.lifecycle.Lifecycle.State,kotlin.coroutines.SuspendFunction1)">repeatOnLifecycle</a> API which is the recommended way to collect flows in Android using the View system.</p><p>collectAsStateWithLifecycle saves you from typing the boilerplate code shown below that also collects flows in a lifecycle-aware manner from a composable function:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8c0a6affed5d61477cfa7a1ef5a3027a/href">https://medium.com/media/8c0a6affed5d61477cfa7a1ef5a3027a/href</a></iframe><h3>Flow collection in your architecture</h3><p>Types in your app architecture shouldn’t know about the implementation details of other types. The UI shouldn’t know <em>how</em> the ViewModel produces the UI state.<strong> </strong>If the UI is not visible on the screen, the flow collection should stop to free up app resources if appropriate.</p><p>The UI can help free up resources by collecting the UI state using collectAsStateWithLifecycle. The ViewModel can do the same by producing the UI state in a collector-aware manner. If there are no collectors , such as when the UI isn’t visible on screen, stop the upstream flows coming from the data layer. You can do so using the <a href="https://github.com/android/nowinandroid/blob/main/feature-author/src/main/java/com/google/samples/apps/nowinandroid/feature/author/AuthorViewModel.kt#L104">.stateIn(WhileSubscribed)</a> flow API when producing the UI state. For more information about this, watch <a href="https://youtu.be/fSB6_KE95bU?t=1009">this part of the Kotlin flows in practice talk</a>. For testing the ViewModel producing UI state in this way, check out the <a href="https://developer.android.com/kotlin/flow/test#statein">testing guide</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*WoIKlW_GaW82KFeW" /><figcaption><em>In the UI layer, consume the UI state using collectAsStateWithLifecycle and produce it using .stateIn(WhileSubscribed) when the data layer exposes reactive streams. This enables the rest of the app to free up resources when not needed.</em></figcaption></figure><p>Consumers and producers of flows don’t need to know how each other is implemented. Figuring out implementation details in a big app with multiple environments, variants, libraries, and features can be very time consuming. And even worse, maintaining code that relies on implementation details is hard.</p><h3>Keeping resources active in the background</h3><p>Android apps can run on a myriad of Android devices. Unfortunately, not all devices and not all users have endless resources. Apps usually run in a constrained environment. When an Android app is running, there are important factors that impact the user experience and device system health:</p><ul><li><strong>CPU usage</strong>: CPUs have the highest battery consumption of all device components. Battery life is a perennial user concern. If abused, users might uninstall your app.</li><li><strong>Data usage</strong>: Reducing network traffic in an app when not connected to Wi-Fi can help users save money.</li><li><strong>Memory usage:</strong> How an app uses memory can have a very large impact on the overall stability and performance of the device.</li></ul><p>An Android developer that wants to respect the user, device system health, or <a href="https://developer.android.com/docs/quality-guidelines/build-for-billions">build for billions</a> should optimize these different factors depending on the market, devices, or countries they’re targeting. Keeping unneeded resources alive can have a negative impact depending on the type of device and the Android version the device is running. Using collectAsStateWithLifecycle in the UI layer enables the rest of the hierarchy to free up resources.</p><h3>collectAsState comparison</h3><p>Developers often ask: if collectAsStateWithLifecycle is the safest way to collect flows from composable functions in Android, <em>why do we need the </em><em>collectAsState API now? or why not add the lifecycle-aware functionality to </em><em>collectAsState instead of creating a new API?</em></p><p>The lifecycle of a composable function is agnostic to the platform Compose is running on. As documented on the <a href="https://developer.android.com/jetpack/compose/lifecycle">Lifecycle of composables page</a>, instances of composable functions enter the Composition, recompose 0 or more times, and leave the Composition.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*MZkRry7NwG7hcyXM" /><figcaption><em>Lifecycle of an instance of a composable function in the Composition</em></figcaption></figure><p>The collectAsState API follows the Composition’s lifecycle. It starts collecting the flow when the composable enters the Composition and stops collecting when it leaves the Composition. collectAsState is the platform-agnostic API you can use to collect flows.</p><p>However, when using Compose in an Android app, the Android lifecycle also plays a critical role in how resources should be managed. Even if Compose halts recompositions while the Android app is in the background, collectAsState keeps the collection active. This makes it impossible for the rest of the hierarchy to free up resources.</p><p>Both collectAsState and collectAsStateWithLifecycle have a purpose in Compose. The latter when developing Android apps, the former when developing for other platforms.</p><p>Migrating from collectAsState to collectAsStateWithLifecycle is a no-brainer:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/494999faa0e3b0bbb52b2246680703f1/href">https://medium.com/media/494999faa0e3b0bbb52b2246680703f1/href</a></iframe><p>Collecting flows in a lifecycle-aware manner is the recommended way to collect flows on Android to enable other parts of your app to free up resources if needed.</p><p>If you’re building an Android app with Jetpack Compose, use the collectAsStateWithLifecycle composable function to do this.</p><p>P.S. Thanks to <a href="https://medium.com/u/e0a4c9469bb5">Jose Alcérreca</a>, <a href="https://medium.com/u/ec2087b3c81f">Marton Braun</a>, <a href="https://medium.com/u/92c44d274e60">Alejandra Stamato</a>, and Jake Roseman for reviewing this article.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cde014d0d5a3" width="1" height="1" alt=""><hr><p><a href="https://medium.com/androiddevelopers/consuming-flows-safely-in-jetpack-compose-cde014d0d5a3">Consuming flows safely in Jetpack Compose</a> was originally published in <a href="https://medium.com/androiddevelopers">Android Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Now in Android #65]]></title>
            <link>https://medium.com/androiddevelopers/now-in-android-65-5dad5bb2c0cb?source=rss-3b5622dd813c------2</link>
            <guid isPermaLink="false">https://medium.com/p/5dad5bb2c0cb</guid>
            <category><![CDATA[featured]]></category>
            <category><![CDATA[now-in-android]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[latest]]></category>
            <category><![CDATA[jetpack-compose]]></category>
            <dc:creator><![CDATA[Manuel Vivo]]></dc:creator>
            <pubDate>Wed, 03 Aug 2022 21:58:15 GMT</pubDate>
            <atom:updated>2022-08-05T14:24:24.901Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*3zsNaCoZ6ZdFuX-Z" /><figcaption>Illustration by <a href="https://twitter.com/VPoltrack">Virginia Poltrack</a></figcaption></figure><h4>Android 13 Beta 4, Predictive back gestures, Jetpack Compose, Wear OS, Text gradients, Large screens, System UI, and more!</h4><p>Welcome to Now in Android, your ongoing guide to what’s new and notable in the world of Android development.</p><p><strong>Episode 65 Video and Podcast</strong></p><p><em>Now in Android</em> is also offered as a video and podcast.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FI00YEO1J1bo%3Flist%3DPLWz5rJ2EKKc9AtgKMBBdphI-mrx8XzW56&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DI00YEO1J1bo&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FI00YEO1J1bo%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/348ae6b2afa05a04b874f1685b451114/href">https://medium.com/media/348ae6b2afa05a04b874f1685b451114/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=%2F%2Fhtml5-player.libsyn.com%2Fembed%2Fepisode%2Fid%2F23950908%2Fheight%2F90%2Ftheme%2Fcustom%2Fthumbnail%2Fyes%2Fdirection%2Fforward%2Frender-playlist%2Fno%2Fcustom-color%2F88AA3C%2F&amp;display_name=Libsyn&amp;url=https%3A%2F%2Fnowinandroid.libsyn.com%2F65-android-13-beta-4-jetpack-compose-12-stable-wear-os-and-more&amp;image=https%3A%2F%2Fassets.libsyn.com%2Fsecure%2Fcontent%2F133293873&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=libsyn" width="600" height="90" frameborder="0" scrolling="no"><a href="https://medium.com/media/9063d0ff242913197b15fc6b52cebb50/href">https://medium.com/media/9063d0ff242913197b15fc6b52cebb50/href</a></iframe><h3>Android 13 Beta 4</h3><p>We’re just a few weeks away from the official release of Android 13! Meanwhile, we published the last Beta for your testing and development. We <a href="https://android-developers.googleblog.com/2022/06/android-13-beta-3-platform-stability.html">reached Platform Stability at Beta 3</a>, so all app-facing surfaces are final, including SDK and NDK APIs, app-facing system behaviors, and restrictions on non-SDK interfaces. With these and the latest fixes and optimizations, <strong>Beta 4 gives you everything you need to complete your testing</strong>.</p><p>Take a look at the <a href="https://android-developers.googleblog.com/2022/07/Final-Android-13-Beta-update-official-release-is-next.html">blog post</a> for everything you need to check and test. Watch for information on the official Android 13 launch coming in the weeks ahead! Until then, feel free to <a href="https://developer.android.com/preview/feedback">continue sharing your feedback</a> through our hotlists for <a href="https://issuetracker.google.com/issues/new?component=190602&amp;template=1658301">platform issues</a>, <a href="https://issuetracker.google.com/issues/new?component=190602&amp;template=1658359">app compatibility issues</a>, and <a href="https://issuetracker.google.com/issues/new?component=190602&amp;template=1658360">third-party SDK issues</a>.</p><p><a href="https://android-developers.googleblog.com/2022/07/Final-Android-13-Beta-update-official-release-is-next.html">Final Android 13 Beta update, official release is next!</a></p><h3>10 years of Google Play</h3><p>In 2012, the team opened the (digital) doors of Google Play. A decade later, more than 2.5 billion people in over 190 countries use Google Play every month to discover apps, games and digital content. And more than 2 million developers work with us to build their businesses and reach people around the globe! Congratulations to the Google Play team for this huge milestone.</p><p><a href="https://android-developers.googleblog.com/2022/03/celebrating-10-years-of-google-play.html">Celebrating 10 years of Google Play. Together.</a></p><h3>Android Basics with Compose Unit 3 available</h3><p>The Unit 3 of Android Basics with Compose course is available already! Unit 3 covers how to build apps that display a list of data and how to make your apps more beautiful with Material Design.</p><p>This is a continuation of the previous units that starts with learning programming basics and creating your first Android app, and continues with the fundamentals of Kotlin, and building more interactive apps.</p><p><a href="https://developer.android.com/courses/android-basics-compose/course">https://developer.android.com/courses/android-basics-compose/course</a></p><h3>Jetpack Compose 1.2 is now stable</h3><p>This release contains new features like downloadable fonts, lazy grids, and improvements for tablets and Chrome OS with better focus, mouse, and input handling.</p><p>Read the blog post for more information about the new features and APIs, the bugs fixed, and the <a href="https://developer.android.com/jetpack/androidx/compose-roadmap">updated Compose public roadmap</a>.</p><p><a href="https://android-developers.googleblog.com/2022/07/jetpack-compose-1-2-is-now-stable.html">Jetpack Compose 1.2 is now stable!</a></p><h3>Compose for Wear OS is now 1.0</h3><p>The first stable release of our modern declarative UI toolkit is designed to help developers create beautiful, responsive apps for Google’s smartwatch platform.</p><p>Compose for Wear OS makes building apps for Wear OS easier, faster, and more intuitive by following the declarative approach and offering powerful Kotlin syntax. Moving forward, <strong>Compose for Wear OS is our recommended approach for building user interfaces</strong> for <a href="https://developer.android.com/training/wearables/user-interfaces#overlay">Wear OS apps</a>.</p><p>Read the blog post for more information about what’s included in the 1.0 stable release, the tooling available in Android Studio, and how to get started.</p><p><a href="https://android-developers.googleblog.com/2022/07/compose-for-wear-os-10-stable.html">Compose for Wear OS is now 1.0: time to build wearable apps with Compose!</a></p><h3>AndroidX releases 🚀</h3><p>Apart from the Jetpack Compose 1.2 and Compose for Wear OS 1.0 stable releases, there has been a bunch of interesting stuff released in <a href="https://developer.android.com/jetpack/androidx/versions">AndroidX</a>.</p><p>Stable are also the <a href="https://developer.android.com/jetpack/androidx/releases/core#core-splashscreen-1.0.0">Core splashscreen v1.0</a>, and <a href="https://developer.android.com/jetpack/androidx/releases/profileinstaller#version_120_3">Profile Installer v1.2</a>. In RC, you can find <a href="https://developer.android.com/jetpack/androidx/releases/appcompat#version_150_2">AppCompat v1.5</a>, <a href="https://developer.android.com/jetpack/androidx/releases/compose-compiler#version_13_2">Compose Compiler v1.3</a> that brings support to Kotlin version 1.7.10, <a href="https://developer.android.com/jetpack/androidx/releases/emoji2#version_12_2">Emoji2 v1.2</a>, and <a href="https://developer.android.com/jetpack/androidx/releases/sharetarget#version_120_2">ShareTarget v1.2</a>. Lastly, <a href="https://developer.android.com/jetpack/androidx/releases/wear-tiles#version_11_2">Wear Tiles v1.1</a> reached its first beta version</p><p>See the rest of AndroidX releases in this <a href="https://developer.android.com/jetpack/androidx/versions/all-channel">link</a>.</p><h3>Articles 📚</h3><p><a href="https://tiwiz.medium.com/"><strong>Roberto Orgiu</strong></a><strong> wrote about how to </strong><a href="https://medium.com/androiddevelopers/make-your-app-large-screen-ready-baf8fe505ae7"><strong>make your app large screen ready</strong></a><strong>!</strong> Give it a read if you want to know how to get started with large screen support and why it is so important. Accurately handling orientation changes, aspect ratios, and adaptive layouts may seem challenging, but with new large screen experiences in mind, multiple form factors bring new possibilities to your users.</p><p><a href="https://medium.com/androiddevelopers/make-your-app-large-screen-ready-baf8fe505ae7">Make your app large screen ready</a></p><p><a href="https://medium.com/@ataulm"><strong>Ataul Munim</strong></a><strong> wrote about Wear OS 3!</strong> You don’t need a physical device to test your Wear apps. Read <a href="https://medium.com/androiddevelopers/get-familiar-with-wear-os-3-without-a-physical-device-e7962c97f02b">this article</a> to take a brief look at unique UI surfaces on Wear OS, create a Wear emulator and explore it from a user perspective.</p><p><a href="https://medium.com/androiddevelopers/get-familiar-with-wear-os-3-without-a-physical-device-e7962c97f02b">Get familiar with Wear OS 3 (without a physical device)</a></p><p><a href="https://medium.com/@arriolachris"><strong>Chris Arriola</strong></a><strong> wrote about </strong><a href="https://medium.com/androiddevelopers/jetpack-compose-interop-using-compose-in-a-recyclerview-569c7ec7a583"><strong>Jetpack Compose interop: Using Compose in a RecyclerView</strong></a> which covers what versions of Compose and RecyclerView you need to use to get the best performance. Furthermore, you’ll understand how the interop works under the hood.</p><p><a href="https://medium.com/androiddevelopers/jetpack-compose-interop-using-compose-in-a-recyclerview-569c7ec7a583">Jetpack Compose Interop: Using Compose in a RecyclerView</a></p><p><a href="https://medium.com/@astamato"><strong>Alejandra Stamato</strong></a><strong> wrote two blog posts about text coloring in Compose</strong>. The first one, <a href="https://medium.com/androiddevelopers/brushing-up-on-compose-text-coloring-84d7d70dd8fa"><strong>Brushing up on Compose Text coloring</strong></a>, is a very colorful blog post about how to work with Brush API together with TextStyle to achieve complex text coloring like giving a gradient to your text in a simple way.</p><p><a href="https://medium.com/androiddevelopers/brushing-up-on-compose-text-coloring-84d7d70dd8fa">Brushing up on Compose Text coloring</a></p><p><strong>The second one, </strong><a href="https://medium.com/androiddevelopers/animating-brush-text-coloring-in-compose-%EF%B8%8F-26ae99d9b402"><strong>Animating brush Text coloring in Compose 🖌️</strong></a>, covers how to animate gradients in your text using the Brush API and Compose animations. Go check them out, I can’t stop looking at those animations now!</p><p><a href="https://medium.com/androiddevelopers/animating-brush-text-coloring-in-compose-%EF%B8%8F-26ae99d9b402">Animating brush Text coloring in Compose 🖌️</a></p><p><strong>Diego Zuluaga and Jason Tang wrote the </strong><a href="https://android-developers.googleblog.com/2022/07/prepare-your-app-to-support-predictive-back-gestures.html"><strong>Prepare your app to support predictive back gestures</strong></a><strong> blog post</strong>. Predictive back gestures is a feature that will be available in future versions of Android. However, to give you more time to adopt it, we made it available in the developer options of Android 13 Beta 4. Read the blog post for details on how to try out the new gesture and support it in your apps. Spoiler alert: it’s straightforward for most apps!</p><p><a href="https://android-developers.googleblog.com/2022/07/prepare-your-app-to-support-predictive-back-gestures.html">Prepare your app to support predictive back gestures</a></p><h3>ADB Podcast Episodes🎙</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/200/0*MvxyJJZfDghjECKO" /></figure><p>There has been one episode of <a href="https://adbackstage.libsyn.com/">Android Developers Backstage</a> posted since the last Now in Android. Check it out at the link below, or in your favorite podcast client:</p><p>In <a href="https://adbackstage.libsyn.com/episode-187-system-ui-a-retrospective">Episode 187: System UI: A Retrospective</a>, Tor and Chet meet Dan Sandler and Adam Cohen from the SystemUI team. They dip into a bit of history, talking about where things were at when they joined the team, and how things have developed in the many years since. They also talk about how to expose (or not) gestures and features in a UI system.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=%2F%2Fhtml5-player.libsyn.com%2Fembed%2Fepisode%2Fid%2F23855616%2Fheight%2F90%2Ftheme%2Fcustom%2Fthumbnail%2Fyes%2Fdirection%2Fforward%2Frender-playlist%2Fno%2Fcustom-color%2F88AA3C%2F&amp;display_name=Libsyn&amp;url=https%3A%2F%2Fadbackstage.libsyn.com%2Fepisode-187-system-ui-a-retrospective&amp;image=https%3A%2F%2Fassets.libsyn.com%2Fsecure%2Fitem%2F23855616&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=libsyn" width="600" height="90" frameborder="0" scrolling="no"><a href="https://medium.com/media/67cff9ff4426f1ee427fdc22c2e7525f/href">https://medium.com/media/67cff9ff4426f1ee427fdc22c2e7525f/href</a></iframe><h3>Now then… 👋</h3><p>That’s it for this time, with <a href="https://android-developers.googleblog.com/2022/07/Final-Android-13-Beta-update-official-release-is-next.html">Android 13 reaching Beta 4</a>, <a href="https://android-developers.googleblog.com/2022/03/celebrating-10-years-of-google-play.html">10 years of Google Play</a>, articles on <a href="https://medium.com/androiddevelopers/make-your-app-large-screen-ready-baf8fe505ae7">large screens</a> and <a href="https://medium.com/androiddevelopers/get-familiar-with-wear-os-3-without-a-physical-device-e7962c97f02b">Wear OS 3</a>, <a href="https://medium.com/androiddevelopers/jetpack-compose-interop-using-compose-in-a-recyclerview-569c7ec7a583">Compose interop with RecyclerView</a>, <a href="https://medium.com/androiddevelopers/brushing-up-on-compose-text-coloring-84d7d70dd8fa">Compose Text coloring</a>, <a href="https://medium.com/androiddevelopers/animating-brush-text-coloring-in-compose-%EF%B8%8F-26ae99d9b402">animating the text coloring</a>, and <a href="https://android-developers.googleblog.com/2022/07/prepare-your-app-to-support-predictive-back-gestures.html">predictive back gestures</a>, a bunch of <a href="https://developer.android.com/jetpack/androidx/versions/all-channel">AndroidX releases</a>, and a <a href="https://adbackstage.libsyn.com/episode-187-system-ui-a-retrospective">new episode of ADB</a>!</p><p><strong>Come back here soon for the next update from the Android developer universe.</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5dad5bb2c0cb" width="1" height="1" alt=""><hr><p><a href="https://medium.com/androiddevelopers/now-in-android-65-5dad5bb2c0cb">Now in Android #65</a> was originally published in <a href="https://medium.com/androiddevelopers">Android Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>