CN

loading
Can an App Really Do Whatever It Wants With System Permissions?

In 2023, public research described vulnerability exploitation code and dynamically delivered DEX files associated with an Android app. I wanted to see which system capabilities this code attempted to use. I put the original article together in a hurry and did not examine all the code closely. The walkthrough remains here, with corrections based on the screenshots and AOSP source. The original references follow:

  1. Deep Blue Insight: The Most “Unpardonable” Vulnerabilities of 2022
  2. XXX apk embedded privilege escalation code and dynamic delivery dex analysis
  3. History of Android Deserialization Vulnerability Attack and Defense

Security is not my specialty. For background, see History of Android Deserialization Vulnerability Attack and Defense. This article does not reproduce the exploit chain or treat an API call as proof of root access.

Android Performance Optimization: Techniques, Methods, and Tools

Hackers and Painters

In his book , Paul Graham states: “The execution efficiency gap between different programming languages is becoming increasingly large, so profilers are becoming more important. Currently, performance profiling is not receiving enough attention. Many people still believe that the key to improving program running speed is developing compilers that can generate faster code. The gap between code efficiency and machine performance is continuously increasing, and we will increasingly clearly see that the key to improving application software running speed is having a good performance profiler to guide program development.”

By Paul Graham — Hackers and Painters

Search for “Android optimization tools” and you’ll find plenty of articles. Many repeat the same material or go straight to instructions without explaining how the tools fit together. It is easy to come away thinking one tool can solve everything. Our team’s experience says otherwise: there is no silver bullet. Tools change, and familiar problems return in new forms. You still need to understand what is happening underneath.

We’ll start with the data we collect, how we collect it, and how we analyze it. Then we’ll look at Google’s traditional “big three” performance tools. We want you to understand the measurements as well as the tools, and save yourself some of the detours others have already taken.

2021 Year in Review: Baby, Career, and Growth

2021 has passed. Taking advantage of the New Year holiday, I’d like to look back at the year. This will be a casual review—writing whatever comes to mind. 2021 for me was marked by becoming a father, changing jobs (including a long, boring spell at home in between), and making new friends. Overall, it was a pretty good year.

However, in terms of personal growth, I feel like I might have stagnated or even regressed, which is a bit alarming. Learning is like rowing upstream; if you don’t move forward, you fall back. In 2022, I need to spend more time working through things properly. I hope to progress together with everyone reading this.

I’ve also tallied some data related to my technical sharing, shared my income from these platforms, and listed some hardware and software I recommend. Feel free to take a look.

Android Systrace Responsiveness in Action 3 - Extended Knowledge on Responsiveness

Jank, slow response, and ANRs can share causes or occur together, but they are not three severity levels of the same problem. When a user says an app feels slow, first distinguish uneven animation, a long delay after an action, and a system-detected failure to respond.

Animation and scrolling stutter is usually called jank. Long startup, screen wake-up, or navigation delays are slow response / high latency. An ANR depends on a specific system timeout condition. Frame-drop rate, startup duration, and ANR rate measure different things.

This is the third article in the Responsiveness series, focusing on extended knowledge when using Systrace to analyze app responsiveness, including startup speed testing, log interpretation, state analysis, and third-party startup libraries.

Android Systrace Responsiveness in Action 2 - Responsiveness Analysis - Using App Startup as an Example

Jank, slow response, and ANRs can share causes or occur together, but they are not three severity levels of the same problem. When a user says an app feels slow, first distinguish uneven animation, a long delay after an action, and a system-detected failure to respond.

Animation and scrolling stutter is usually called jank. Long startup, screen wake-up, or navigation delays are slow response / high latency. An ANR depends on a specific system timeout condition. Frame-drop rate, startup duration, and ANR rate measure different things.

This is the second article in the Responsiveness series, using Android App Cold Start as an example to explain how to use Systrace for analysis.

Android Systrace Responsiveness in Action 1 - Understanding Responsiveness Principles

Jank, Responsiveness, and ANR often appear together and can share contributing causes, but they are not severity levels of one mechanism. Uneven visual progress, delayed feedback, and an ANR triggered by a particular timeout need separate evidence. Treat a user’s “the app is slow/stuttering” as an experience report first, then establish which action and outcome are delayed.

Uneven animation or scrolling is usually called Jank. Long startup, screen-wake, or transition delays are slow response / high latency; ANR means Application Not Responding. These categories can overlap. High latency can coexist with jank, while ANRs must be diagnosed by their specific trigger.

Furthermore, within Apps or manufacturers, Jank, Responsiveness, and ANR have individual metrics like Frame Drop Rate, Startup Speed, and ANR Rate. Mastering the analysis and optimization of these issues is crucial for developers.

