Applicable to android app

Android Application Launch explained: from Zygote to your Activity.onCreate()

Apr 30, 2018 · 6 min read

This article explains how Android launches your application when a user clicks an app icon. The Android system does a lot of heavy lifting behind the curtains to make your launch activity visible to a user. This article covers this process in detail by highlighting the important phases and call sequences.

Android applications are unique in two ways:

  1. Multiple Entry points: Android apps are composed of different components and they can invoke the components owned by other apps. These components roughly correspond to multiple entry points for any application. Hence, they differ from traditional applications which have a single entry point like main() method.
  2. Own Little World: Every Android application lives in its own world, it runs in a separate process, it has its own Dalvik VM instance and is assigned a unique user ID.

When does Android process start?

An Android process is started whenever it is required.

Any time a user or some other sys t em component requests a component (could be a service, an activity or an intent receiver) that belongs to your application be executed, the Android system spins off a new process for your app if it’s not already running. Generally processes keep running until killed by the system. Application processes are created on demand and a lot of things happen before you see your application’s launch activity up and running.

Every app runs in its own process: By default, every Android app runs in its own Android process which is nothing but a Linux process which gets one execution thread to start with. For example, when you click on a hyper-link in your e-mail, a web page opens in a browser window. Your mail client and the browser are two separate apps and they run in their two separate individual processes. The click event causes Android platform to launch a new process so that it can instantiate the browser activity in the context of its own process. The same holds good for any other component in an application.

Zygote : Spawning new life, new process

Let’s step back for a moment and have a quick look on system start-up process. Like the most Linux based systems, at startup, the boot loader loads the kernel and starts the init process. The init then spawns the low level Linux processes called “daemons” e.g. android debug daemon, USB daemon etc. These daemons typically handle the low level hardware interfaces including radio interface.

Init process then starts a very interesting process called ‘ Zygote ’.

As the name implies it’s the very beginning for the rest of the Android application. This is the process which initializes a very first instance of Dalvik virtual machine. It also pre-loads all common classes used by Android application framework and various apps installed on a system. It thus prepares itself to be replicated. It stats listening on a socket interface for future requests to spawn off new virtual machines (VM)for managing new application processes. On receiving a new request, it forks itself to create a new process which gets a pre-initialized VM instance.

After zygote, init starts the runtime process.

The zygote then forks to start a well managed process called system server. System server starts all core platform services e.g activity manager service and hardware services in its own context.

Читайте также:  Гонки сега для андроид

At this point the full stack is ready to launch the first app process — Home app which displays the home screen also known as Launcher application.

When a user clicks an app icon in Launcher …

The click event gets translated into startActivity(intent) and it is routed to ActivityManagerService via Binder IPC. The ActvityManagerService performs multiple steps

  1. The first step is to collect information about the target of the intent object. This is done by using resolveIntent() method on PackageManager object. PackageManager.MATCH_DEFAULT_ONLY and PackageManager.GET_SHARED_LIBRARY_FILES flags are used by default.
  2. The target information is saved back into the intent object to avoid re-doing this step.
  3. Next important step is to check if user has enough privileges to invoke the target component of the intent. This is done by calling grantUriPermissionLocked() method.
  4. If user has enough permissions, ActivityManagerService checks if the target activity requires to be launched in a new task. The task creation depends on Intent flags such as FLAG_ACTIVITY_NEW_TASK and other flags such as FLAG_ACTIVITY_CLEAR_TOP.
  5. Now, it’s the time to check if the ProcessRecord already exists for the process.If the ProcessRecord is null, the ActivityManager has to create a new process to instantiate the target component.

As you saw above many things happen behind the scene when a user clicks on an icon and a new application gets launched. Here is the full picture :

There are three distinct phases of process launch :

  1. Process Creation
  2. Binding Application
  3. Launching Activity / Starting Service / Invoking intent receiver …

ActivityManagerService creates a new process by invoking startProcessLocked() method which sends arguments to Zygote process over the socket connection. Zygote forks itself and calls ZygoteInit.main() which then instantiates ActivityThread object and returns a process id of a newly created process.

