<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Syed Zubyl N | Software Developer - Architecture</title>
    <subtitle>Syed Zubyl N — Software Developer focused on Java, Spring Boot, backend development, REST APIs, databases, Flutter and production-oriented applications.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://syedzubyl.space/tags/architecture/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://syedzubyl.space"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-05-02T00:00:00+00:00</updated>
    <id>https://syedzubyl.space/tags/architecture/atom.xml</id>
    <entry xml:lang="en">
        <title>Designing a Production-Oriented Application from Mobile UI to Database</title>
        <published>2026-05-02T00:00:00+00:00</published>
        <updated>2026-05-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Syed Zubyl N
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://syedzubyl.space/blog/system-design-mobile-to-database/"/>
        <id>https://syedzubyl.space/blog/system-design-mobile-to-database/</id>
        
        <content type="html" xml:base="https://syedzubyl.space/blog/system-design-mobile-to-database/">&lt;h3 id=&quot;the-problem&quot;&gt;The Problem&lt;&#x2F;h3&gt;
&lt;p&gt;When transitioning from building simple prototype applications to production-oriented software, the architecture must change fundamentally. A prototype can connect a mobile UI directly to a database like Firebase, bypassing strict backend validation. A production application cannot. It requires clear separation of concerns, strict validation, and the ability to scale different components independently.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;context&quot;&gt;Context&lt;&#x2F;h3&gt;
&lt;p&gt;The goal is to design a system where a Flutter mobile client securely interacts with a Java Spring Boot backend, which in turn manages business logic and talks to a relational database (MySQL).&lt;&#x2F;p&gt;
&lt;p&gt;The flow looks like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Mobile Client &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ↓ (JSON over HTTPS)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;API Gateway &#x2F; Controller &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ↓ (DTOs)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Service Layer &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ↓ (Entities)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Repository Layer &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ↓ (SQL)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Database&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;what-i-tried-the-anti-pattern&quot;&gt;What I Tried (The Anti-Pattern)&lt;&#x2F;h3&gt;
&lt;p&gt;Early in my learning journey, I tried building “fat controllers.” The API controller would receive an HTTP request, open a database transaction, parse the JSON, write custom SQL queries, and return an HTTP response all in one massive function.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-failed&quot;&gt;What Failed&lt;&#x2F;h3&gt;
&lt;p&gt;This failed spectacularly as the application grew.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Testing:&lt;&#x2F;strong&gt; I couldn’t test the business logic without mocking the entire HTTP request&#x2F;response cycle.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Reusability:&lt;&#x2F;strong&gt; When a scheduled background job needed to update user records, I had to duplicate the code from the controller because the controller was tightly coupled to HTTP requests.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Security:&lt;&#x2F;strong&gt; Raw data structures were passed directly back to the client, exposing internal database IDs and password hashes.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;what-worked-technical-explanation&quot;&gt;What Worked &amp;amp; Technical Explanation&lt;&#x2F;h3&gt;
&lt;p&gt;I implemented a strict N-Tier Architecture, separating concerns at every layer.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;1. The API Layer (Controllers)&lt;&#x2F;strong&gt;
Controllers only care about HTTP. They receive a request, validate the incoming JSON against a Data Transfer Object (DTO), and immediately pass the data to the Service Layer.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;2. The Service Layer (Business Logic)&lt;&#x2F;strong&gt;
This is the brain of the application. It knows nothing about HTTP or SQL. It receives validated DTOs, applies business rules (e.g., “A user cannot register if they are under 18”), and coordinates with the Repository Layer.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;3. The Repository Layer (Data Access)&lt;&#x2F;strong&gt;
This layer handles the actual database communication using an ORM like Hibernate or raw SQL queries. It returns Domain Entities.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;4. External Services&lt;&#x2F;strong&gt;
If the application needs to send an email or process a payment, the Service Layer calls an Interface (e.g., &lt;code&gt;EmailService&lt;&#x2F;code&gt;). The actual implementation (e.g., &lt;code&gt;SendGridEmailServiceImpl&lt;&#x2F;code&gt;) is injected.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h3&gt;
&lt;p&gt;Separation of concerns is not just theoretical computer science overhead. It is the only way to build software that can survive changing requirements. By decoupling the HTTP layer from the business logic, I can swap out the web framework. By decoupling the business logic from the database, I can swap out the ORM.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-i-would-do-differently&quot;&gt;What I Would Do Differently&lt;&#x2F;h3&gt;
&lt;p&gt;I would introduce an API Gateway pattern earlier if the system required microservices. However, for most of the production applications I build, a well-structured modular monolith using the exact architecture described above is significantly more efficient to deploy and maintain.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Designing a Reliable API Layer for a Mobile Application</title>
        <published>2026-03-22T00:00:00+00:00</published>
        <updated>2026-03-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Syed Zubyl N
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://syedzubyl.space/blog/designing-reliable-api-layer/"/>
        <id>https://syedzubyl.space/blog/designing-reliable-api-layer/</id>
        
        <content type="html" xml:base="https://syedzubyl.space/blog/designing-reliable-api-layer/">&lt;h3 id=&quot;the-problem&quot;&gt;The Problem&lt;&#x2F;h3&gt;
&lt;p&gt;In the early stages of a mobile LMS application, HTTP requests were scattered directly inside UI widgets. Buttons would execute &lt;code&gt;http.get&lt;&#x2F;code&gt;, parse JSON inline, and call &lt;code&gt;setState&lt;&#x2F;code&gt;. This quickly became unmaintainable. Token expiration caused random crashes, error handling was inconsistent, and mocking data for tests was impossible.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;context&quot;&gt;Context&lt;&#x2F;h3&gt;
&lt;p&gt;A robust mobile application requires a strict separation of concerns. The UI should only care about &lt;em&gt;displaying&lt;&#x2F;em&gt; state, not fetching it. The networking layer must handle token injection, timeouts, retries, and error standardization before the data ever reaches the UI.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-i-tried&quot;&gt;What I Tried&lt;&#x2F;h3&gt;
&lt;p&gt;I initially tried to create a single massive &lt;code&gt;ApiService&lt;&#x2F;code&gt; class that contained every single endpoint in the application.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-failed&quot;&gt;What Failed&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;ApiService&lt;&#x2F;code&gt; file grew to thousands of lines. When multiple developers worked on different features (Authentication, Courses, User Profile), merge conflicts became a daily nightmare. Furthermore, handling token refreshes on a per-method basis resulted in heavily duplicated code.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-worked-technical-explanation&quot;&gt;What Worked &amp;amp; Technical Explanation&lt;&#x2F;h3&gt;
&lt;p&gt;I re-architected the API layer into a layered, modular system based on the Repository Pattern and Interceptors.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;1. The Base HTTP Client (The Interceptor Layer)&lt;&#x2F;strong&gt;
Instead of using raw &lt;code&gt;http.Client&lt;&#x2F;code&gt;, I implemented a wrapper (using packages like &lt;code&gt;dio&lt;&#x2F;code&gt; or custom &lt;code&gt;http.BaseClient&lt;&#x2F;code&gt; implementations) that intercepts every request.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Request Interceptor:&lt;&#x2F;strong&gt; Automatically injects the &lt;code&gt;Authorization: Bearer &amp;lt;token&amp;gt;&lt;&#x2F;code&gt; header from secure storage into every outgoing request.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Response Interceptor:&lt;&#x2F;strong&gt; Global error handling. If a &lt;code&gt;401 Unauthorized&lt;&#x2F;code&gt; is returned, the interceptor pauses all outgoing requests, silently hits the refresh-token endpoint, updates secure storage, and retries the failed requests.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;2. Domain-Specific Repositories&lt;&#x2F;strong&gt;
Instead of one massive API class, I created focused repositories:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AuthRepository&lt;&#x2F;code&gt;: Handles login, registration, and token management.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;CourseRepository&lt;&#x2F;code&gt;: Fetches course lists and lesson details.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;VideoRepository&lt;&#x2F;code&gt;: Manages video streaming URLs and playback telemetry.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;3. Standardized Result Wrappers&lt;&#x2F;strong&gt;
Instead of throwing exceptions directly into the UI, repositories return a standardized Result type (often using Dart’s &lt;code&gt;Either&lt;&#x2F;code&gt; pattern via the &lt;code&gt;fpdart&lt;&#x2F;code&gt; or &lt;code&gt;dartz&lt;&#x2F;code&gt; package).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;dart&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;Future&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;Either&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;ApiFailure&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; Course&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; getCourseDetails&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt; id) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;async&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;  try&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    final&lt;&#x2F;span&gt;&lt;span&gt; response &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;= await&lt;&#x2F;span&gt;&lt;span&gt; _client.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;#39;&#x2F;courses&#x2F;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;id&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; Right&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;Course&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;fromJson&lt;&#x2F;span&gt;&lt;span&gt;(response.data));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  } &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;on&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; DioError&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F97583;&quot;&gt; catch&lt;&#x2F;span&gt;&lt;span&gt; (e) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F97583;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt; Left&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #79B8FF;&quot;&gt;ApiFailure&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt;fromDioError&lt;&#x2F;span&gt;&lt;span&gt;(e));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h3&gt;
&lt;p&gt;Separating the UI from the network layer is non-negotiable for production apps. The complexity of handling network latency, offline states, and token lifecycles must be encapsulated so the UI can remain declarative and clean.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-i-would-do-differently&quot;&gt;What I Would Do Differently&lt;&#x2F;h3&gt;
&lt;p&gt;I would implement local caching (using SQLite) much earlier in the architecture. While the API layer was robust, relying entirely on network availability resulted in a poor experience on slow connections. Integrating a repository that checks local storage &lt;em&gt;before&lt;&#x2F;em&gt; hitting the API is the next logical step.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Flutter Splash Screens vs Native Android Startup Screens</title>
        <published>2026-01-25T00:00:00+00:00</published>
        <updated>2026-01-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Syed Zubyl N
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://syedzubyl.space/blog/flutter-splash-screens/"/>
        <id>https://syedzubyl.space/blog/flutter-splash-screens/</id>
        
        <content type="html" xml:base="https://syedzubyl.space/blog/flutter-splash-screens/">&lt;h3 id=&quot;the-problem&quot;&gt;The Problem&lt;&#x2F;h3&gt;
&lt;p&gt;A client wanted a highly customized, complex, animated Flutter-style splash screen to play the moment the user tapped the app icon. They wanted their branding to animate immediately, replacing the “boring” default app launch experience.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;context&quot;&gt;Context&lt;&#x2F;h3&gt;
&lt;p&gt;When an Android application launches, there is an unavoidable window of time where the OS loads the app process into memory. During this time, Android displays a system-controlled launch screen. With the introduction of Android 12, Google enforced the &lt;code&gt;SplashScreen&lt;&#x2F;code&gt; API, standardizing this experience to show the app icon and a background color.&lt;&#x2F;p&gt;
&lt;p&gt;Flutter operates inside an Android Activity. The Flutter engine must initialize, load the Dart isolate, and render the first frame. This takes time.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-i-tried&quot;&gt;What I Tried&lt;&#x2F;h3&gt;
&lt;p&gt;The client wanted the animation to start instantly. I initially tried putting the animation directly into the first Flutter widget loaded by &lt;code&gt;runApp()&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-failed&quot;&gt;What Failed&lt;&#x2F;h3&gt;
&lt;p&gt;This resulted in a jarring experience:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;User taps app.&lt;&#x2F;li&gt;
&lt;li&gt;System shows Android 12 static splash screen (icon + background).&lt;&#x2F;li&gt;
&lt;li&gt;System splash disappears.&lt;&#x2F;li&gt;
&lt;li&gt;White flash (briefly, as Flutter attaches).&lt;&#x2F;li&gt;
&lt;li&gt;Flutter animated splash screen begins.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;It looked like two separate splash screens playing back-to-back.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-worked-technical-explanation&quot;&gt;What Worked &amp;amp; Technical Explanation&lt;&#x2F;h3&gt;
&lt;p&gt;The actual limitation is that the system-controlled Android launch splash occurs &lt;em&gt;before&lt;&#x2F;em&gt; the Flutter UI is ready, especially under Android 12+ splash-screen rules. A Flutter animation can begin after the Flutter engine&#x2F;UI becomes available, but it does not replace the system launch sequence in the same way.&lt;&#x2F;p&gt;
&lt;p&gt;The correct approach was a hybrid hand-off:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Configure the native Android 12 &lt;code&gt;SplashScreen&lt;&#x2F;code&gt; via &lt;code&gt;styles.xml&lt;&#x2F;code&gt; to match the exact background color and static logo of the first frame of the Flutter animation.&lt;&#x2F;li&gt;
&lt;li&gt;Use the &lt;code&gt;flutter_native_splash&lt;&#x2F;code&gt; package to hold the native splash screen up until Flutter is fully rendered.&lt;&#x2F;li&gt;
&lt;li&gt;Once Flutter renders its first frame, immediately begin the complex Flutter animation from the exact state the native splash left off.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&amp;lt;!-- android&#x2F;app&#x2F;src&#x2F;main&#x2F;res&#x2F;values-v31&#x2F;styles.xml --&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;style&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;LaunchTheme&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; parent&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;Theme.SplashScreen&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;item&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;windowSplashScreenBackground&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;@color&#x2F;brand_background&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;item&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;item&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;windowSplashScreenAnimatedIcon&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;@drawable&#x2F;launch_icon&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;item&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;item&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B392F0;&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9ECBFF;&quot;&gt;&amp;quot;postSplashScreenTheme&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;@style&#x2F;NormalTheme&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;item&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #85E89D;&quot;&gt;style&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h3&gt;
&lt;p&gt;You cannot fight the OS. The Android lifecycle dictates what happens before your application code runs. Understanding the boundaries between native Android processes and the Flutter engine is critical for smooth UX.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-i-would-do-differently&quot;&gt;What I Would Do Differently&lt;&#x2F;h3&gt;
&lt;p&gt;I will clarify the distinction between “OS Launch Screen” and “App Onboarding Animation” to clients early on. Managing expectations around what happens in the first 500ms of an app’s lifecycle prevents impossible requests later.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