This is the first article in the Responsiveness series, focusing on theoretical knowledge, including an overview of performance engineering, key responsiveness concepts, and analysis methodologies.

Android Systrace Smoothness in Action 3 - FAQs During Jank Analysis

Different people have different understandings of smoothness (jank/dropped frames) and different perceptions of jitter thresholds. Therefore, before starting this series, it is necessary to clarify the content to avoid misunderstandings. Here are some basic explanations:

  1. For mobile users, jank encompasses many scenarios: dropped frames when scrolling lists, excessive white screen during app startup, slow screen wake-up when pressing the power button, unresponsive interface followed by a crash, no response when clicking an icon, incoherent window animations, lagging touch response, or stuttering when entering the desktop after a reboot. These scenarios differ slightly from what developers understand as “jank.” Developers categorize these more finely, which is a cognitive gap between developers and users that must be noted when handling feedback from users or testers.
  2. Developers can initially classify feedback as Smoothness (uneven visual progress), Responsiveness (long waits after an action), or Stability (crashes and ANRs). These can overlap. An icon that appears unresponsive is not necessarily a stability failure; input, application state, and logs determine the diagnosis.
  3. These are not one Message-timeout mechanism with different thresholds. Long main-thread tasks can delay both input and rendering, but GPU work, SurfaceFlinger, the display stack, scheduling, or remote services can also cause delays. ANRs depend on specific input or component timeout rules; crashes have separate causes such as exceptions or signals. A long Message alone establishes neither.
  4. This series primarily analyzes smoothness-related issues. Responsiveness and stability will be covered in dedicated articles. Understanding smoothness first will make analyzing responsiveness and stability much easier.
  5. This series focuses on using Systrace (Perfetto) for analysis. Systrace is our entry point because many factors affect smoothness—some within the app itself and others within the system. Systrace (Perfetto) provides a holistic view of the system’s operation during the problem, helping us initially pinpoint the root cause.
Android Systrace Smoothness in Action 2 - Case Analysis - MIUI Launcher Scroll Jank Analysis

Different people have different understandings of smoothness (jank/dropped frames) and different perceptions of jitter thresholds. Therefore, before starting this series, it is necessary to clarify the content to avoid misunderstandings. Here are some basic explanations:

  1. For mobile users, jank encompasses many scenarios: dropped frames when scrolling lists, excessive white screen during app startup, slow screen wake-up when pressing the power button, unresponsive interface followed by a crash, no response when clicking an icon, incoherent window animations, lagging touch response, or stuttering when entering the desktop after a reboot. These scenarios differ slightly from what developers understand as “jank.” Developers categorize these more finely, which is a cognitive gap between developers and users that must be noted when handling feedback from users or testers.
  2. Developers can initially classify feedback as Smoothness (uneven visual progress), Responsiveness (long waits after an action), or Stability (crashes and ANRs). These can overlap. An icon that appears unresponsive is not necessarily a stability failure; input, application state, and logs determine the diagnosis.
  3. These are not one Message-timeout mechanism with different thresholds. Long main-thread tasks can delay both input and rendering, but GPU work, SurfaceFlinger, the display stack, scheduling, or remote services can also cause delays. ANRs depend on specific input or component timeout rules; crashes have separate causes such as exceptions or signals. A long Message alone establishes neither.
  4. This series primarily analyzes smoothness-related issues. Responsiveness and stability will be covered in dedicated articles. Understanding smoothness first will make analyzing responsiveness and stability much easier.
  5. This series focuses on using Systrace (Perfetto) for analysis. Systrace is our entry point because many factors affect smoothness—some within the app itself and others within the system. Systrace (Perfetto) provides a holistic view of the system’s operation during the problem, helping us initially pinpoint the root cause.
Android Systrace Smoothness in Action 1 - Understanding Jank Principles

