<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Marco Coelho</title>
    <description>The latest articles on DEV Community by Marco Coelho (@marcotcdev).</description>
    <link>https://dev.to/marcotcdev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2718686%2F243d4f66-7fb5-4907-bd24-0a500a6858ec.png</url>
      <title>DEV Community: Marco Coelho</title>
      <link>https://dev.to/marcotcdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marcotcdev"/>
    <language>en</language>
    <item>
      <title>5 things every senior developer must ask before modernizing legacy software</title>
      <dc:creator>Marco Coelho</dc:creator>
      <pubDate>Tue, 24 Feb 2026 02:58:44 +0000</pubDate>
      <link>https://dev.to/marcotcdev/5-things-every-senior-developer-must-ask-before-modernizing-legacy-software-2nll</link>
      <guid>https://dev.to/marcotcdev/5-things-every-senior-developer-must-ask-before-modernizing-legacy-software-2nll</guid>
      <description>&lt;p&gt;Pretty much every software developer has, at some point in their career, had to maintain old software. It could be a legacy system created in days gone by, or software recently built using outdated technology to preserve some backward compatibility. Either way, you've probably faced this challenge at some point: &lt;em&gt;What do I need to ask before modernizing a piece of software?&lt;/em&gt; Here are five important questions you should ask yourself when working on an old project before you begin modernizing it.&lt;/p&gt;

&lt;h3&gt;
  
  
  First Question: Why Was It Created?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fin9v8ye3kxt6f8wn4i6s.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fin9v8ye3kxt6f8wn4i6s.webp" alt=" " width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first question you have to ask is why this software was created. This is the fundamental question: Why does this software exist? Talk to the people who use it, review the documentation, and try to find out as much as possible about its origins. What problem was this software meant to solve? Did it solve that problem entirely, or was it only a partial success? Does the issue that originally required this software still exist, or has it since been resolved by other means?&lt;/p&gt;

&lt;p&gt;Understanding why this system or solution was created in the first place is essential. Depending on the answer, you may already be able to determine whether it makes sense to invest effort in modernizing it or not.&lt;/p&gt;

&lt;h3&gt;
  
  
  Second Question: Who Made It, and When?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F01gx8h6myderu1tj9u5a.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F01gx8h6myderu1tj9u5a.gif" alt=" " width="250" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second question is: who made this software? Was it built in-house by the company or institution using it, or was it developed by a third party? You already know &lt;em&gt;why&lt;/em&gt; the software was created, but it's equally important to know &lt;em&gt;by whom&lt;/em&gt;. Knowing who built it also gives you a solid sense of &lt;em&gt;when&lt;/em&gt; it was built.&lt;/p&gt;

&lt;p&gt;With both answers — "Why?" and "Who?" — you can begin to picture the context in which this software came to life: at some point in time, there was a problem, and a person or team created this solution to address it. Just by answering these questions, you'll likely uncover a lot about the infrastructure and technology originally used, whether that's an open-source framework or a paid corporate solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Third Question: Do You Still Need It?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9cz7xxhkd8yfmlumg11w.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9cz7xxhkd8yfmlumg11w.gif" alt=" " width="300" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is another critical question. Now that you understand the context in which this solution was created, the "Why?" and the "Who?". Ask yourself whether you still need to keep it. Think of this as the &lt;em&gt;"For what?"&lt;/em&gt; follow-up question.&lt;/p&gt;

&lt;p&gt;When considering this, factor in your viable alternatives. Could a modern solution be less costly than the effort and budget required to modernize the existing software? To answer this properly, you'll need to calculate how much the current software is costing you today, and how much implementing an alternative would cost.&lt;/p&gt;

&lt;p&gt;Another possibility: You need this software, but only a small part of it, a small piece that solves a lingering problem. In that case, consider modernizing only what is currently required.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fourth Question: Is It Possible to Maintain It As-Is?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4qjo8ky2fy7i1pm0l56p.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4qjo8ky2fy7i1pm0l56p.gif" alt=" " width="480" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By this point, you should have a solid grasp of why this software was created and why it's still in use. The next step is to ask: Can you avoid modernizing it by simply maintaining it in its current state?&lt;/p&gt;

&lt;p&gt;It may seem counterintuitive to ask this in a guide about modernization, but any change carries both a cost and a risk. This is your &lt;em&gt;"May I?"&lt;/em&gt; question, as in, &lt;em&gt;"May I keep it as it is?"&lt;/em&gt;; building on the "Why?", "Who?", and "For what?" questions you've already answered.&lt;/p&gt;

&lt;p&gt;To truly answer this question, you need to weigh the risks of modernizing versus not modernizing. Consider the growing complexity of the project, the costs involved, and the risks that come with changing the code. Keep in mind that new versions of libraries and frameworks are released constantly; code that could be used to update your older project. This is both a blessing and a challenge: Updating libraries can offload some maintenance responsibility, but updating one library may force you to update other libraries in a domino effect.&lt;/p&gt;

&lt;p&gt;This effort needs to be calculated carefully. &lt;strong&gt;You need to identify what is truly critical to modernize and determine the minimum effort required to do so.&lt;/strong&gt; The less time, money, and risk involved, the simpler and more cost-effective the modernization will be for your client.&lt;/p&gt;

&lt;p&gt;Will you replace entire hardware and software components in bulk? Or will you refactor specific pieces of code for better control over the process? Either approach requires deep knowledge of the technology in use and an understanding of how the software evolved over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fifth Question: What Is the Cost of Modernizing It?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstxdqwfcwgj6f8j4ifpg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstxdqwfcwgj6f8j4ifpg.gif" alt=" " width="480" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've reached this fifth question, you've already concluded that modernization is necessary. Regardless of whether you'll rewrite part of the system or all of it, the work must be done. So the final question is: How much is it going to cost?&lt;/p&gt;

&lt;p&gt;It's easy to see why this question must be answered before you start: It tells you whether modernizing this software is even feasible. By answering it upfront, you avoid the painful scenario of running out of time, money, or resources mid-project; thus leaving the work unfinished.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Modernizing software is a risky endeavor. I can't guarantee you'll be able to answer all the questions above. Sometimes it's impossible to know who originally built the software. Sometimes it's difficult to estimate the cost of modernization. And sometimes, the hardest question is whether it needs to be modernized at all.&lt;/p&gt;

&lt;p&gt;There are structured methodologies that can help — such as Architecture Driven Modernization or Model Driven Engineering — but even deciding whether to modernize is a challenge in itself. &lt;strong&gt;When that happens, remember the original reason why you took up the task, and the right decision will eventually become clear.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you found this article helpful, follow me on social media and on dev.to for more content on software modernization and related topics.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Cover image by Freepik - &lt;a href="http://www.freepik.com" rel="noopener noreferrer"&gt;www.freepik.com&lt;/a&gt;&lt;br&gt;
Animated GIFs by GIPHY - &lt;a href="https://giphy.com/" rel="noopener noreferrer"&gt;https://giphy.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>modernizing</category>
      <category>software</category>
      <category>legacy</category>
      <category>developer</category>
    </item>
    <item>
      <title>4 things backend developers should consider when developing services for mobile apps</title>
      <dc:creator>Marco Coelho</dc:creator>
      <pubDate>Sun, 31 Aug 2025 01:59:08 +0000</pubDate>
      <link>https://dev.to/marcotcdev/4-things-backend-developers-should-consider-when-developing-services-for-mobile-apps-5cnf</link>
      <guid>https://dev.to/marcotcdev/4-things-backend-developers-should-consider-when-developing-services-for-mobile-apps-5cnf</guid>
      <description>&lt;p&gt;Let's say you are a backend developer, with some expertise in different systems. One day, your leader assigns you a new task; You have to develop and test a few REST endpoints for an upcoming mobile app. So far, so good. Since you have experience as backend developer, it is not that hard, alright?&lt;/p&gt;

&lt;p&gt;You build and deploy the changes, and everything seems ok in the tests. No issues detected, the app is working fine, and so is the service running in the cloud to communicate with the app. But then, a few weird things start happening. A user complain about not being able to use the app. There was an error in the app first version, you already rolled out a hotfix, but the error seems to persist. Then, the system goes down due to a max quota rule. And you can't debug what is going on, no matter how much you try.&lt;/p&gt;

&lt;p&gt;It is in times like these we would like someone to share with us how to get around problems like those. &lt;em&gt;Lucky for you, in my years as mobile software developer, I learned a few tips about backend development&lt;/em&gt;. So, I'm going to share here four things I learned when developing a backend service for a mobile app.&lt;/p&gt;

&lt;h1&gt;
  
  
  1) You don't control when a mobile app updates
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo4w5cfh7kwu1x6kepg0m.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo4w5cfh7kwu1x6kepg0m.gif" alt=" " width="498" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When developing a website, you will have control when to merge code and deploy. You choose when it's time for the test version to go into the production environment. You may migrate the database first and deploy the backend, or choose the frontend instead. It all depends on how you planned your product version migration. And you have to plan the compatibility between your frontend and backend instances. Either that, or updating both at the same time while keeping the downtime restricted. So far, so good.&lt;/p&gt;

&lt;p&gt;With mobile app development, you may release a new version anytime, but &lt;strong&gt;you can't control when users will install it&lt;/strong&gt;. The delay could be days or even years.&lt;/p&gt;

&lt;p&gt;For instance, in a scenario where you need to perform an API migration (due to a framework update, for example). Do you consider the consequences of allowing both the old and new APIs at the same time? It could be a heavy load, or duplicated data. If that's not possible, &lt;strong&gt;you must plan for when the older app loses access to the deprecated API&lt;/strong&gt;. Will your HTTP server return a &lt;code&gt;404 Not Found&lt;/code&gt;? How will the older app versions handle that response? Will they crash, or will they retry? Or will you return a &lt;code&gt;200 OK&lt;/code&gt; with an empty body? Is the client built to handle a successful response that contains no data?&lt;/p&gt;

&lt;p&gt;So yes, migrating a service on a mobile app is a lot more complicated than on your own website. One classic way is to follow the version standard for rest apis, by adding &lt;code&gt;/v1&lt;/code&gt; or &lt;code&gt;/v2&lt;/code&gt; and such. Remember to adjust different versions of the app to use different endpoints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Another way is to check the app version, and redirect it to the proper url. Or to deny the usage of the older api by returning an error message&lt;/strong&gt;. The former is a more friendly approach, but it may lead to a complex scenario of spaghetti api endpoints. The latter is a more forced approach, and it may not resonate well with your public. Especially if the app has a large audience who expects to be able to access the app at any time. It is a matter of choosing the most adequate answer to your problem.&lt;/p&gt;