Every process gets one thread by default. The main thread has a Looper instance to handle messages from a message queue and it calls Looper.loop() in its every iteration of run() method. It’s the job of a Looper to pop off the messages from message queue and invoke the corresponding methods to handle them. ActivityThread then starts the message loop by calling Looper.prepareLoop() and Looper.loop() subsequently.

The following sequence captures the call sequence in detail —

The next step is to attach this newly created process to a specific application. This is done by calling bindApplication() on the thread object. This method sends BIND_APPLICATION message to the message queue. This message is retrieved by the Handler object which then invokes handleMessage() method to trigger the message specific action — handleBindApplication(). This method invokes makeApplication() method which loads app specific classes into memory.

This call sequence is depicted in following figure.

Launching an Activity:

After the previous step, the system contains the process responsible for the application with application classes loaded in process’s private memory. The call sequence to launch an activity is common between a newly created process and an existing process.

The actual process of launching starts in realStartActivity() method which calls sheduleLaunchActivity() on the application thread object. This method sends LAUNCH_ACTIVITY message to the message queue. The message is handled by handleLaunchActivity() method as shown below.

Assuming that user clicks on Video Browser application. the call sequence to launch the activity is as shown in the figure.

The Activity starts its managed lifecycle with onCreate() method call. The activity comes to foreground with onRestart() call and starts interacting with the user with onStart() call.

Thanks for reading through 🙌🏼. If you found this post useful, please applaud using the 👏 button and share it through your circles.

This article was initially published as two part series (Part 1 and Part 2) on my blog ./ mult-core-dump in 2010. These articles have been cited in multiple documents including the very famous Introduction to the Android Graphics Pipeline

Источник

Keeping your Android application running when the device wants to sleep (Updated for Android Pie)

Updated January 2020 to include detail about Android Pie.

Читайте также:  Торговый счет для андроид

Since the introduction of doze mode in Android Marshmallow we have seen a number of enterprise use cases where customers want to ensure their application continues to run even though the device wants to enter a power saving mode. It is assumed the reader is familiar with doze mode and the other changes made in Android Oreo and Pie related to background services, at least at a high level.

From a consumer point of view, getting maximum battery life out of a device is frequently an ever-present consideration, so much so that a slew of snake oil “task manager” and “task killer” applications formerly gained popularity to prevent background apps but in recent Android releases Google has taken a more aggressive approach to what apps can do in the background.

Enterprise applications are written primarily to enhance user efficiency; battery consumption will always be a consideration but may be secondary or tertiary to application responsiveness or performance.

The goal of this blog is to explain your options as an application developer to give you the most control over your device’s power management and what you can do to ensure your application is always available to your users.

There are two fundamental reasons people might not want the device to enter a power saving mode:

  • The application should be available to respond to network requests, for example a push message. Often Firebase Cloud Messaging (FCM) is not a suitable option for customers because the device is behind a firewall or does not have GMS services available.
  • The application needs to do work continually and it is not acceptable for the Android OS to kill the application’s background services.

Before diving into the detail, it is necessary to understand the concepts around Android power management:

Wake Locks

Wake locks are an Android concept designed to allow an application to indicate that it wants to have the device stay on, for example the YouTube application would take a FULL_WAKE_LOCK to prevent the screen turning off whilst the user is watching a video. A wake lock can control the status of the CPU, Screen and hardware Keyboard backlight but all but one type of wake lock can be cancelled by the end user simply by pressing the power key. Since only PARTIAL_WAKE_LOCKs persist when the user presses the power key the remainder of this blog will be concerned exclusively with those, where the CPU continues running but the screen and hardware keyboard backlight is allowed to turn off.

Android documentation is available for the wake lock definition as well as methods to acquire and release wake locks.

Any application requiring a wake lock must request the android permission:

You can detect any wake locks being held by applications on your device through adb:

The following screenshot shows a single wake lock is on the device, it is a partial wake lock and has been given the tag ‘WakeLockExampleAppTag1’ by the application which created it:

Wake lock acquired.png

Partial wake locks will be released either when the application which created it calls release(), or the lock was only acquired for a specified time. Note that wake locks will be automatically released when the device enters doze mode unless battery optimization is disabled for the application which acquired the lock (see later)

Whilst this blog is concerned primarily with Android Marshmallow, you may notice that earlier Zebra devices’ WiFi service gains its own partial wake lock, even when the WiFi policy is set to not «keep WiFi awake when the device is sleeping». You can see any wake lock using the technique described above and should bear this in mind if wondering why your device is not sleeping when expected on earlier devices e.g. MC40.

Читайте также:  Build android emulator image

WiFi Locks

WiFi locks are only applicable to Android Nougat devices and below (Marshmallow, Lollipop etc). From Android Oreo onward the WiFi will always be on when the device is sleeping.

WiFi locks allow an application to keep the WLAN radio awake when the user has not used the device in a while, they are frequently used in conjunction with wake locks since any application doing work in the background would likely need WLAN connectivity (e.g. downloading a large file)

Android documentation for the WifiLock is here and the documentation on how to acquire a WiFi lock is here.

As stated in the official docs, WifiLocks cannot override the user-level “Wifi-Enabled” setting, nor Airplane Mode. For Zebra devices, we can extend this to WifiLocks not being able to override the Wi-Fi Enable / Disable setting of the WiFi CSP

Some other special considerations for Zebra devices:

  • Out of the box, older Zebra devices come pre-loaded with the AppGallery client. AppGallery will be holding its own WifiLock lock and since the radio is only allowed to turn off when no WifiLocks are held, the radio will not turn off by default (until the device enters doze mode). AppGallery’s lock is defined as follows:
    • WifiLock
  • You can disable AppGallery in a number of ways:
    • Using the MX AccessManager whitelist feature
    • Using the MX ApplicationManager to disable the application
    • Using Enterprise Home Screen’s preference
    • Disabling the application manually under Settings —> Apps —> AppGallery —> App info

Note that the current package name is com.rhomobile.appgallery but that may change in the future.

  • Zebra devices also have an additional “Sleep Policy” parameter as part of the MX Wifi Manager
    • You can set the sleep policy via the Settings UI: Settings —> Wi-Fi —> (Menu) Advanced —> “Keep Wi-Fi on during sleep”. The values are:
      • Always (the WiFi radio will not turn off when the device sleeps)
      • ‘Only when plugged in’ (the WiFi radio will not turn off provided the device is connected to power)
      • Never (the WiFi radio will be allowed to turn off when the device sleeps)
    • The sleep policy does not hold a separate WiFi lock, it is configuring the WiFi policy and is reflected in the mSleepPolicy value.
    • The default value of the sleep policy will vary from device to device. As a general rule, devices running Marshmallow or earlier will have this value set to ‘Never’ and devices running Nougat or later will set this value to ‘Always’ but there will be exceptions (notably the TC8000, a Lollipop device, defaults to ‘Always’).
      • For a consistent staging experience across all devices it is recommended to use StageNow’s WifiSleepPolicy parameter
    • The device will only turn WiFi off during standby if there are no WiFi locks and it is allowed to do so according to the WiFi sleep policy
  • When the device receives a network request over WiFi, the device obviously needs to do some processing to handle the message. Although this requires hardware support from the WiFi stack and processor, recent Zebra devices will be able to wake the processor to perform the required packet handling. If more than simple processing is required when packets are received it may be prudent to also acquire a wake lock for the duration of that processing. This is true of all Android Marshmallow or later devices.

You can detect any wifi locks being held by applications on your device through adb:

The following screenshot shows a single wifi lock is on the device (in blue) and is given the tag ‘WifiLockExampleAppTag1’ by the application which created it. Highlighted in green is the mSleepPolicy variable which can be used to determine the WiFi sleep policy, here 0 is ‘Never’ keep WiFi on during sleep but a value of 2 would indicate ‘Always’ keep WiFi on during sleep.:

Источник

Оцените статью