Different people have different understandings of smoothness (jank/dropped frames) and different perceptions of jitter thresholds. Therefore, before starting this series, it is necessary to clarify the content to avoid misunderstandings and help everyone approach these articles with the right questions. Here are some basic explanations:

  1. For mobile users, jank encompasses many scenarios: dropped frames when scrolling lists, excessive white screen during app startup, slow screen wake-up when pressing the power button, unresponsive interface followed by a crash, no response when clicking an icon, incoherent window animations, lagging touch response, or stuttering when entering the desktop after a reboot. These scenarios differ slightly from what developers understand as “jank.” Developers categorize these more finely, which is a cognitive gap between developers and users that must be noted when handling feedback from users or testers.
  2. Developers can initially classify feedback as Smoothness (uneven visual progress), Responsiveness (long waits after an action), or Stability (crashes and ANRs). These can overlap. An icon that appears unresponsive is not necessarily a stability failure; input, application state, and logs determine the diagnosis.
  3. These are not one Message-timeout mechanism with different thresholds. Long main-thread tasks can delay both input and rendering, but GPU work, SurfaceFlinger, the display stack, scheduling, or remote services can also cause delays. ANRs depend on specific input or component timeout rules; crashes have separate causes such as exceptions or signals. A long Message alone establishes neither.
  4. This series primarily analyzes smoothness-related issues. Responsiveness and stability will be covered in dedicated articles. Understanding smoothness first will make analyzing responsiveness and stability much easier.
  5. This series focuses on using Systrace (Perfetto) for analysis. Systrace is our entry point because many factors affect smoothness—some within the app itself and others within the system. Systrace (Perfetto) provides a holistic view of the system’s operation during the problem, helping us initially pinpoint the root cause.
Analysis of Android App Chain Wakeups

The release of MIUI 12 brought a long-standing battle between App developers and ROM developers into the public eye, revealing the intricate details of this technical tug-of-war. As the saying goes, “While the demon rises a foot, the path rises ten feet.” ROM developers, with their higher system-level permissions, generally hold the upper hand. App developers, however, are not easily deterred, employing various “black technologies” for background persistence and cross-app wakeups. Even Google has stepped in to mediate, establishing rules to regulate behavior for both parties. This competition is arguably healthy; a total victory by either side would inevitably lead to stagnation or the loss of useful functionality.

However, the victims of this struggle are undoubtedly the consumers. If App developers succeed, phones become cluttered with persistent background processes that hog CPU and memory. Conversely, if ROM developers are too aggressive, the app experience suffers—a pain well-known to many Android developers.

As discussed later in this article, most smartphone manufacturers have developed their own strategies to handle auto-starts and associated starts. Beyond the technical struggle, there’s the issue of privacy. Baidu’s Robin Li once remarked that “Chinese people are more open about privacy and relatively less sensitive. If they can trade privacy for convenience, safety, or efficiency, they are willing to do so in many cases.” Consider the convenience of copying a phrase in WeChat and having Taobao automatically open to the corresponding item. It’s helpful, isn’t it? But do we really want every app peering into our clipboards?

Android Systrace Basics - SurfaceFlinger Explained

This is the fifth article in the Systrace series, primarily providing a brief introduction to the workflow of SurfaceFlinger. It covers several important threads within SurfaceFlinger, including Vsync signal interpretation, app buffer display, and jank detection. Since Vsync has already been covered in Systrace Basics - Vsync Explained and Detailed Explanation of Android Rendering Mechanism Based on Choreographer, it won’t be discussed in detail here.

The purpose of this series is to view the overall operation of the Android system from a different perspective using Systrace, while also providing an alternative angle for learning the Framework. Perhaps you’ve read many articles about the Framework but can never remember the code, or you’re unclear about the execution flow. Maybe from Systrace’s graphical perspective, you can gain a deeper understanding.

Android Systrace Basics - CPU Info Interpretation

This is the twelfth article in the Systrace series, primarily providing a brief introduction to the CPU information area (Kernel) in Systrace. It covers how to view CPU-related information output by the Kernel module, including CPU frequency, scheduling, frequency locking, and core locking.

The purpose of this series is to view the overall operation of the Android system from a different perspective using Systrace, while also providing an alternative angle for learning the Framework. Perhaps you’ve read many articles about the Framework but can never remember the code, or you’re unclear about the execution flow. Maybe from Systrace’s graphical perspective, you can gain a deeper understanding.

Android Systrace Basics - Triple Buffer Explained

This is the eleventh article in the Systrace series, providing a brief introduction to Triple Buffer within Systrace. It covers how to identify jank in Systrace, perform preliminary localization and analysis, and explains the impact of Triple Buffer on performance.

The purpose of this series is to view the overall operation of the Android system from a different perspective using Systrace, while also providing an alternative angle for learning the Framework. Perhaps you’ve read many articles about the Framework but can never remember the code, or you’re unclear about the execution flow. Maybe from Systrace’s graphical perspective, you can gain a deeper understanding.

Android Systrace Basics - Binder and Lock Contention Explained

This is the tenth article in the Systrace series, primarily providing a brief introduction to Binder and lock information in Systrace. It covers the basic situation of Binder, the representation of Binder communication in Systrace, how to view Binder information, and analysis of lock contention in SystemServer.