&lt;h1&gt;
  
  
  2) Always authenticate an api call
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpgcs36ag20lu70u40fnc.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpgcs36ag20lu70u40fnc.gif" alt=" " width="275" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's say you are developing a stock broker website. You have to present information, and some of it will be specific for a user, and some will be public. For example, the history of operations by that user will be specific, while the real time value of the stock price will be open to everyone.&lt;/p&gt;

&lt;p&gt;In this scenario, the architect may authenticate specific calls, leaving public calls unauthenticated. It is a sensible approach, as it helps avoid unnecessary overhead.&lt;/p&gt;

&lt;p&gt;But when developing for a mobile application, this scenario changes. First of all, you no longer have a connection of 1 to 1, frontend to backend, instead now you have a connection of N to 1. &lt;strong&gt;When you create a service to enable hundred of thousands of simultaneous accesses, you could be vulnerable to a Denial of Service (DoS) attack&lt;/strong&gt;. All it takes is to forget to authenticate the requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before processing any request from a mobile app, you must identify and authorize it&lt;/strong&gt;. It could be through an authentication token, an API key, or a client-side SSL certificate. &lt;em&gt;And that rule applies even for open endpoints, like the one about stock prices&lt;/em&gt;, after all, you don't want to face avoidable downtime in your service.&lt;/p&gt;

&lt;p&gt;You should also consider measures like rate limiting to prevent spam, often done via a reverse proxy. If you don't, you might get some &lt;em&gt;leeches&lt;/em&gt; using your website service in their own website. Using a load balancer to distribute traffic across your servers is another suggestion.&lt;/p&gt;

&lt;h1&gt;
  
  
  3) Don't expect an api request to represent real time action
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91pj95jkkt0xy7fqai9b.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91pj95jkkt0xy7fqai9b.gif" alt=" " width="374" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When responding to a request from a browser, you may assume the time the request arrived is a decent approximation of the time the request was made. Of course, it makes sense after all. When a user navigates take actions on the website, it will send requests to the service.&lt;/p&gt;

&lt;p&gt;With mobile apps, this assumption is often false. A user might perform an action while offline (e.g., in airplane mode or outside roaming coverage). &lt;em&gt;The app may store that action in the device and sync it with your server once connectivity returns&lt;/em&gt;, hours or days later. As such, the server's request timestamp does not reliably represent the instant when the action occurred.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If recording the event time is crucial, the mobile client should timestamp the action when it happens and include that timestamp in the data&lt;/em&gt;. The service must be ready to accept it.&lt;/p&gt;

&lt;h1&gt;
  
  
  4) Make sure you add product and OS information to your calls
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0d0e0psksws96q2763ep.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0d0e0psksws96q2763ep.gif" alt=" " width="240" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine the following scenario. You go to work at morning, and your first ticket to check out is about an user not being able to save or update a record. While checking the backlogs for the service, you see this problem seems to repeat, but only with this user. So, what is the first suspect in this erratic behavior scenario that affects only one user? The browser type and version, of course.&lt;/p&gt;

&lt;p&gt;If the client's browser type and version does not explain the issue, the search expands. Other factors, like the OS version, network routing, or authentication may be why.&lt;/p&gt;

&lt;p&gt;The same line of thought applies to a service providing an endpoint for a mobile app. &lt;em&gt;Whenever a mobile client makes a request, it is very important to provide its OS version and manufacturer&lt;/em&gt;. Those details may be crucial to debug the issue at hand. Some issues only do happen on a specific version of OS or vendor. Send the information in the request header or body, depending on your strategy. Ensure your service logs this information for a reasonable time, especially alongside any errors. &lt;strong&gt;So the more you know about the error when it happens the first time, the easier will be when debugging it&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Considerations
&lt;/h1&gt;

&lt;p&gt;Creating a backend service for a mobile app is no different from any other service. Yet, &lt;em&gt;the mobile app is a consumer whose update cycle and environment are outside your control&lt;/em&gt;. Because of those restrictions, make sure to create a proper plan for updates and changes. &lt;em&gt;Knowing the particularities of Android and iOS will help you when building and maintaing a reliable service for them&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Doing so should not be a daunting task, as the modern state of both Android and iOS are particularly similar. Given how hybrid technologies are popular today, most solutions will work for both. Still, having a background in native development, knowing each OS details will help you to design your service. Especially if you need to ramp up security and performance. &lt;em&gt;And if you enjoyed this article, follow me on my website and social media pages for more articles&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Cover image by Freepik - &lt;a href="http://www.freepik.com" rel="noopener noreferrer"&gt;www.freepik.com&lt;/a&gt;&lt;br&gt;
Animated GIFs by GIPHY - &lt;a href="http://www.https://giphy.com/" rel="noopener noreferrer"&gt;www.https://giphy.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>backend</category>
      <category>mobile</category>
      <category>android</category>
      <category>webdev</category>
    </item>
    <item>
      <title>News from Google I/O '25 for Android devs</title>
      <dc:creator>Marco Coelho</dc:creator>
      <pubDate>Wed, 09 Jul 2025 23:24:56 +0000</pubDate>
      <link>https://dev.to/marcotcdev/news-from-google-io-25-for-android-devs-5a6p</link>
      <guid>https://dev.to/marcotcdev/news-from-google-io-25-for-android-devs-5a6p</guid>
      <description>&lt;h1&gt;
  
  
  Google I/O '25: My personal take on the announcement regarding the Android ecosystem for this year and the next
&lt;/h1&gt;

&lt;p&gt;Well, another Google I/O has come and gone, and the Android track for 2025 certainly didn't skimp on announcements. I've watched the presentations (most of them), scribbled down the highlights (and a few lowlights), and now it's time to distill what this means for us developers and the ecosystem at large, while presenting some compliments and criticism I believe to be valid and appropriate. So, grab a coffee, and let's dive in the news!&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 1: Android 16 - The middle eastern dessert (Very tasty, actually)
&lt;/h2&gt;

&lt;p&gt;Android 16 is the most antecipated announcement, and this year, it made an early appearance. &lt;em&gt;Google’s team even color-coded the changes by importance, so we may know where to focus first&lt;/em&gt;, and where to focus later on (red, yellow, green – a bit like a traffic light for our development priorities).&lt;/p&gt;

&lt;p&gt;Kicking things off, &lt;strong&gt;Jetpack Compose&lt;/strong&gt; continues to be the solid library all modern Android UI development is now based on. We're getting new modifiers (Autofill text, Autosize text, Animate bounds, and fancier Visibility trackers), &lt;em&gt;alongside welcome performance boosts and a rather impressive 32% reduction in experimental APIs, with increased stability&lt;/em&gt;. The way I see, that's a win. &lt;strong&gt;Navigation 3&lt;/strong&gt; is also on the horizon, rebuilt with Compose in mind, promising slicker transitions and customization, which is, of course, very welcome to have. But the bigger surprise to me was a Jetpack Compose based &lt;strong&gt;Media 3 and CameraX&lt;/strong&gt; new libraries, &lt;em&gt;a sort of overhaul of the already present libraries, and also very welcomed to have available&lt;/em&gt;. It seems good winds are blowing Compose further into the future.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kotlin Multiplatform (KMP)&lt;/strong&gt; enthusiasts, fans, skeptics and community alike, rejoice! Full Jetpack support for Tier 1 platforms (Android, iOS, JVM) is now available. This is genuinely good news, and shows KMP also has a promising future in the highly competitive market of hybrid mobile development.&lt;/p&gt;

&lt;p&gt;Regarding security and privacy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Digital Credentials Verification&lt;/strong&gt; and restoration via new API calls look promising. Frankly, anything that makes the apps safer is welcomed, no questions asked.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Privacy Sandbox&lt;/strong&gt; now lets you isolate any third-party code in its own runtime process, not just ad SDKs. That's a neat trick for containing rogue code, although checking the reputation of a library before using it is also important.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Android Advanced Protection Mode&lt;/strong&gt; is another new user-toggleable feature users can set, and that we'll need to integrate with in our apps before they will be able to use it – It means more coding, debugging and testing for us, but hopefully more peace of mind for users.&lt;/li&gt;
&lt;li&gt;And the one I'm particularly glad to see: &lt;strong&gt;Theft Protection with Identity Check&lt;/strong&gt;! An extra biometric layer to deter those snatch-and-run phone thieves? Excellent! We can't have enough of those, folks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Health Connect&lt;/strong&gt; is expanding, aiming to consolidate more health data for better medical context – think vaccines, allergies, alongside the usual sleep and movement. A positive change, I believe.&lt;/p&gt;

&lt;p&gt;On the performance front, the perennial battery vampire, &lt;em&gt;wake locks&lt;/em&gt;, are still an issue, often due to long-running jobs. Google is tweaking &lt;em&gt;Expedited Work in WorkManager&lt;/em&gt; to try and tame this beast. Yet, it remains to be seen how effective that will be when applied.&lt;/p&gt;

&lt;p&gt;And then there’s the big push: &lt;strong&gt;Adaptive Apps&lt;/strong&gt; -&amp;gt; Android is doubling down on making apps look good everywhere. For larger screens, Android 16 will apparently start ignoring your carefully set orientation and resizability restrictions on activity recreation. &lt;em&gt;While reorienting and resizing is something that should always be considered on our checklist, I fear developers will resist adopting this library and adding proper adaptative code.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Material 3 Expressive&lt;/strong&gt; is also part of this, an "expansion pack" (as I see it) for Material 3, bringing 15 new/improved components with unexpected shapes, new physics, and colors. It sounds fun, but let's hope it doesn't carry any serious letdowns.&lt;/p&gt;

&lt;p&gt;Other notable mentions for Android 16:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live Updates&lt;/strong&gt;: A new notification template for time-sensitive tasks like food deliveries, or map update for navigation. It is a notification in the notification tray changing content every few seconds. Very useful in some contexts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jetpack Glance 1.2 Alpha&lt;/strong&gt;: A widget building API based on Jetpack Compose. Again, it's only fair for this to be available, since Compose is being standardized as the recommended way to develop UI on Android.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Low Light Boost&lt;/strong&gt;: A software library using ML for better snaps in the dark. Nice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preload Manager for Media 3&lt;/strong&gt; and &lt;strong&gt;Native PCM Audio Offload&lt;/strong&gt;: More tools for media-heavy apps, allowing performance improvements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemini Nano Integration&lt;/strong&gt;: Via a new GenAI API and Gemini Live APIs (text/audio I/O), now Android apps may make use of an on-device generative AI capabilities. As a developer who is very interesting in connecting people and integrating software, I find this feature very promising and very interesting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;My Sentiment on the changes for Android 16&lt;/strong&gt;: Look, performance and usability optimizations in Jetpack and other libraries are always welcome, no questions about it. &lt;em&gt;The anti-theft layer is something that warms my heart, knowing someone took their time to code something to help you in your moment of vulnerability, just after a theft. Even if you don't recover your device, it will likely still protect you by giving you more time to take measures&lt;/em&gt;. The way I see it, it's a massive win.&lt;/p&gt;

