Android 15 (API Level 35) is still in Beta 1 phase. Some changes and APIs might not be final and are still subject to change.
ApplicationStartInfo
Android 15 (API Level 35) introduces a class named ApplicationStartInfo
that contains the information of an application process's startup.
Inside ApplicationStartInfo
class, there are many valuable information concerning app's startup process that you might find useful for your use cases.
Properties​
Startup Reason​
You can find out what triggered your app's startup process by using getReason()
method. The method will return one of these reason codes:
Code | Description |
---|---|
START_REASON_ALARM | Process started due to alarm. |
START_REASON_BACKUP | Process started to run backup. |
START_REASON_BOOT_COMPLETE | Process started due to boot complete. |
START_REASON_BROADCAST | Process started due to broadcast received. |
START_REASON_CONTENT_PROVIDER | Process started due to access of ContentProvider. |
START_REASON_JOB | Process started to run scheduled job. |
START_REASON_LAUNCHER | Process started due to click app icon or widget from launcher. |
START_REASON_LAUNCHER_RECENTS | Process started from launcher recents. |
START_REASON_OTHER | Process started not for any of the listed reasons. |
START_REASON_PUSH | Process started due to push message. |
START_REASON_SERVICE | Process service started. |
START_REASON_START_ACTIVITY | Process started due to Activity started for any reason not explicitly listed. |
Startup State​
You can retrieve the current state of the startup process by using getStartupState()
method. Depending on the state of the startup, the information that an ApplicationStartInfo
instance has will be different.
Code | Description |
---|---|
STARTUP_STATE_STARTED | State indicating process startup has started. Some information is available in ApplicationStartInfo and more will be added. |
STARTUP_STATE_ERROR | State indicating process startup has failed. Startup information in ApplicationStartInfo is incomplete, but no more will be added. |
STARTUP_STATE_FIRST_FRAME_DRAWN | State indicating process startup has made it to first frame draw. Startup information in ApplicationStartInfo is complete with potential exception of fully drawn timestamp which is not guaranteed to be set. |
Startup Type​
You can also retrieve the state of the app during startup by using getStartType()
method. The method will return one of these type codes:
Code | Description |
---|---|
START_TYPE_COLD | Process started from scratch. |
START_TYPE_HOT | Process brought back to foreground. |
START_TYPE_UNSET | Start type not yet set. |
START_TYPE_WARM | Process retained minimally SavedInstanceState. |
Note that the startup type value will be available if the startup state is STARTUP_STATE_FIRST_FRAME_DRAWN
. For other states, the value is not guaranteed.
Startup Launch Mode​
Launch mode is an instruction on how the activity should be launched. Launch modes work in conjunction with activity flags in Intent objects to determine how an activity should handle an intent.
We can retrieve app's launch mode by using getLaunchMode()
method. This will method will return one of these launch modes:
Code | Description |
---|---|
LAUNCH_MODE_STANDARD | Default. The system always creates a new instance of the activity in the target task and routes the intent to it. |
LAUNCH_MODE_SINGLE_TOP | If an instance of the activity already exists at the top of the target task, the system routes the intent to that instance through a call to its onNewIntent() method, rather than creating a new instance of the activity. |
LAUNCH_MODE_SINGLE_INSTANCE | The system creates the activity at the root of a new task or locates the activity on an existing task with the same affinity. If an instance of the activity already exists and is at the root of the task, the system routes the intent to existing instance through a call to its onNewIntent() method, rather than creating a new one. |
LAUNCH_MODE_SINGLE_TASK | Same as "singleTask", except that the system doesn't launch any other activities into the task holding the instance. The activity is always the single and only member of its task. |
LAUNCH_MODE_SINGLE_INSTANCE_PER_TASK | The activity can only be running as the root activity of the task, the first activity that created the task, and therefore there will only be one instance of this activity in a task; but activity can be instantiated multiple times in different tasks. |
Startup Timestamps​
We can also retrieve several timestamps that are relevant to app's startup process by using getStartupTimestamps()
method. This method will return a Map<Integer, Long>
type where the map key is one of the timestamp code value below and the map value is the timestamp (clock monotonic).
Value | Code | Description |
---|---|---|
0 | START_TIMESTAMP_LAUNCH | Clock monotonic timestamp of launch started. |
1 | START_TIMESTAMP_FORK | Clock monotonic timestamp of process fork. |
2 | START_TIMESTAMP_APPLICATION_ONCREATE | Clock monotonic timestamp of Application onCreate called. |
3 | START_TIMESTAMP_BIND_APPLICATION | Clock monotonic timestamp of bindApplication called. |
4 | START_TIMESTAMP_FIRST_FRAME | Clock monotonic timestamp of first frame drawn. |
5 | START_TIMESTAMP_FULLY_DRAWN | Clock monotonic timestamp of reportFullyDrawn called by application. |
6 | START_TIMESTAMP_INITIAL_RENDERTHREAD_FRAME | Clock monotonic timestamp of initial renderthread frame. |
7 | START_TIMESTAMP_SURFACEFLINGER_COMPOSITION_COMPLETE | Clock monotonic timestamp of surfaceflinger composition complete. |
Whether App Was Previously Force-Stopped​
ApplicationStartInfo
class also has wasForceStopped()
method that returns true if the current startup process is the app's first process launch since it was force stopped for some reason.
Basic Usages​
Getting Historical Startup Informations​
We can retrieve our application's most recent startup process by using getHistoricalProcessStartReasons()
method inside ActivityManager
class:
import android.app.ActivityManager
import android.content.Context
import android.util.Log
val activityManager = context.getSystemService(ActivityManager::class.java)
val applicationStartInfos = activityManager.getHistoricalProcessStartReasons(10)
applicationStartInfos.forEach {
Log.i("reason", it.reason.toString())
Log.i("state", it.startupState.toString())
Log.i("type", it.startType.toString())
Log.i("launchMode", it.launchMode.toString())
Log.i("startupTimestamps", it.startupTimestamps.toString())
Log.i("wasForceStopped", it.wasForceStopped().toString())
}
Getting Current Startup Information​
We can retrieve our application's current startup process by using addApplicationStartInfoCompletionListener()
method inside ActivityManager
class.
In the simple example below, we add the listener inside the activity's onCreate()
and remove them in onDestroy()
method:
package com.hanmajid.androidnotebook
import android.annotation.SuppressLint
import android.app.ActivityManager
import android.app.ApplicationStartInfo
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import com.hanmajid.androidnotebook.ui.theme.AndroidNotebookTheme
import java.util.function.Consumer
@SuppressLint("NewApi")
class MainActivity : ComponentActivity() {
private lateinit var activityManager: ActivityManager
private lateinit var applicationStartInfoCompletionListener: Consumer<ApplicationStartInfo>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityManager = getSystemService(ActivityManager::class.java)
applicationStartInfoCompletionListener = Consumer {
Log.i("reason", it.reason.toString())
Log.i("state", it.startupState.toString())
Log.i("type", it.startType.toString())
Log.i("launchMode", it.launchMode.toString())
Log.i("startupTimestamps", it.startupTimestamps.toString())
Log.i("wasForceStopped", it.wasForceStopped().toString())
}
activityManager.addApplicationStartInfoCompletionListener(
mainExecutor,
applicationStartInfoCompletionListener,
)
setContent {
AndroidNotebookTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Text("Hello Android Notebook!")
}
}
}
}
override fun onDestroy() {
activityManager.removeApplicationStartInfoCompletionListener(
applicationStartInfoCompletionListener,
)
super.onDestroy()
}
}