The purpose of this series is to view the overall operation of the Android system from a different perspective using Systrace, while also providing an alternative angle for learning the Framework. Perhaps you’ve read many articles about the Framework but can never remember the code, or you’re unclear about the execution flow. Maybe from Systrace’s graphical perspective, you can gain a deeper understanding.

Android Systrace Basics - Vsync Explained

This is the seventh article in the Systrace series, primarily introducing the Vsync mechanism in Android. This article examines the display of each frame in the Android system from the perspective of Systrace. Vsync is a critical mechanism in Systrace. Although invisible and intangible when operating a phone, we can see in Systrace how the Android system, guided by Vsync signals, orderly performs rendering and composition for each frame, ensuring stable frame rates.

The purpose of this series is to view the overall operation of the Android system from a different perspective using Systrace, while also providing an alternative angle for learning the Framework. Perhaps you’ve read many articles about the Framework but can never remember the code, or you’re unclear about the execution flow. Maybe from Systrace’s graphical perspective, you can gain a deeper understanding.

Complete Guide to Android App Startup Optimization

I’ve gathered the Android app startup optimization approaches I knew of when writing this article. Use them as a checklist: see what others have tried, then look for gaps in your own app. The details depend heavily on your business, so I won’t explain every implementation here. Once you find an approach that fits, follow up on that particular method.

I’ve also included some startup work done by system manufacturers, limited to the parts I know about. There are proprietary tricks I can’t cover here. Knowing what happens on the system side may still help, including when discussing whitelisting or SDK integration with a manufacturer.

Comprehensive Record of Android App Startup Optimization

I’ve gathered the Android app startup optimization approaches I knew of when writing this article. Use them as a checklist: see what others have tried, then look for gaps in your own app. The details depend heavily on your business, so I won’t explain every implementation here. Once you find an approach that fits, follow up on that particular method.

I’ve also included some startup work done by system manufacturers, limited to the parts I know about. There are proprietary tricks I can’t cover here. Knowing what happens on the system side may still help, including when discussing whitelisting or SDK integration with a manufacturer.

Android Systrace Basics - MainThread and RenderThread Explained

This is the ninth article in the Systrace series, primarily introducing the MainThread and RenderThread in Android Apps—commonly known as the Main Thread and Rendering Thread. This article examines their workflows from the perspective of Systrace and covers related topics: jank, software rendering, and dropped frame calculation.

The purpose of this series is to view the overall operation of the Android system from a different perspective using Systrace, while also providing an alternative angle for learning the Framework. Perhaps you’ve read many articles about the Framework but can never remember the code, or you’re unclear about the execution flow. Maybe from Systrace’s graphical perspective, you can gain a deeper understanding.

Android Systrace Basics - Input Interpretation

This is the sixth article in the Systrace series, primarily providing a brief introduction to Input in Systrace. It covers the Input workflow, how Input information is represented in Systrace, and how to combine Input info to analyze related performance issues.

The purpose of this series is to view the overall operation of the Android system from a different perspective using Systrace, while also providing an alternative angle for learning the Framework. Perhaps you’ve read many articles about the Framework but can never remember the code, or you’re unclear about the execution flow. Maybe from Systrace’s graphical perspective, you can gain a deeper understanding.

Analysis of 'Zombie Animations' in the Android Background

This article records a 2019 issue: animation work continued after the app’s UI was no longer visible. However, some apps continue to run “zombie animations”—animations that are completely invisible to the user yet consume precious CPU cycles and battery. When users discover this, the result is often a manual kill, an OS-level background restriction, or an outright uninstallation.

This issue can be easy to miss. In the original investigation, I used Systrace after opening apps and returning home, capturing traces while swiping between launcher pages. Some departed apps still fired callbacks. A reproduction should record versions, operations, and visibility; opening many apps is not itself a diagnostic requirement or proof.

Here, “zombie animations” means updates that continue when their UI is invisible and the feature no longer needs them. Many paths can schedule animation work through Choreographer. Investigate the actual stack, playback state, and library version. A live process is not necessarily free to consume CPU indefinitely; modern systems can freeze eligible cached processes.

Detailed Explanation of Android Rendering Mechanism Based on Choreographer

This article introduces Choreographer, a class that app developers rarely encounter but is crucial in the Android Framework rendering pipeline. It covers the background of Choreographer‘s introduction, an overview, source code analysis, its relationship with MessageQueue, its use in APM, and optimization ideas from mobile manufacturers.