&lt;p&gt;More KMP and Compose-centric libraries like Glance, Media 3, and CameraX are also desirable, and to be expected. I also agree the way Android manages screen reconfiguration is outdated, unnecessarily complicated, and sometimes, a letdown to developers. &lt;em&gt;However, I find it too convenient for Google to push an update for multiple form factors on Android while at the same time, announcing the release of Android XR.&lt;/em&gt; This push for adaptive screens across multiple form factors... It is good on paper, but it seems people forget it will come at a cost for companies. And I can't help but think someone might be trying to strong-arm the Android community into supporting the fledgling Android XR... Adapting your app for yet another device category costs real money, and not every app needs to be on every screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 2: Polishing the Shelves of Google Play
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Google Play Console&lt;/strong&gt; also got a fresh coat of paint and some new tools under the hood. The &lt;em&gt;app dashboard has been redesigned&lt;/em&gt; to surface key metrics like "Test and release" and "Monitor and improve" more prominently. Each core object now gets an overview page, which should simplify navigation.&lt;/p&gt;

&lt;p&gt;To tackle the challenge of multi-platform optimization, the console will now &lt;em&gt;flag incorrect edge-to-edge rendering&lt;/em&gt; in a pre-review check. A new panel for &lt;em&gt;quality issues and recommended fixes&lt;/em&gt; has also been added, alongside an &lt;em&gt;Android Vitals metric for low memory app closures&lt;/em&gt; and excessive battery drain. As long as the UI and UX design can keep up with the amount of data the console provides, those changes should be helpful, I believe.&lt;/p&gt;

&lt;p&gt;Store listings get more customizable, and a &lt;em&gt;new panel for engagement metrics&lt;/em&gt; (installs, ongoing engagement) has arrived. Monetization sees &lt;em&gt;more currencies and payment methods&lt;/em&gt;, with an AI model suggesting the most appropriate one. Good.&lt;/p&gt;

&lt;p&gt;On the security front, the &lt;strong&gt;Play Integrity API&lt;/strong&gt; gets enhancements for hardware-based security to reduce spoofing and a &lt;em&gt;new abuse detection feature for apps in trial mode&lt;/em&gt; that doesn't rely on device IDs, which is a privacy-conscious move. Again, I may be biased, but anything related to security is a win in my book, so kudos to them.&lt;/p&gt;

&lt;p&gt;Google says it's integrating the user end-to-end experience with developer tools to convert engagement into revenue. We'll see how that pans out.&lt;br&gt;
Discovery gets a boost with topic browser pages (for movies, books, games, etc.) and a "&lt;strong&gt;Where to watch&lt;/strong&gt;" feature. Those sound helpful, but I have to use it first to know where I stand regarding it. Audio samples are now available on app store pages, starting with health and wellness apps – an interesting idea.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Engage SDK&lt;/strong&gt; is expanding significantly with "Collections" – a full-screen immersive surface to pull content onto users' home screens, continue journeys across devices, create cluster recommendations, and promote specific clusters. Engage SDK content is also coming to the Play Store itself and now supports travel content and reservations. This "Collections" feature actually sounds quite promising for driving deeper engagement, and I'm warm to the prospect of using "Collections" in the future.&lt;/p&gt;

&lt;p&gt;Subscription management gets some love too: Single checkout for multiple subscriptions, more visibility for subscription benefits (to fight voluntary churn), and &lt;em&gt;more flexibility for grace periods on payment failures&lt;/em&gt; (to combat involuntary churn). The last one particularly stood out for me, especially given sometimes I have to cancel my virtual credit card when info leaks out, so it's nice to have a grace period.&lt;/p&gt;

&lt;p&gt;For the game devs, &lt;strong&gt;Google Play Games&lt;/strong&gt; is focusing more on engaging players on Mobile (a shift from PC), an &lt;strong&gt;Earnback program&lt;/strong&gt; to help &lt;em&gt;migrate PC games to Android&lt;/em&gt;, the &lt;strong&gt;Recall API&lt;/strong&gt; for cross-platform retention, and bulk achievement creation via CSV. Frankly, I barely play any mobile games, so I don't have much to comment here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My Sentiment on Google Play&lt;/strong&gt;: The changes are welcome, but many feel like minor tune-ups rather than any major overhaul. Still, I'm lukewarm towards them. My biggest gripe remains: I feel there’s a &lt;em&gt;lack of serious effort to curb malicious apps&lt;/em&gt;. This leads me to hesitate and suspect others when downloading apps from lesser-known developers who haven't shelled out for major marketing. I wish there were an easy way to tell malicious developers apart from genuine ones. Hopefully, AI could help with that, but so far, I've seen no announcement on that topic on Google Play. However, the Engage SDK "&lt;strong&gt;Collections&lt;/strong&gt;" feature does seem genuinely interesting and promising, while the rest seems to be mostly quality-of-life improvements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 3: Android Studio - Narwhal and the Gemini Effect
&lt;/h2&gt;

&lt;p&gt;Android Studio codename "Narwhal" will be getting significant AI adoption, largely thanks to some Gemini powered new features.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A new &lt;strong&gt;KMP template&lt;/strong&gt; is available, along with Compose preview, menu, and action enhancements. Good.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemini is embedding itself deeper into the IDE&lt;/strong&gt;: It can help update all project libraries (proposing solutions before touching code), analyze files to create Composable previews, and now it has agent-like capabilities to identify bugs, correct them, and rerun tests. A very promising update.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the headline act for me is &lt;strong&gt;Android Journey&lt;/strong&gt;, the &lt;em&gt;apparent successor to Android Espresso&lt;/em&gt;. The idea of instructing Gemini to test an Android app using natural language commands, rather than wrestling with Espresso's lists, intents, and the dreaded IdlingResources functionality, is a massive improvement. Plus, purging IdlingResource test code from release builds has always been a necessity when using Espresso, a necessity that will become outdated soon. &lt;strong&gt;Journey&lt;/strong&gt; could solve a lot of headaches for exploratory, integration system and regression testing.&lt;/p&gt;

&lt;p&gt;Yes, there are potential pitfalls with AI-driven testing, but I believe the benefits here could genuinely outweigh the risks.&lt;/p&gt;

&lt;p&gt;Other notable Studio upgrades:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Firebase device streaming&lt;/strong&gt;: Test on remote devices via device partner labs. Very welcomed in this age of remote work, for sure!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ADB Wi-Fi&lt;/strong&gt; improvements. A nice quality of life improvement, since I've already lost some cables when working with debug apps in Android, hopefully this change will save me some money.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;new backup feature&lt;/strong&gt; in Android 16 for app settings and data (presumably with Studio integration). Good.&lt;/li&gt;
&lt;li&gt;Studio will &lt;strong&gt;now recommend .ktx syntax&lt;/strong&gt; over plain .kt. Another minor change.&lt;/li&gt;
&lt;li&gt;Official support for &lt;strong&gt;Android XR devices&lt;/strong&gt;. Good.&lt;/li&gt;
&lt;li&gt;And a heads-up: &lt;strong&gt;16KB page size validation&lt;/strong&gt; is coming, up from 4KB. Time to check those native libraries. I won't complain about it, in the age of gigabytes of RAM in computers, I believe we are way past the point of needing only 4KB or 8KB memory pages for any partition type or memory context. Still, I think we could have adopted larger memory pages, who knows?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;My Sentiment on Android Studio&lt;/strong&gt;: I’m actually quite excited about the upcoming changes in Android Studio Narwhal. &lt;em&gt;Journey replacing Espresso is a potential game-changer&lt;/em&gt;, further allowing Jetpack Compose to assume the role of leading UI designing tool in Android, and helping in the rough edges of many different kinds of testing, especially regression test. The &lt;em&gt;Gemini integration for library updates and bug squashing&lt;/em&gt; is also welcomed. Features like 16KB page support and better ADB over Wi-Fi are nice to have, but I see them more as quality of life updates than the real deal for the event.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 4: The All-Encompassing Adaptive Android
&lt;/h2&gt;

&lt;p&gt;The push for "&lt;strong&gt;Adaptive Android&lt;/strong&gt;" was a recurring theme, with Google heavily promoting support for various form factors: &lt;em&gt;Phone, Tablet, Foldable, Wearable, Automotive&lt;/em&gt;, and the newest product (not so new, actually), &lt;strong&gt;Android XR&lt;/strong&gt;. I believe the dream behind it is that many apps could work seamlessly across different product environments, while retaining the same UI and UX when used, without a huge effort to rewrite those apps. But, in my opinion, there were also another message, an underlying message: &lt;em&gt;If your app isn't adaptive, you might be left out of the whole Android userbase, so you better use it&lt;/em&gt;. I think this kind of approach is counterproductive - an approach where a Jetpack Compose library helps the developers to adapt faster, easier and with a minimum cost to their companies, would be much more productive. Let's hope this is the road we are on.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Navigation 3&lt;/strong&gt; library will allow metadata tags for different navigation styles (like list vs. panel) to help with this. We're also getting new animations for app reconfiguration: &lt;strong&gt;Levitation&lt;/strong&gt; (moves a panel from landscape side to portrait center) and &lt;strong&gt;Reflow&lt;/strong&gt; (moves it to the top/bottom in portrait). For Android XR, there are new &lt;em&gt;Android XR exclusive components&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;As mentioned earlier, &lt;strong&gt;Android 16&lt;/strong&gt; will &lt;em&gt;start ignoring orientation, aspect ratio, and resizability restrictions on larger screens&lt;/em&gt; (defined as 360dp width or more). Instead of the developer, the user will have total control of the app on larger screens. Hence, it is understandable why &lt;em&gt;Google is advocating for a single, adaptive app for all these form factors, built with Compose and their tooling&lt;/em&gt;. And this adaptive approach extends to games too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My Sentiment on Adaptive Android&lt;/strong&gt;: While the ambition is clear, and Android was long overdue for an update regarding screen reconfiguration, this heavy emphasis on adaptiveness for larger screen, &lt;em&gt;again feels like a strong-arming Android towards bolstering the app ecosystem for Android XR, even before it is launched&lt;/em&gt;. I get the strategy – Android is growing on larger screens, like televisions, totems, monitors, automotive, so a form factor app library becomes necessary for this constantly evolving platform. But the reality for many developers is, &lt;em&gt;they hardly have the time or budget to work on form factors, much less to adapt Android to a supporting platform, especially if it’s not a natural fit for their app&lt;/em&gt;. I fear the community and the Android Google team might be on different pages.&lt;/p&gt;