Choreographer coordinates animations, some input processing, and View updates with display timing. It requests frame callbacks when work is pending rather than unconditionally waking the app on every physical refresh. A 60Hz display, common in 2019, has an interval of about 16.67ms; 90Hz and 120Hz correspond to about 11.11ms and 8.33ms. Modern devices can also change refresh rates. A timely callback does not mean the image has been presented: RenderThread, GPU, composition, and display work remain. Understanding this flow helps explain Message, Handler, Looper, MessageQueue, Measure, Layout, and Draw.

Overview of Jank and Frame Drops in Android - Low Memory

In the Overview of Jank and Frame Drops in Android - System Layer article, we touched upon jank cases caused by low system memory. Since low memory has a significant impact on overall device performance, I’m dedicating this article to exploring those effects in depth.

As Android versions evolve and apps become more feature-heavy, their memory requirements increase. When this article was written in 2019, many devices had 4GB of RAM or less. These users are prone to low memory situations, especially after major system updates or as more apps and services run concurrently.

Memory pressure can contribute to slow responsiveness and jank. Examples include longer app launch times, more frame drops in scrolling, more frequent cold starts as background processes are killed, and extra reclaim/restart work that can increase power use. Heat alone does not diagnose memory pressure. Below, I’ll outline the causes, debugging methods, and potential optimizations for these issues.

Case Study: Debugging the Android Launcher Kill Problem

This started with a bug I encountered at work. It was not a difficult one, but while writing my diary afterward, I thought the investigation was worth recording and sharing. I also learned some useful analysis and tool tricks from my clever colleague Mei Ming.

I’ve used a variety of tools mentioned in my Android Performance Optimization Methodology, including:

  • Reproduction Video
  • Event Log
  • AS Source/Debug
  • AS Profiler
  • Systrace
  • Dumpsys
  • Unix ps utility

You might wonder whether such a simple bug needs an article. I wanted to keep a record for myself, and the way we used the tools together may be useful in other investigations. If it helps you, all the better. If you have your own debugging tricks, please join our discussion group and share them!

Overview of Jank and Frame Drops in Android - System Layer

Technical review · 2026-10-13. These cases and screenshots date from 2019. The review uses relevant Android 8.1/9/16 source, Linux v6.6 documentation, and current Android documentation while preserving the images and the author’s experience. Long slices, CPU numbers, reclaim activity, and input pacing are no longer treated as standalone proof of root cause. No original-device rerun or complete trace replay was performed, and missing conditions are not invented.

The Application Layer article covers app-side problems. Here we organize cases around system services, display, scheduling, and memory. Hardware, kernels, and vendor implementations differ, so retain the actual system version and configuration.

OEM and app teams may use Matrix or their own monitoring. System privileges can expose more evidence, but capture scope still depends on build type, kernel configuration, and enabled sources.

Smoothness is not simply average FPS. An average of 55 FPS over one second on a 60 Hz display does not locate the delayed frames or determine every user’s perception. Examine intended pacing, actual presentation intervals, and input response. Static screens need not submit content on every refresh. The four-part series is:

A Detailed Guide to Activity Launch Modes in Android

Technical review · 2026-10-13. The 2019 sequences remain historical examples. Task selection, affinity, and Recents behavior were checked against AOSP android-9.0.0_r1 and android-16.0.0_r1; Android 12 (API 31) singleInstancePerTask is added below. The old records lack a complete device build identifier, and no device rerun was performed for this review.

Android Activities have several important launch modes: standard, singleTop, singleTask, and singleInstance. Plenty of articles explain these modes. I wrote a small demo to show how they change the arrangement of activities in tasks. The newer singleInstancePerTask mode is covered afterward.

Ordinary navigation within a task is commonly LIFO. Below, A -> B denotes the sequence of launch actions; task contents are listed top first. Keep an eye on the task contents after each action; following the changes makes the differences easier to see. Repeating a launch action does not necessarily create an instance. A Task is not a process or necessarily one visible Recents card.

I put the demo on GitHub too: AndroidLunchModeTest. The reviewed snapshot is eaa1f987e332e0f85187a911ad9ae01cd20fff05, using compile/target SDK 29 and min SDK 26. Its package is com.example.lunchmodetest, whereas the historical sequences below retain com.example.launchmodetest.

Check all navigation targets for each case. In the snapshot, MainActivity.startSingleTopActivity launches SingleTaskActivity, and StandardActivity launches SingleInstanceWithAffinityActivity by default. Changing one target does not implement every sequence. The WithAffinity classes actually use empty affinity; SingleTopWithAffinityActivity does not even declare singleTop. Class names are not configuration evidence. The sample code was inspected for this review; the project was not modified or compiled.

The explanations assume the same user, ordinary foreground Activity launches, and no extra Intent flags unless stated. Updating the old project to target SDK 31+ also requires explicit android:exported for components with intent filters; use true for the Launcher entry.

Android Systrace Basics - Prerequisites for Analyzing Systrace

Technical update — 2026-10-13: Historical Systrace screenshots are retained, including cases added after the original 2019 article. Colors and shortcuts refer to the legacy UI. Linux state semantics are checked against v6.6 documentation; the modern UI reference is Perfetto v58.3 (11fbaed83). Inaccurate Self Time, wakeup and scheduling-state annotations in the images are corrected in the adjacent text. These are not new device measurements.

This is the second article in the Systrace series, primarily explaining the prerequisites for analyzing Systrace. With these prerequisites, analyzing Systrace will be more effective, allowing you to identify issues faster and more efficiently.

This article introduces how to view thread states in Systrace, how to analyze thread wakeup information, how to interpret data in the information panel, and common shortcuts. By studying this article, you will gain an understanding of process and thread-related information and know how to extract key information from complex Systrace traces.

Android Systrace Basics - SystemServer Explained

Technical update — 2026-10-13: The historical screenshots and code are retained. Code excerpts were checked against AOSP android-10.0.0_r1; modern differences use android-16.0.0_r1 as an example. These tags do not identify the screenshot devices: the original traces, ROMs and build details were not supplied. The descriptions of animation ownership, StartingWindow and thread interactions are corrected below.

This is the fourth article in the Systrace series, primarily providing a brief introduction to SystemServer. It covers several important threads within SystemServer. Since Input and Binder are particularly critical, they are discussed separately and won’t be covered in detail here.

The purpose of this series is to view the overall operation of the Android system from a different perspective using Systrace, while also providing an alternative angle for learning the Framework. Perhaps you’ve read many articles about the Framework but can never remember the code, or you’re unclear about the execution flow. Maybe from Systrace’s graphical perspective, you can gain a deeper understanding.

Android Systrace Basics - Why 60 FPS?

Technical update — 2026-10-13: First published in 2019, this article uses 60 Hz devices to explain frame pacing. 60 FPS is not a fixed standard for every Android device. The universal 16.67 ms budget, mismatched-rate examples and power claims are corrected below, with updated tools available from Android 11 / API 30 and Android 12 / API 31.

This is the third article in the Systrace series, explaining why 60 FPS is constantly emphasized. Here, FPS describes the app’s content frame rate, while Hz describes display refresh rate; they measure different things. For further context, refer to: A New Smooth Experience: A Talk on 90Hz.

The purpose of this series is to view the overall operation of the Android system from a different perspective using Systrace, while also providing an alternative angle for learning the Framework. Perhaps you’ve read many articles about the Framework but can never remember the code, or you’re unclear about the execution flow. Maybe from Systrace’s graphical perspective, you can gain a deeper understanding.

This article separates frame rate from refresh rate, then discusses pacing, power and response latency. On 90 Hz and 120 Hz devices, content updates still need to work with display timing, but 60 FPS and 16.67 ms are no longer universal targets.

Android Systrace -- Series Article Index

Technical update — 2026-10-13: This page is dated 2019 and retains update records from earlier tutorials. The old Systrace tooling workflow is obsolete. Read historical screenshots, source code and experiments against the Android versions stated in each article; they do not describe every current implementation. Start with the Perfetto series below for current capture and analysis workflows.

As Systrace and Android changed, my earlier tutorials started to show their age. I had also learned to read more from a trace, which helped me solve performance problems. I wanted to write those things down and get better at explaining what I had learned. If the notes helped someone else too, all the better.

The purpose of this series is to view the overall operation of the Android system from a different perspective using Systrace, while also providing an alternative angle for learning the Framework. Perhaps you’ve read many articles about the Framework but can never remember the code, or you’re unclear about the execution flow. Maybe from Systrace’s graphical perspective, you can gain a deeper understanding.

Does the Android System Not Release Memory?

Besides the CPU, many users consider RAM size when buying a phone. Different RAM configurations come with different prices—but how much RAM do you actually need? How does Android manage its memory? Average users are often confused: How much RAM does this app use? How much does the system use? How does RAM affect my experience? And how much RAM should my next phone have?

A common question on Zhihu is: “Does the Android system not release memory?”. It’s not that the user doesn’t know the system releases memory, but rather they want to understand the mechanics to optimize their experience. In this article, I’ll address these user concerns. More technical details will be covered in later articles.

Some Thoughts on Android System Fluency