&lt;p&gt;Perhaps for games, this one-app-fits-all approach will work wonders, but I suspect many specific apps may not translate well to XR. And I believe Android XR, much like Wear OS, will carve out its own small but dedicated niche, but nothing too far from that.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Regarding using Android XR for something like a translation tool, it may be interesting, but the thought of strapping a $1000+ gadget to my face, ripe for a quick slap-and-grab mugging, still gives me pause&lt;/em&gt;. I'm willing to consider using it, and Android XR may be an interesting product, no doubt, but perhaps not the revolutionary leap the presentation painted it as.&lt;/p&gt;

&lt;p&gt;That said, the smaller changes aimed at improving Android's behavior across different screen sizes, like the navigation and animation enhancements, are definitely welcome.&lt;/p&gt;




&lt;p&gt;So, that's my 2 cents regarding Google I/O '25 track about Android -&amp;gt; A lot of AI, a big push for adaptive everything (especially Android XR, it seems), new libraries and updates, and some genuinely useful improvements sprinkled throughout. Some of it is exciting, some of it feels a bit pushed, and the real test will be when these tools and APIs land in our hands.&lt;/p&gt;

&lt;p&gt;I recommend that you take action: &lt;em&gt;Download the newest Android Studio Narwhal, start testing your product with Journey and Gemini&lt;/em&gt;. Take some time to consider adapting your app with form factors (consider the time and budget necessary to do so), and &lt;em&gt;don't forget to replace any workaround with a proper, Jetpack Compose based library. Even if it's in alpha development, I think it will be worth it&lt;/em&gt;. Time to update those build.gradle files, I suppose!&lt;/p&gt;

&lt;p&gt;Cover image by Freepik - &lt;a href="http://www.freepik.com" rel="noopener noreferrer"&gt;www.freepik.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>news</category>
      <category>gemini</category>
      <category>google</category>
    </item>
    <item>
      <title>8 important security changes from Android 8 to Android 15</title>
      <dc:creator>Marco Coelho</dc:creator>
      <pubDate>Fri, 16 May 2025 21:59:47 +0000</pubDate>
      <link>https://dev.to/marcotcdev/8-important-security-changes-from-android-8-to-android-15-3l8f</link>
      <guid>https://dev.to/marcotcdev/8-important-security-changes-from-android-8-to-android-15-3l8f</guid>
      <description>&lt;p&gt;Yesterday, when I was at the bakery buying some snacks, I overheard a conversation between one attendant with another regarding her Android phone not downloading and installing the ChatGPT Android app. Curious about the subject, I decided to ask her more regarding her issue, and to talk about it. She explained her smartphone was an older model, using Android 8.0, aka Oreo, and that's probably why the chatgpt android app wasn't downloading and installing on it.&lt;/p&gt;

&lt;p&gt;We talked a while, and I pondered that while there are a lot of reasons for an app not to work on an older Android OS version, the most relevant of them are the security reasons. So I decided to list eight changes from Android 8.0 (Oreo) to Android 15 (Vanilla Ice Cream), the most impactful and relevant of each major version:&lt;/p&gt;

&lt;h2&gt;
  
  
  1 - Project Treble on Android 8.0
&lt;/h2&gt;

&lt;p&gt;Project Treble was, undoubtedly, the biggest change to architecture and security starting with &lt;strong&gt;Android 8.0&lt;/strong&gt;, from the previous Nougat (&lt;strong&gt;Android 7.0&lt;/strong&gt;). Not only did it compartmentalize the Android system image into a vendor partition and a system partition, it also increased the security and allowed for faster updates to be released and possibly longer device lifespan.&lt;/p&gt;