Version note — reviewed October 13, 2026: This article was written in 2018. Device examples, app experiences, and vendor opinions describe that period; the old hardware rankings and buying advice are outdated. Technical corrections and updates identify their Android versions. These are not new measurements of the named products.

I’ve long wanted to write about Android system fluency because it’s the most direct aspect of the user experience. The long-standing criticism that Android “gets laggier over time” still casts a shadow over the platform, and it’s a primary reason many users default to iPhone.

Because Google keeps Android open, different manufacturers produce devices with vastly different hardware, and app quality varies wildly. Consequently, fluency is affected by countless factors. It’s rarely just “the system isn’t optimized.” Often, two devices with the same OS but different SOCs offer completely different experiences.

I want to talk through some of the reasons Android can feel slow, so that the next time it happens, we don’t immediately blame the system. Perhaps uninstalling one app will turn out to be enough. Here are the areas I want to cover:

  1. Hardware
  2. System
  3. Applications
  4. The Optimization Loop

Ready? Let’s get started, and please join the discussion.

Zhihu: Save Your StartingWindow

It’s often said that the overall iOS experience is superior to Android. This is partly due to third-party software quality (iOS versions are often more polished) and partly due to Apple’s tight control over its ecosystem. To get on the App Store, you must pass rigorous reviews.

Today we look at the system-provided transition before app content is ready: Android’s StartingWindow and iOS’s Launch Screen. Neither is the same as an advertising Activity or business home screen rendered by the app.

I originally wrote that iOS required a single image. I was wrong about that. Xcode 6 release notes document XIB/Storyboard launch screens from iOS 8. They provide early feedback, not a guaranteed zero-delay timestamp. Older Android theme paths allowed customization, disabled previews, and translucent windows; behavior depends on the OS version.

2017 Best Recommendations - A Reward for Hard-Working Self

2017 slipped by before I knew it, and I haven’t updated the blog in ages. Partly, the more I learn, the less I feel I know, and I worry about misleading readers with a technical post. Partly, I’m just lazy. So I’ve decided this blog doesn’t have to be all technical articles. I’ll also write about things that matter to me and thoughts I want to keep. It’s a record for myself; if someone else finds it useful, even better. (Not that there are many readers…)

With 2017 just behind us, I wanted to share the things I enjoyed using or found helpful at work and at home. Maybe some will be useful to you in 2018. There are apps, hardware, books, and exercise equipment here. These are my picks; what worked for me may not work for you. Right, on to the list.

2017 Annual Best Recommendations - Reward Yourself for Hard Work

2017 has passed before we knew it. The blog hasn’t been updated for a while - one reason is that I increasingly realize how shallow my knowledge is and fear that writing about technical topics might mislead readers, and another reason is simply that I’ve been too lazy. Given these two reasons, I’ve decided that blog updates no longer need to be limited to technical articles - things I find meaningful, thoughts, and reflections will also be shared here. On one hand, it serves as my own record, and if it happens to help readers along the way, that would be even better (though there aren’t many readers anyway…).

Since 2017 has just passed, I feel it’s necessary to recommend to everyone the things that I found to be great experiences or very helpful for work and life in 2017 - perhaps you’ll need them in 2018. The recommendations include Apps, hardware, books, equipment, etc. It should be noted that these are things that brought me great help in 2017 - what works for me may not work for you. Without further ado, let’s get into it!

How to Calculate App Startup Time in Android?

Someone recently asked on Zhihu: “How to calculate APK startup time?”

“How can I use Python or direct ADB commands to calculate APK startup time? I want to measure the time from clicking the icon to the APK being fully started. For example, in a game, this would be from the icon tap to entering the login screen. Existing methods like adb shell am start -W provide ThisTime and TotalTime, but I’m unsure of the difference and they don’t seem to match visual reality.”

My colleague Guo Qifa and I answered different parts of the question. With his permission, I put our answers together here: partly so I could find them again, and partly to make them easier for other developers to find outside Zhihu.

Android App Launch Optimization: Implementation and Principles of DelayLoad (Part 2)

In the previous article, we tried the third DelayLoad approach. That article showed the code; here I want to follow what happens when it runs.

That takes us through several Android framework classes and Activity lifecycle methods.

I found tracing it quite fun: use the tools, add some debug code, and follow it one step at a time. Doing that helped me understand Activity startup better. I hope walking through it helps you too.

Android App Startup Optimization - DelayLoad Implementation and Principles (Part 1)

To make an Android app start faster, the main idea is to do less during startup. In practice, we usually reach for:

  1. Asynchronous Loading
  2. Delayed Loading (DelayLoad)
  3. Lazy Loading

If you have worked on startup optimization, you have probably used these already. Here I want to look at one DelayLoad implementation and why it behaves as it does. The code is simple, but following it takes us through Looper, Handler, MessageQueue, and VSYNC. I’ll also discuss the problems I ran into and some thoughts along the way.

RenderThread Workflow in Android hwui

Preface

These are my notes from learning how hwui’s RenderThread works in Android 5.0. I haven’t covered every detail; I wanted to trace the main flow so that, next time I hit a problem, I would know where to look.

I captured the first RenderThread Draw during app startup with Systrace, as shown below. It helps show the execution order on that thread, but the end of a DrawFrame slice is not the moment pixels appear on screen: GPU work, buffer consumption, composition, and presentation still matter. A StartingWindow may appear during startup; this CPU slice alone does not establish when it disappears.

Android Code Memory Optimization Suggestions - OnTrimMemory

Android Memory Optimization Series:

  1. Android Code Memory Optimization Suggestions - Android (Official)
  2. Android Code Memory Optimization Suggestions - Java (Official)
  3. Android Code Memory Optimization Suggestions - Android Resources
  4. Android Code Memory Optimization Suggestions - OnTrimMemory

onTrimMemory(int level), introduced in Android 4.0 (API 14), hints when an app should reduce unnecessary memory usage. Trimming caches can help the system retain more background processes, but does not guarantee process survival or a faster next return.

This article keeps the Q&A format to explain callback delivery, integration, and cleanup. Decide what to retain by resource purpose, and make sure the UI can recover what was released.

Android Code Memory Optimization Suggestions - Android Resources

Android Memory Optimization Series:

  1. Android Code Memory Optimization Suggestions - Android (Official)
  2. Android Code Memory Optimization Suggestions - Java (Official)
  3. Android Code Memory Optimization Suggestions - Android Resources
  4. Android Code Memory Optimization Suggestions - OnTrimMemory

I wrote this because understanding common memory problems before writing the code can save a lot of diagnosis later. We will look at Bitmaps, database queries, list reuse, and drawing: who creates each resource, what keeps it alive, and when it is no longer needed. Retention, repeated allocation, and leaks need different remedies.

Android Code Memory Optimization Suggestions - Android (Official)

Android Memory Optimization Series:

  1. Android Code Memory Optimization Suggestions - Android (Official)
  2. Android Code Memory Optimization Suggestions - Java (Official)
  3. Android Code Memory Optimization Suggestions - Android Resources
  4. Android Code Memory Optimization Suggestions - OnTrimMemory

For GC to reclaim unused objects, longer-lived owners must stop retaining references that are no longer needed. Reachability from GC roots matters, not whether another object holds a reference: a group of mutually referencing objects can still be collected when the whole group is unreachable. Becoming unreachable does not mean GC runs immediately or that the memory is immediately returned to the OS.

Memory management also includes bounded caches, resource ownership, and component lifecycles. Close files, connections, and native resources through their own APIs rather than waiting only for their Java wrappers to be collected.

Enabling Multi-Window Mode on Nexus 6 with Android M

On May 28, 2015, Google announced the Android M Developer Preview for devices including Nexus 6. This records that experience; the images below show the home screen and Easter egg.

Obsolete experimental procedure · Technical review (2026-10-13): Changing system properties to expose this switch is retained only as history for Nexus 6 (shamu) and the 2015 Android M preview. Google’s later announcement identifies the initial preview as MPZ44Q, but this article retained no device build-number output to verify its exact image. Modern multi-window development uses the versioned APIs discussed at the end, without these system modifications.

Android Tips Round-Up, Part 5

In the original Chinese post, I translated Dan Lew’s fifth and final Android tips round-up, which he published in May 2014. As in the earlier parts, I added explanations and notes of my own rather than translating word for word. I hope a few of these tools save you some trouble. Technical corrections and version updates are noted below.

Technical review — 2026-10-13: Old Support Library links now point to AndroidX. Storage, thumbnail generation, and app languages have version-specific updates. The side effects of clearing app data and yielding a database transaction are explained in their entries.

Android Tips Round-Up, Part 1

Reviewed 2026-10-13: This 2014 list focuses on Android’s View system. Most APIs remain valid. The old Html.fromHtml(String) overload was deprecated in API 24; the notes below add its replacement and correct the descriptions of cache directories, layout inflation, and reverse playback.

For the first Chinese post in this series, I translated Dan Lew’s Android Tips Round-Up. You may already know some of these small SDK tools; I’m writing them down in case a few are new to you. It isn’t a word-for-word translation. I use some of these classes myself, so I’ve added my own notes and explanations where I thought they would help. This English edition includes the API updates below.