&lt;p&gt;To understand the advance of the &lt;strong&gt;Project Treble&lt;/strong&gt;, first you need to understand the basics of Android product development. In a very abridged form, the Android operating system is maintained and developed by the &lt;strong&gt;Open Handset Alliance&lt;/strong&gt;, a consortium of different companies, but most of the code for next version of the &lt;strong&gt;AOSP&lt;/strong&gt; (Android Open Source Project) is maintained and developed by a team at &lt;strong&gt;Google&lt;/strong&gt;. This version of the OS usually does not contain a kernel and system drivers, something which is added later by the device manufacturers like &lt;em&gt;Samsung, Motorola&lt;/em&gt;. The vendors usually retrieve and adapt the latest version of the &lt;strong&gt;Linux kernel&lt;/strong&gt;, and the system drivers from the chipset manufacturer, like &lt;em&gt;Qualcomm or MediaTek&lt;/em&gt; when not produced in-house. Only then, after it's developed and tested, the product goes to the resellers, who are too many to cite here. Think of it as an assembly line, where each step is done by a different company.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Project Treble changed some of that by separating the Android Framework software layer usually maintained by the AOSP team, which was named system partition, from the low level software layer maintained by the device manufacturer, which was named vendor partition. So now the assembly line has two distinct steps in regards to software instead of just one.&lt;/em&gt; To be honest, there are more than two partitions in an Android Device, but that's the general idea behind it. &lt;em&gt;Not only did it allow for the AOSP to update an older device Android operating system as long as the interface remains the same, it made access to system sensitive resources like the camera and microphone (something we don't want malicious apps to have access to) much harder to happen. This allows security patches to be deployed much faster than before when bugs are found.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There were other improvements made to Android 8.0, like the &lt;strong&gt;Webview component running on an isolated process&lt;/strong&gt;, making the device more secure against attacks via web, a &lt;strong&gt;serial hardware number&lt;/strong&gt; access requiring a specific permission to be granted, and better &lt;strong&gt;boot security&lt;/strong&gt;, but the biggest and most important change remains the Treble.&lt;/p&gt;

&lt;p&gt;If you would like to know more about the Project Treble, check out this article: &lt;a href="https://threatpost.com/whats-new-in-android-8-0-oreo-security/128061/" rel="noopener noreferrer"&gt;What's new in Android 8.0 Oreo Security&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2 - Biometric API on Android 9
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Android 9&lt;/strong&gt; Pie really started to tighten the screws on app permissions and how apps talk to the internet. For instance, it made &lt;strong&gt;secure connections&lt;/strong&gt; (HTTPS) the default for apps, which is like ensuring all your mail is sent in a sealed, tamper-proof envelope instead of an open postcard. It also put stricter limits on what apps could do in the background, especially with things like your &lt;strong&gt;microphone and camera&lt;/strong&gt;, stopping them from snooping when you're not looking.&lt;/p&gt;

&lt;p&gt;But for me, &lt;em&gt;the most important change in Android 9 was the Biometric API. Before this, every app had to build its own way to use your fingerprint, which wasn't always secure or consistent. With this API, Android provided a standard, super-secure way for apps to ask for your fingerprint or face scan.&lt;/em&gt; It's like having one master locksmith design a universal, highly secure keyhole that all trusted apps can use, instead of relying on a bunch of different, potentially flimsy locks. Relying on the Android OS also made biometric data interception by other apps less likely.&lt;/p&gt;

&lt;p&gt;If you would like to know more about the Biometric Prompt, check out Android 9 release notes: &lt;a href="https://source.android.com/docs/whatsnew/p-release-notes" rel="noopener noreferrer"&gt;Android 9 release notes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3 - Scoped Storage on Android 10
&lt;/h2&gt;

&lt;p&gt;Starting with &lt;strong&gt;Android 10&lt;/strong&gt;, privacy and security were taken to a whole new level, almost like building higher walls around your digital castle. It gave us much finer control over location access, letting you decide if an app gets your location only when you're using it. It also clamped down on apps &lt;strong&gt;launching activities from the background&lt;/strong&gt;, which helped stop those annoying pop-up ads or worse. On the technical side, it boosted security with things like &lt;strong&gt;TLS 1.3&lt;/strong&gt; support and randomizing &lt;strong&gt;MAC addresses&lt;/strong&gt; to prevent tracking.&lt;/p&gt;

&lt;p&gt;However, in my opinion, &lt;em&gt;the standout security feature in Android 10 was Scoped Storage. Think of your phone's storage as a big house. Before Scoped Storage, when giving another app permission to access your app files, the permissions were given to pretty much all files, for all the time, until rescinded. This was like giving them free access to your entire house when you only wanted to show them the kitchen.&lt;/em&gt; Scoped Storage gave each app its own private, locked room for its files by default. If an app wants to access a file, it has to ask for specific permission, and the permission is given for a specific action, for a specific file, for a specified timespan, making it much harder for a previously trusted app to go rogue and steal your data, &lt;em&gt;something that was far too common at the time.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4 - Permission auto reset on Android 11
&lt;/h2&gt;

&lt;p&gt;With &lt;strong&gt;Android 11&lt;/strong&gt;, the focus was on giving users even more direct control and making permissions smarter. It introduced &lt;strong&gt;one-time permissions&lt;/strong&gt;, which is like giving an app a key that only works once – super handy for apps you don't fully trust but need to use briefly. It also gained a &lt;strong&gt;better security for SIM Identifiers&lt;/strong&gt;, and encryption for &lt;strong&gt;user-stored credentials&lt;/strong&gt;. Also, &lt;strong&gt;Scoped Storage&lt;/strong&gt; previously introduced on Android 10 is now enforced on all apps.&lt;/p&gt;

&lt;p&gt;But the real game-changer for me here was &lt;em&gt;the auto-reset permissions feature. If you install an app, grant it a bunch of permissions, and then forget about it for a few months, Android 11 steps in, like a helpful assistant, to automatically revoke those permissions from the dormant app.&lt;/em&gt; It’s like that assistant noticing you haven't had a particular guest (app) over in a while, so they proactively take back the spare key you gave them, just in case. &lt;em&gt;This is a brilliant way to reduce the attack surface from old, forgotten apps, which again could sometimes hold &lt;strong&gt;malicious code to be executed&lt;/strong&gt; only after days, weeks or months&lt;/em&gt; after being installed into a device and given permission for a legitimate use.&lt;/p&gt;

&lt;h2&gt;
  
  
  5 - Phantom touch blocking on Android 12
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Android 12&lt;/strong&gt; brought a big visual overhaul, but it also packed some serious security punches. The &lt;strong&gt;Privacy Dashboard&lt;/strong&gt; was a great addition, giving you a clear timeline of which apps accessed sensitive stuff like your camera, mic, or location. Those &lt;strong&gt;little green indicators&lt;/strong&gt; for camera/mic use? Genius. Like a little light that tells you someone's listening or watching. It also allows you to give apps seeking your location only your &lt;strong&gt;approximate location&lt;/strong&gt;, which is perfect for things like weather apps that don't need to know your exact address.&lt;/p&gt;

&lt;p&gt;But for me, &lt;em&gt;the most crucial security update in Android 12 was blocking untrusted touch events. Imagine a malicious app creating an invisible button over a real button in another app, trying to trick you into tapping something dangerous. Android 12 got much better at detecting and blocking these "tapjacking" attempts.&lt;/em&gt; It’s like having a filter for your screen that blocks &lt;strong&gt;shady attempts at tricking you&lt;/strong&gt; into opening an app, or allowing a permission.&lt;/p&gt;

&lt;p&gt;If you want to know more about the untrusted touch events block, check out the release notes for Android 12: &lt;a href="https://source.android.com/docs/whatsnew/android-12-release" rel="noopener noreferrer"&gt;Android 12 release notes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6 - Photo Picker addition on Android 13
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Android 13&lt;/strong&gt; continued to refine these privacy and security controls. A new kind of &lt;strong&gt;permission&lt;/strong&gt; was added to Android 13 - The &lt;strong&gt;app notification permission&lt;/strong&gt;. Apps now do have to explicitly ask for this permission to send any notifications, if not granted, the app will not be able to send notifications! This was meant to curb the excessive spam via notification some apps were doing. It also introduced more &lt;strong&gt;granular permissions for media files&lt;/strong&gt;, so an app wanting your photos doesn't also get access to your videos and audio files unless specified. The new unified &lt;strong&gt;Security &amp;amp; Privacy settings page&lt;/strong&gt; also made it easier to see what's going on.&lt;/p&gt;

&lt;p&gt;But, if I had to pick one, &lt;em&gt;the most significant security improvement for me in Android 13 was the Photo Picker. Previously, if an app wanted a photo, you often had to grant it access to your entire photo library. This could include sensitive, private and personal photos, and the user wouldn't know if those photos were accessed or not. Now, any app has to use the Photo Picker, which is like a secure messenger;&lt;/em&gt; you tell it which &lt;strong&gt;specific photos or videos&lt;/strong&gt; you want to share with an app, and only those items are made available, for that one time. The app never gets to rummage through your whole album, &lt;em&gt;keeping other photos and videos private.&lt;/em&gt; It’s a much safer way to share your memories and keep your privacy.&lt;/p&gt;

&lt;h2&gt;
  
  
  7 - Memory Tagging Extension on Android 14
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Android 14&lt;/strong&gt; built on this solid foundation, making several under-the-hood and user-facing security enhancements. It started nudging users towards &lt;strong&gt;6-digit PINs&lt;/strong&gt; for better lock screen security and gave IT admins more power, like &lt;strong&gt;disabling 2G connections&lt;/strong&gt; which can be a security risk. &lt;strong&gt;Disabling 2G connections&lt;/strong&gt; on your phone was possible since Android 12, but now, even remote administrators could do it. It also &lt;strong&gt;made it harder to install very old apps&lt;/strong&gt; that might be riddled with known, unpatched vulnerabilities.&lt;/p&gt;

&lt;p&gt;However, from my perspective, &lt;em&gt;the most important step forward in Android 14 was the improved real-time malware protection, especially enhancements related to Memory Tagging Extension (MTE) where the hardware supports it. Think of MTE as an incredibly sophisticated alarm system for your phone's memory. It "tags" different parts of memory, and if an app tries to access a part it shouldn't, or messes with memory in a way that's common for malware, the alarm goes off instantly, often stopping an attack before it can do any damage.&lt;/em&gt; This helps catch and neutralize &lt;strong&gt;a whole class of tricky memory-related bugs&lt;/strong&gt; and exploits in real-time, from stack injection to memory dumping.&lt;/p&gt;

&lt;h2&gt;
  
  
  8 - Anti-theft protection on Android 15
&lt;/h2&gt;

&lt;p&gt;Looking at &lt;strong&gt;Android 15&lt;/strong&gt;, it's clear they're doubling down on protecting you from more modern threats, especially physical theft. It's also bringing features like a "&lt;strong&gt;private space&lt;/strong&gt;" to hide sensitive apps and data, and further hardening the system by using more memory-safe languages like Rust. There are also improvements to how it handles &lt;strong&gt;one-time passwords&lt;/strong&gt; to prevent malicious apps from peeking at them.&lt;/p&gt;

&lt;p&gt;But undoubtedly, for anyone who ever had their phone stolen, &lt;em&gt;the most significant security feature in Android 15 is the advanced theft protection. This isn't just about remotely wiping your phone anymore, which was an important feature, but could be bypassed if the phone was stolen while unlocked. It's about considering the scenarios where there is suspicious behavior (like if a thief snatches your phone and tries to run) and minimizing the damage.&lt;/em&gt; If the anti-theft system thinks the phone is stolen, it can &lt;strong&gt;automatically lock it down&lt;/strong&gt;, make it harder to factory reset without your credentials, and even lock the screen if someone repeatedly fails to unlock it or tries to disable "Find My Device." It's like an intelligent alarm for your phone, where it activates a &lt;strong&gt;killswitch&lt;/strong&gt; of sorts, making the device much harder to compromise, requiring more time, technical expertise, &lt;em&gt;and making it less appealing and valuable to thieves.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you want to know more about the anti-theft, I recommend this article: &lt;a href="https://blog.cortado.com/en/android-security-for-businesses/" rel="noopener noreferrer"&gt;Android Security 2025: The Most Important Security Features for Businesses&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;While talking with both attendants, I tried to explain why, sometimes, an Android app will not run on an older device. I didn't get too technical, but I made my point - &lt;em&gt;Newer devices aren't simply a programmed obsolescence ploy to sell you something you already have again. Newer technologies like 5G and 6G aren't simply faster, they are also much more secure than 2G and 3G.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If I had to put it in simpler terms, I'd say we, users, are in the middle of an &lt;strong&gt;arms race&lt;/strong&gt; between &lt;strong&gt;tech companies&lt;/strong&gt;, and &lt;strong&gt;criminal entrepreneurs&lt;/strong&gt;, who are always innovating in new ways to commit crime, either by tricking you into installing a malicious app, or physically stealing your phone. Either way, we should take measures to avoid unnecessary risks, and buying a new phone from time to time can be considered one of them. Of course, you don't need to buy the latest phone model every single year, but waiting too much to buy a new one could compromise your digital security, as &lt;em&gt;the more time passes, the more vulnerabilities will be known by everyone, including attackers&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In my discussion with them, I tried to state that point. Also, &lt;em&gt;just buying a new phone is not enough if the user is not going to make use of proper security practices.&lt;/em&gt; Make sure you enable your anti-theft system on your phone, avoid downloading strange unknown apps if possible, and pay attention to any strange behavior on your device, for example, if it feels too hot to the touch, it may be running a malicious code in background without your knowledge. &lt;em&gt;Keep an eye out for risks, and you may avoid the worst of them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Cover image by Freepik - &lt;a href="http://www.freepik.com" rel="noopener noreferrer"&gt;www.freepik.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>cybersecurity</category>
      <category>security</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Seven Legacy Technologies in Android Development and Their Modern Counterparts</title>
      <dc:creator>Marco Coelho</dc:creator>
      <pubDate>Mon, 27 Jan 2025 13:01:47 +0000</pubDate>
      <link>https://dev.to/marcotcdev/seven-legacy-technologies-in-android-development-and-their-modern-counterparts-3hc8</link>
      <guid>https://dev.to/marcotcdev/seven-legacy-technologies-in-android-development-and-their-modern-counterparts-3hc8</guid>
      <description>&lt;p&gt;Android development has come a long way since its inception in 2008. The tools and the framework that developers relied on in the early days have evolved or been replaced entirely, leaving behind a trail of technologies with legacy status. Here, we'll dive into seven of these legacy technologies, explore their importance to android software development, appoint their legacy and modern counterparts, and discuss why the evolution was necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. From Java to Kotlin
&lt;/h3&gt;

&lt;p&gt;When Android launched, Java was the exclusive language choosen and designed for Android development. A lot of the reason was that Java had a developer community unlike other technologies, allowing Java to have a deeper penetration power into distinct and different markets.&lt;br&gt;
It also had to do with timing and opportunity, due to Apache annoucing the project &lt;strong&gt;Apache Harmony&lt;/strong&gt;, a open source free Java implementation back in year of 2005. One of the biggest reasons for that, was the concept of &lt;strong&gt;Sandbox&lt;/strong&gt; - &lt;em&gt;Each Android application (apk) would run in it's own instance of the JVM&lt;/em&gt;, hence making any possible unintentional crash less likely to affect other applications, or protecting the OS somewhat from malicious code. Hence, &lt;em&gt;Java is vital to the Android project&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Of course, if you wanted to design an audio driver or if you wanted to create a specific game, most of the time you had to code some low level code in C/C++, something named &lt;strong&gt;native layer&lt;/strong&gt; by the Android project. However, coding an Android apk with C/C++ came with it's layers of risks and restrictions, given it did not have the &lt;strong&gt;Sandbox&lt;/strong&gt; protection.&lt;/p&gt;

&lt;p&gt;It served its purpose well, but the language came with its baggage, notably the infamous &lt;em&gt;Null Pointer Exceptions (NPEs)&lt;/em&gt; that caused endless headaches for developers. Also, Java had it's own share of conflicts, primarily conflicts between Microsoft, Sun, Oracle and RedHat leading to the creation of &lt;strong&gt;openJDK&lt;/strong&gt; (an successor to Apache Harmony), and thus the main focus of the community wasn't Google and the Android project, despite Java being vital to Android.&lt;/p&gt;

&lt;p&gt;Enter Kotlin, originally unveiled in 2011, but officialy launched in February 2016, as an alternative to Java due to those issues. Kotlin addressed these issues with nullable types and offered a syntax that is concise and readable, significantly simplifying code. While some argue that modern Java (version 21, for example) narrows the gap with Kotlin, back in 2017, Kotlin was a breath of fresh air for developers needing a language more adequate for Android development. The transition from Java to Kotlin took some time to gain traction with Google officially suportting Kotlin only on 2017, and the &lt;em&gt;developer community largely embraced Kotlin since then, and as such, Kotlin has become the official language for Android apk development&lt;/em&gt;, despite both Java and C still being supported.&lt;/p&gt;

&lt;p&gt;Of course, the main reason Kotlin is able to run on the Android OS is because Kotlin source code is compiled into Java .class (and later .dex) files, hence Kotlin itself is also heavily dependent on the &lt;strong&gt;Java Virtual Machine&lt;/strong&gt;, something not likely to go away at any time in the future.&lt;/p&gt;
&lt;h4&gt;
  
  
  How to update:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Add the Kotlin plugin in your project if not added yet:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Groovy&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${version}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or in Kotlin DSL&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alias(libs.plugins.jetbrains.kotlin.android)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In Android Studio, press Code &amp;gt; Convert Java File to Kotlin&lt;/li&gt;
&lt;li&gt;You need to code check the conversion to make sure it's done properly. For that, reading the Kotlin official website docs will help: &lt;a href="https://kotlinlang.org/docs/home.html" rel="noopener noreferrer"&gt;https://kotlinlang.org/docs/home.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Jetpack Compose: Bye-Bye XML Layouts
&lt;/h3&gt;

&lt;p&gt;Jetpack Compose, first announced in 2019, but released in July 2021, revolutionized UI development in Android. Gone are the days of juggling XML files, the inflater class, and various resource files for layouts, animations, and themes. Gone were the days where an app could crash if the inflater couldn't find a XML reference during runtime, or you could end up with a weird colored dialog box due to using an incorrect app theme. &lt;em&gt;Compose consolidates all these elements into a declarative, Kotlin-exclusive framework, and makes sure that: 1) The code is coherent in compilation time, 2) it is always using the proper app theme&lt;/em&gt;, thus avoiding the runtime issues associated with missing classes, weird colors and improper reflection usage.&lt;/p&gt;

&lt;p&gt;One standout feature is the composable preview library, which provides a more accurate representation of UI components compared to the old XML layout preview. Despite being stable, Jetpack Compose is still evolving, and developers are encouraged to adopt it gradually because some features are still experimental, like the &lt;code&gt;Canvas&lt;/code&gt;, &lt;code&gt;LazyColumn&lt;/code&gt;, &lt;code&gt;LazyRow&lt;/code&gt; and &lt;code&gt;ConstraintLayout&lt;/code&gt;. As such, those features are still prone to change, and it's not uncommon to find on internet older projects using outdated Compose code for those features - Beware!&lt;/p&gt;

&lt;p&gt;Android studio default Jetpack Compose placeholder code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Text("Hello world!")
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Still, Jetpack Compose's flexibility allows teams to update their apps step by step, changing one screen at a time, or even mixing parts of XML and Compose by using reducing the risk of breaking existing functionality. This can be done either by inserting a Composable inside an XML layout by using an XML element named &lt;code&gt;ComposeView&lt;/code&gt; and calling &lt;code&gt;setContent&lt;/code&gt; on it in the Activity class Kotlin source code. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;androidx.compose.ui.platform.ComposeView
android:id="@+id/my_custom_composable"
android:layout_width="match_parent"
android:layout_height="match_parent" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;findViewById&amp;lt;ComposeView&amp;gt;(R.id.my_custom_composable).setContent {
    MaterialTheme {
        Surface {
          Text(text = "Custom composable!")
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or by calling an composable named &lt;code&gt;AndroidView&lt;/code&gt; in the Activity class Kotlin source code, and then inflating in runtime the necessary XML component tree by coding the &lt;code&gt;factory&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt; methods of &lt;code&gt;AndroidView&lt;/code&gt;. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AndroidView(
        modifier = Modifier.fillMaxSize(),
        // Occupy the max size in the Compose UI tree
        factory = { context -&amp;gt;
            // Create or inflate your view hierarchy here
            TODO()
        },
        update = { view -&amp;gt;
            // Called each time the composable is updated
            TODO()
        }
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  How to update:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;You may use ComposeView to insert a compose element inside an XML layout file tree hierarchy (As shown above).&lt;/li&gt;
&lt;li&gt;You may use AndroidView to insert an XML element and inflate it inside a Compose hierarchy (As shown above).&lt;/li&gt;
&lt;li&gt;Entire screens may be redesigned in Compose by studying how Jetpack Compose works. Since Compose uses Kotlin and Android inflater uses different languages, it will require studying Compose and how to build an equivalent screen using it.&lt;/li&gt;
&lt;li&gt;This official tutorial will show how to use Jetpack Compose: &lt;a href="https://developer.android.com/develop/ui/compose/tutorial" rel="noopener noreferrer"&gt;https://developer.android.com/develop/ui/compose/tutorial&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Google Material Design: Evolution to M3
&lt;/h3&gt;

&lt;p&gt;Material Design has been the cornerstone of Android’s visual language since its introduction. Currently in its third iteration, Material Design 3 (M3), released in October 2021, offers a refined subset of color values, text sizes, and typography, enabling developers to create distinctive visual identities for their apps. &lt;em&gt;The colors in Material Design are chosen to ensure they do not clash too strongly, making the app almost always visually pleasant and easy to read&lt;/em&gt;. The typography style is also designed to help apps adapt better to screens of any size, ensuring a consistent and polished look. If you want to quickly test or create a material theme, use the web builder for the theme: &lt;a href="https://material-foundation.github.io/material-theme-builder/" rel="noopener noreferrer"&gt;https://material-foundation.github.io/material-theme-builder/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Material Design came to replace older design styles for Android up to version 4.4 KitKat. &lt;em&gt;Until Lollipop, there was no official design style for Android apps&lt;/em&gt;, with the design used on apps varying from styles copied from web development, or styles similar to the earlier Macromedia Flash apps, or styles trying to copy iOS.&lt;/p&gt;

&lt;p&gt;Updating from M1 or M2 to M3 requires rethinking your app’s style, but the payoff is worth it. The latest version integrates seamlessly with Kotlin and Jetpack Compose, allowing developers to create pleasant apps with less effort than the previous versions. Also, the color scheme of Material 3 makes it far easier to support dark mode with very few changes necessaries to adapt the code.&lt;/p&gt;

&lt;h4&gt;
  
  
  How to update:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;There is no straightforward way to migrate from earlier version of Material library into Material 3, but you may use the official documentation for some help: &lt;a href="https://developer.android.com/develop/ui/compose/designsystems/material2-material3" rel="noopener noreferrer"&gt;https://developer.android.com/develop/ui/compose/designsystems/material2-material3&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;If you need the official reference for M3: &lt;a href="https://m3.material.io/" rel="noopener noreferrer"&gt;https://m3.material.io/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Dependency Injection: Dagger vs. Koin
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Dependency injection&lt;/strong&gt; (DI) has always been a crucial part of Android development. &lt;code&gt;dagger&lt;/code&gt;, while powerful, wasn’t particularly friendly to Kotlin developers. &lt;code&gt;hilt&lt;/code&gt; improved on &lt;code&gt;dagger&lt;/code&gt; but still retained some limitations, like requiring injection methods to be public.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Koin&lt;/strong&gt;, launched in November 2017, is a Kotlin-first DI framework that uses a domain-specific language (DSL) to make dependency management more intuitive. By embracing Koin, developers can better align with Kotlin’s object-oriented nature while simplifying DI. Also, the nature of Koin allows the developer to create distinct modules for testing scenarios, and productions scenarios, thus allowing the developer to also mock data under the right circusmtances.&lt;/p&gt;

&lt;h4&gt;
  
  
  How to update:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;In build.gradle file, application level (not project level) replace the import of any dagger library with Koin library. Example:
From
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies {
    implementation 'com.google.dagger:dagger:2.x'
    kapt 'com.google.dagger:dagger-compiler:2.x'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies {
    implementation("io.insert-koin:koin-core:$koin_version")
    implementation("io.insert-koin:koin-android:$koin_android_version")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Afterwards, you need to read and understand the documentation of Koin to create and inject Koin modules.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For more info: &lt;a href="https://insert-koin.io/" rel="noopener noreferrer"&gt;https://insert-koin.io/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. AsyncTasks to Coroutines and Flow
&lt;/h3&gt;

&lt;p&gt;Android has a golden rule when it comes to thread - The main thread, also called UI Thread, should not take more than 16 ms to run. Each method in the Android framework has this time constraint, and if you wish to run a longer, blocking operation like network communication, you should run it on a background thread. So why not run all the code, including UI updating code, on the background thread? Simple, Android also required for it's view objects to be updated only in the UI Thread, to prevent race conditions since the Android UI Toolkit is not Thread safe.&lt;/p&gt;

&lt;p&gt;When Android was created, all the parallelism done in the app had to be done using the &lt;em&gt;Java Thread&lt;/em&gt; mecanism. While powerful, Java Thread can cause a lot of damage if misused, and Threads were also quite resource expensive in the earlier days of Android developer. To fix this issue, the &lt;code&gt;Handler&lt;/code&gt; and &lt;code&gt;Looper&lt;/code&gt; mechanism was created in API Level 1.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Looper&lt;/code&gt; and &lt;code&gt;Handler&lt;/code&gt; worked like a pair, where the &lt;code&gt;Looper&lt;/code&gt; would create a infinite loop inside a newly started thread, while &lt;code&gt;Handler&lt;/code&gt; would be associated with this &lt;code&gt;Looper&lt;/code&gt; and thus would be able to receive &lt;code&gt;Runnable&lt;/code&gt; objects to run on the thread being managed by the looper. If you found that confusing, this was why the &lt;code&gt;AsyncTask&lt;/code&gt; was created later on the API Level 3, to make short parallel tasks easier to plan and execute. It was much simpler to create an &lt;code&gt;AsyncTask&lt;/code&gt; object, implement it's &lt;code&gt;onPreExecute&lt;/code&gt;, &lt;code&gt;onPostExecute&lt;/code&gt; and &lt;code&gt;doInBackground&lt;/code&gt; methods to guarantee only the blocking code would run on the background, while the other code would run on the UI Thread.&lt;/p&gt;

&lt;p&gt;So as it can be seen, managing parallelism back then meant wrestling with &lt;code&gt;AsyncTasks&lt;/code&gt;, &lt;code&gt;Looper&lt;/code&gt;, and &lt;code&gt;Handler&lt;/code&gt; classes—a process fraught with pitfalls like UI thread clogging, the dreaded "Application Not Responding" (ANR) dialog, or crashes if a piece code tried to update the screen from outside the main UI thread. When Google adopted Kotlin as the language for Android development, the door was open for Kotlin based Android apks to use Kotlin Coroutines and Kotlin Flow, which are a Kotlin exclusive paralellism technology, providing a streamlined way to handle long-running and short-lived operations.&lt;/p&gt;

&lt;p&gt;Kotlin Coroutines are a method of running parallel code without the need to design specific callback methods, like the AsyncTask used for &lt;code&gt;doInBackground&lt;/code&gt; and &lt;code&gt;onPostExecute&lt;/code&gt;. To create a coroutine, you use a scope as a source, add a job (Although this part may be skipped if you don't care about cancelling the coroutine), and then either launch it, or call it in a &lt;strong&gt;suspend&lt;/strong&gt; mode. The thread being used may be switched by using a suspend method call named &lt;code&gt;withContext&lt;/code&gt;, which returns only after switching the context (eg. The Thread) into the appropriate one. Hence, a code using a coroutine may look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val job = coroutineScope.launch(Dispatchers.Main) {
    // Execute setup code
    withContext(Dispatchers.IO) {
        // Execute the blocking code here
    }
    withContext(Dispatchers.Main) {
        // Execute post blocking code here
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Android Lifecycle Jetpack library added a bunch of new tools to the Kotlin Coroutines, like &lt;code&gt;lifecycleScope&lt;/code&gt; for activity classes and &lt;code&gt;viewModelScope&lt;/code&gt; for ViewModels classes, simplifying memory and resource management. AsyncTask was officially deprecated in Android 11 (September 2020), marking the end of an era.&lt;/p&gt;

&lt;h4&gt;
  
  
  How to update:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Most AsyncTask classes may be updated by the rough following procedure. Adjust as needed - 1) Create the coroutine as above, 2) Add the code from &lt;code&gt;onPreExecute&lt;/code&gt; into the setup part of the coroutine, 3) Add the &lt;code&gt;doInBackground&lt;/code&gt; code in the &lt;code&gt;Dispatchers.IO&lt;/code&gt; part of the coroutine and, 4) Add the &lt;code&gt;onPostExecute&lt;/code&gt; in the block &lt;code&gt;withContext(Dispatchers.Main)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;For reference, use the official documentation on the Kotlin website: &lt;a href="https://kotlinlang.org/docs/coroutines-overview.html" rel="noopener noreferrer"&gt;https://kotlinlang.org/docs/coroutines-overview.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. SQLiteDatabase vs. Jetpack Room
&lt;/h3&gt;

&lt;p&gt;SQLite Databases have long been a staple for data management in Android, enabling apps to store SQL information securely. However, for many use cases, they’ve been supplanted by Jetpack Room, introduced in May 2018. &lt;em&gt;Room simplifies database management with features like migration tools and query interfaces, offering an ORM-like experience similar to Hibernate.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To create a database in SQLite using SQLiteDatabase class, it was necessary to configure the params when opening the database (either read only, or read write), treat possible situations like a constraint violation, or a conflict when updating or inserting a data, and rollbacks. &lt;em&gt;Also, each transaction had to be carefully set up before commiting, just like any other SQL database.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Using &lt;strong&gt;Room&lt;/strong&gt;, a component of &lt;strong&gt;Android Jetpack&lt;/strong&gt;, made the SQL database management in Android far easier. &lt;em&gt;You can use an annotation to define the whole database in it's database class&lt;/em&gt;, by defining the entities, the version and even how to migrate the database from one version to another. Below is a piece of code from one of my projects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Database(
    entities = [CurrentWeatherCache::class, WeatherCache::class, HourlyWeatherCache::class, DailyWeatherCache::class],
    version = 4,
    autoMigrations = [
        AutoMigration(from = 1, to = 2),
        AutoMigration(from = 2, to = 3),
        AutoMigration(from = 3, to = 4)
    ]
)
abstract class WeatherPeekDatabase : RoomDatabase() {
    abstract fun getCurrentWeatherDao(): CurrentWeatherDao
    abstract fun getWeatherCacheDao(): WeatherCacheDao
    abstract fun getHourlyWeatherCacheDao(): HourlyWeatherCacheDao
    abstract fun getDailyWeatherCacheDao(): DailyWeatherCacheDao
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creating the select, insert, update and delete methods is even easier, just requiring the developer to create an interface with annotations on each method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Dao
interface WeatherCacheDao {

    @Query("SELECT * FROM WeatherCache ORDER BY id ASC")
    fun getAll(): LiveData&amp;lt;List&amp;lt;WeatherCache&amp;gt;&amp;gt;

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertAll(vararg weather: WeatherCache)

    @Query("DELETE FROM WeatherCache")
    suspend fun clear()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare that to the SQLiteDatabase method of reading from a SQL table from the official documentation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// you will actually use after this query.
val projection = arrayOf(BaseColumns._ID, FeedEntry.COLUMN_NAME_TITLE, FeedEntry.COLUMN_NAME_SUBTITLE)

// Filter results WHERE "title" = 'My Title'
val selection = "${FeedEntry.COLUMN_NAME_TITLE} = ?"
val selectionArgs = arrayOf("My Title")

// How you want the results sorted in the resulting Cursor
val sortOrder = "${FeedEntry.COLUMN_NAME_SUBTITLE} DESC"

val cursor = db.query(
        FeedEntry.TABLE_NAME,   // The table to query
        projection,             // The array of columns to return (pass null to get all)
        selection,              // The columns for the WHERE clause
        selectionArgs,          // The values for the WHERE clause
        null,                   // don't group the rows
        null,                   // don't filter by row groups
        sortOrder               // The sort order
)

val itemIds = mutableListOf&amp;lt;Long&amp;gt;()
with(cursor) {
    while (moveToNext()) {
        val itemId = getLong(getColumnIndexOrThrow(BaseColumns._ID))
        itemIds.add(itemId)
    }
}
cursor.close()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  How to update:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Updating from one to the other is straightforward. You need to create a proper schema, and then a database class, and at least one dao class - Some of the query may be imported in the case of the daos, but most of the code from the database will be deleted, since it's usually boilerplate.&lt;/li&gt;
&lt;li&gt;For reference, use the official documentation: &lt;a href="https://developer.android.com/training/data-storage/room" rel="noopener noreferrer"&gt;https://developer.android.com/training/data-storage/room&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7. Shared Preferences to DataStore
&lt;/h3&gt;

&lt;p&gt;In older Android development, when the developer wanted to save key-value pairs, they used to rely on &lt;strong&gt;Shared Preferences&lt;/strong&gt;, a Android class added on API Level 1, &lt;em&gt;which worked well back when Android didn't require thread intensive applications, or elaborate user interfaces&lt;/em&gt;. It worked synchronously, commiting simple key value pairs into a local "database", the &lt;em&gt;database&lt;/em&gt; being nothing more than a &lt;em&gt;local file without the typical database expectations and properties&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;However, using this Android Context framework component had it's risks in multithread environments, &lt;em&gt;including the possibility of race conditions, and UI Thread blocking&lt;/em&gt;. Hence Android Project introduced in 2020 two distinct implementations, one called &lt;strong&gt;Preferences DataStore&lt;/strong&gt;, and other called &lt;strong&gt;Proto DataStore&lt;/strong&gt; as a modern alternative, providing reliable and structured data storage in a multithread environment, along with UI safe execution. For the context of this article, I'm going to consider &lt;strong&gt;Preferences DataStore&lt;/strong&gt;, since this library is the most direct successor do &lt;strong&gt;SharedPreferences&lt;/strong&gt;. Besides those advantages, another big advantage of DataStore is being compatible with Kotlin Coroutines and Kotlin Flow.&lt;/p&gt;

&lt;p&gt;For example, to use &lt;strong&gt;SharedPreferences&lt;/strong&gt;, you simply had to create the database and call a get or put method on it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val sharedPref = activity?.getSharedPreferences(
        getString(R.string.preference_file_key), Context.MODE_PRIVATE)
with (sharedPref.edit()) {
    putInt(getString(R.string.saved_high_score_key), newHighScore)
    apply()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple, straightforward, but Thread unsafe. On the other hand, the modern equivalent is also easier to understand, but &lt;em&gt;behind the method calls, it already take cares of things like UI blocking and Thread safety&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// At the top level of your kotlin file:
val Context.dataStore: DataStore&amp;lt;Preferences&amp;gt; by preferencesDataStore(name = "settings")

val HIGH_SCORE = intPreferencesKey("high_score")

suspend fun incrementCounter() {
  context.dataStore.edit { settings -&amp;gt;
    settings[HIGH_SCORE] = newHighScore
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As seen above, &lt;strong&gt;DataStore&lt;/strong&gt; signals a shift toward a &lt;em&gt;Kotlin friendlier, thread safer, error signalling, exception safer solution, with data migration&lt;/em&gt;, addressing many of the shortcomings of &lt;strong&gt;Shared Preferences&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  How to update:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Updating &lt;strong&gt;SharedPreferences&lt;/strong&gt; to &lt;strong&gt;Preferences DataStore&lt;/strong&gt; is easy - First, add the library in the build.gradle app file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;implementation("androidx.datastore:datastore-preferences:${version}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to create only one instance of the DataStore for each file you are using. Afterwards, change each instance of &lt;code&gt;edit()&lt;/code&gt; to make sure it's using &lt;strong&gt;Preferences DataStore&lt;/strong&gt; &lt;code&gt;edit()&lt;/code&gt;version, and it's using it inside a suspend function, like above.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The hardest part will be replacing the get method from &lt;code&gt;SharedPreferences&lt;/code&gt; with the &lt;code&gt;.data&lt;/code&gt; method from DataStore, which returns a &lt;code&gt;Flow&amp;lt;T&amp;gt;&lt;/code&gt;. This will require understanding &lt;strong&gt;Kotlin Flow&lt;/strong&gt;, and creating at least a single element Flow when retrieving info from the DataStore.&lt;/li&gt;
&lt;li&gt;For reference, use the official documentation: &lt;a href="https://developer.android.com/topic/libraries/architecture/datastore" rel="noopener noreferrer"&gt;https://developer.android.com/topic/libraries/architecture/datastore&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Final Word
&lt;/h3&gt;

&lt;p&gt;Android development is constantly evolving, adopting new languages like &lt;code&gt;Kotlin&lt;/code&gt;, new UI development frameworks like &lt;code&gt;Jetpack Compose&lt;/code&gt;, new coding paradigms like &lt;code&gt;Kotlin Coroutines&lt;/code&gt; and &lt;code&gt;Kotlin Flow&lt;/code&gt;, and even creating some solutions to be more friendly with other modern Android technologies, like &lt;code&gt;Room&lt;/code&gt;, &lt;code&gt;DataStore&lt;/code&gt; and &lt;code&gt;Koin&lt;/code&gt;. Embracing modern tools like &lt;strong&gt;Kotlin, Jetpack Compose, Material Design 3, Koin, Coroutines, Jetpack Room, and DataStore&lt;/strong&gt; &lt;em&gt;not only simplifies development but also ensures apps are more robust, scalable, maintainable and secure.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The transition from legacy systems to modern frameworks isn’t always smooth, requires effort and time, may add some risks into the project, and new unexpected constraints, but the benefits far outweigh the challenges. &lt;em&gt;Take for example the reduced development time by adopting Kotlin instead of Java, or Compose instead of XML. Or the reduction of boilerplate code when using Kotlin instead of Java, or the powerful functionalities of Kotlin DSL libraries like Koin&lt;/em&gt;. By keeping up with these advancements, developers can deliver &lt;strong&gt;better experiences to users&lt;/strong&gt;, in a &lt;strong&gt;shorter time and accompany the ever-changing Android ecosystem&lt;/strong&gt; keeping their product up-to-date.&lt;/p&gt;




&lt;p&gt;Cover image designed by fullvector at Freepik - &lt;a href="http://www.freepik.com" rel="noopener noreferrer"&gt;www.freepik.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>legacy</category>
      <category>development</category>
      <category>refactorit</category>
    </item>
    <item>
      <title>Four dramatic predictions regarding AI tools and the IT market</title>
      <dc:creator>Marco Coelho</dc:creator>
      <pubDate>Mon, 20 Jan 2025 15:20:04 +0000</pubDate>
      <link>https://dev.to/marcotcdev/four-dramatic-predictions-regarding-ai-tools-and-the-it-market-o4m</link>
      <guid>https://dev.to/marcotcdev/four-dramatic-predictions-regarding-ai-tools-and-the-it-market-o4m</guid>
      <description>&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt;&lt;br&gt;
Of course, &lt;em&gt;you should take everything I say here with a grain of salt, given this is my personal and professional opinion,&lt;/em&gt; and everything I state here could change if IT professionals and the market as a whole make a concerted effort to address the issues. &lt;strong&gt;Nothing I'm predicting here is set in stone; the future can change if enough effort is put into shaping it.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;My prediction for the years ahead for IT professionals is grim, unless significant changes are made. Below are four reasons why I believe this:&lt;/p&gt;




&lt;h3&gt;
  
  
  1. The Tech Industry is Failing the Next Generation
&lt;/h3&gt;

&lt;p&gt;Let’s be frank: the tech industry is neglecting the next generation. The biggest issue isn’t with senior developers, tech leads, QAs, senior designers, project leaders, or product owners. Those roles are relatively secure. The real problem lies with newcomers: junior developers and trainees. &lt;strong&gt;They are being marginalized by the AI industry boom, and this phenomenon isn’t limited to developers but extends to many other careers as well.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The root of the problem is a lack of foresight from industry leaders. CEOs seem to have forgotten the old adage &lt;em&gt;memento mori&lt;/em&gt; ("Remember you are mortal"). People age, retire, and pass away. If there’s no new generation to replace them, the industry will falter, &lt;em&gt;Children of Men&lt;/em&gt; style. &lt;em&gt;Hiring and training newcomers is crucial, even if it appears economically inefficient in the short term.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Without new talent, the workforce pipeline dries up. Layoffs, industry crashes, and a lack of mentorship discourage new entrants. Reputation matters; burned bridges are hard to rebuild.&lt;/p&gt;

&lt;p&gt;Some CEOs believe AI can fill the gap, replacing junior roles entirely. But this strategy is flawed, as explained in the next section.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My proposed solution:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Establish valid trainee programs.&lt;/li&gt;
&lt;li&gt;Continue hiring junior developers.&lt;/li&gt;
&lt;li&gt;Ensure teams have a mix of experience levels, fostering mentorship and growth.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  2. Neglecting the Next Generation is Harmful to AI
&lt;/h3&gt;

&lt;p&gt;AI tools don’t emerge from a vacuum. They require skilled AI developers, machine learning engineers and architects to create and maintain large language models (LLMs). Additionally, these models rely on vast amounts of high-quality training data.&lt;/p&gt;

&lt;p&gt;Where does this data come from? The collective work of developers over decades. Open-source contributions, public repositories, and shared knowledge form the backbone of training datasets. If junior developers aren’t hired and nurtured, the pool of skilled engineers and open-source contributions will dwindle. &lt;em&gt;Over time, the quality and availability of training data will diminish, hindering AI advancements.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My proposed solution:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Support and sustain the developer community by investing in the next generation.&lt;/li&gt;
&lt;li&gt;Reduce over-reliance on AI tools.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  3. Coding AI Thrives on Non-AI Tech Advancements
&lt;/h3&gt;

&lt;p&gt;Many overlook the fact that AI’s impressive coding capabilities are a byproduct of advancements in developer-friendly technologies over the past two decades. &lt;strong&gt;Frameworks and tools like JVM, .NET, Compose, Swift, Next.js, and Node.js simplify development significantly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI tools thrive in this environment but struggle with older, more complex technologies. Let’s see an AI tool code x64 assembly, C, or C++ with the same proficiency and safety it exhibits in JavaScript or Python. &lt;strong&gt;Historically, poorly coded low-level software led to issues like the infamous Windows “blue screen of death.”&lt;/strong&gt; &lt;em&gt;Critical systems still rely on these languages, and skilled developers are irreplaceable in such contexts.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My proposed solution:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reserve AI tools for tasks involving high-level frameworks, or user friendly frameworks.&lt;/li&gt;
&lt;li&gt;Employ trained developers for critical software written in lower-level languages.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  4. IT is Developing a Bad Reputation
&lt;/h3&gt;

&lt;p&gt;The IT industry’s reputation is deteriorating. Hiring sprees during the pandemic followed by mass layoffs have created an environment of distrust. Promises of stability and growth often ring hollow, and statements like &lt;em&gt;“AI will replace developers”&lt;/em&gt; only exacerbate the issue.&lt;/p&gt;

&lt;p&gt;IT workers are also facing a mental health crisis. According to BIMA’s &lt;em&gt;Tech Inclusivity &amp;amp; Diversity Report 2019&lt;/em&gt;, 52% of tech workers have experienced anxiety or depression. Additionally, tech professionals are five times more likely to be depressed than the UK average and report stress levels comparable to those in healthcare. Source: &lt;a href="https://www.diversityintech.co.uk/workplace-diversity-and-mental-health-in-tech/" rel="noopener noreferrer"&gt;https://www.diversityintech.co.uk/workplace-diversity-and-mental-health-in-tech/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This environment discourages young people from pursuing tech careers. Burned by false promises and instability, few are willing to give the industry a second chance. &lt;em&gt;Consider for a moment, how many people do you personally know that have been affected by those?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My proposed solution:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Prioritize mental health in the workplace.&lt;/li&gt;
&lt;li&gt;Invest in reputation-building and transparency.&lt;/li&gt;
&lt;li&gt;Maintain consistent principles and avoid abrupt policy shifts (e.g., remote work mandates).&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;The future of the IT industry depends on the actions we take today. Ignoring the next generation, over-relying on AI, and fostering a toxic work environment will lead to long-term consequences. Again, I need to state clearly: This article is not an argument against AI, but it is an argument against over realiance on it. With strategic changes and a commitment to growth, those grim predictions may be changed, and the industry can secure a brighter future for it's professionals and proper adoption for it's technologies.&lt;/p&gt;

&lt;p&gt;Cover image designed by rawpixel.com at Freepik - &lt;a href="http://www.freepik.com" rel="noopener noreferrer"&gt;www.freepik.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>developers</category>
    </item>
    <item>
      <title>Three Common Pitfalls in Modern Android Development</title>
      <dc:creator>Marco Coelho</dc:creator>
      <pubDate>Wed, 15 Jan 2025 19:49:57 +0000</pubDate>
      <link>https://dev.to/marcotcdev/three-common-pitfalls-in-modern-android-development-1ec7</link>
      <guid>https://dev.to/marcotcdev/three-common-pitfalls-in-modern-android-development-1ec7</guid>
      <description>&lt;p&gt;Developing a modern Android solution can feel like navigating a dense jungle. There are countless tools and methodologies at your disposal, but one wrong step, and you’re in quicksand. Let’s look at three common pitfalls that can trip up even the most seasoned developers—and how to sidestep them like a pro.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Overlooking WebView Limitations in Jetpack Compose
&lt;/h4&gt;

&lt;p&gt;Jetpack Compose is a game-changer for building user interfaces. It’s sleek, declarative, and a joy to work with. But as much as Compose feels like the hero we deserve, it does have a kryptonite: WebView.&lt;/p&gt;

&lt;p&gt;WebView, the trusty sidekick of the older View system, allowed developers to load external web pages seamlessly. Unfortunately, Jetpack Compose doesn’t natively support WebView because it’s rooted in the older system. While you can technically use interop solutions to embed a WebView in Compose, it’s not without its drawbacks. For instance, screen recomposition—a fundamental concept in Compose—can become resource-intensive if not handled carefully.&lt;/p&gt;

&lt;p&gt;So, what’s the play? If your app relies heavily on WebView, you might want to reconsider how you’re integrating it or explore alternatives like fully adopting Compose-native workflows.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Mishandling Coroutines for Asynchronous Operations
&lt;/h4&gt;

&lt;p&gt;Coroutines are the Swiss Army knife of asynchronous programming in Android. They’re powerful, efficient, and—when used correctly—a delight to work with. But like any sharp tool, they’re also easy to misuse.&lt;/p&gt;

&lt;p&gt;One of the most common missteps is calling coroutines in contexts where they’re not lifecycle-aware. This can lead to issues like memory leaks or, worse, crashing your app because a coroutine outlived its welcome. The fix? Leverage lifecycle-aware coroutine contexts. Android provides viewModelScope for ViewModels and lifecycleScope for Activities and Fragments. These scopes automatically tie the lifecycle of your coroutines to the lifecycle of their respective components, ensuring you don’t end up with rogue processes.&lt;/p&gt;

&lt;p&gt;Remember: coroutines are your ally, not your babysitter. Use them responsibly.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Mixing Old and New Technologies Haphazardly
&lt;/h4&gt;

&lt;p&gt;We get it. Sometimes you’re working on a legacy project, and mixing old XML layouts with Jetpack Compose seems like the path of least resistance. Or maybe you’ve got one foot in the MVP camp and another in MVVM because the project evolved (read: spiraled) that way.&lt;/p&gt;

&lt;p&gt;The problem with blending these approaches is that each technology or architecture has its quirks. Mixing them without a clear strategy can result in a Frankenstein’s monster of a codebase—and not the cute, misunderstood kind.&lt;/p&gt;

&lt;p&gt;If you must mix technologies, ensure you’re doing so with a solid plan. Define clear boundaries between components, and don’t let one approach bleed unnecessarily into another. This ensures that your migration or hybrid solution is maintainable and predictable.&lt;/p&gt;

&lt;h4&gt;
  
  
  Wrapping Up
&lt;/h4&gt;

&lt;p&gt;Modern Android development is full of exciting possibilities, but it’s also easy to get tangled in the weeds. By being mindful of Jetpack Compose’s WebView limitations, handling coroutines with care, and approaching technology mixing strategically, you’ll stay on solid ground.&lt;/p&gt;

&lt;p&gt;Oh, and remember: development pitfalls are just stepping stones in disguise. Learn from them, and your next project will thank you for it.&lt;/p&gt;

&lt;p&gt;Keywords: Jetpack Compose, Android development, WebView, coroutines, lifecycleScope, viewModelScope, MVP, MVVM, modern Android development, mobile solutions.&lt;/p&gt;

&lt;p&gt;Cover image designed by fullvector at Freepik - &lt;a href="http://www.freepik.com" rel="noopener noreferrer"&gt;www.freepik.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>development</category>
      <category>mobile</category>
      <category>pitfalls</category>
    </item>
  </channel>
</rss>
