How to accurately measure the startup time of Activity and Fragment in Android apps
In Android application development, understanding the startup time of each activity and Fragment is critical to performance optimization. This article will introduce several ways to accurately measure the startup time of your Activity and Fragment and provide hands-on steps to help improve your application's responsiveness and user experience.
1. Use the adb shell am start -W command
adb shell am start -W
Commands are a simple and straightforward way to measure the startup time of an activity. This command starts the specified activity and outputs the relevant time data. Here is how to use the command and how to resolve common errors.
1.1 Command
adb shell am start -W -n <>/<>
1.2 Output explanation
-
ThisTime
: The current startup time of the activity. -
TotalTime
: Total time from the start of the app to the current activity. -
WaitTime
: System waiting time.
1.3 Start the Activity and pass parameters
use-e
Options pass parameters
To pass key-value pair parameters, you can use-e
Options.-e
Options are used to pass a string key-value pair to the targetActivity
. If there are multiple key-value pairs that need to be passed, multiple can be used-e
Options.
Command format
adb shell am start -n <>/<> -e <key1> <value1> -e <key2> <value2> ...
-
-n <>/<>
: Specify the one to startActivity
。 -
-e <key> <value>
: Specify the parameters to be passed and their corresponding values.key
is the name of the parameter,value
is the value of the parameter.
Example
The application package name is, to start
Activity
yes, and two parameters need to be passed:
user_id
andsession_token
. The following commands can be used:
adb shell am start -n / -e user_id 12345 -e session_token abcdef123456
Passing multiple data types
In addition to using-e
Options pass string parameters, and you can also use the following options to pass parameters of other data types:
-
-e
: Pass string key-value pairs. -
-en
: Pass integer key-value pairs. -
-ef
: Pass the floating point key value pair. -
-el
: Pass a long integer key-value pair. -
-eb
: Pass a boolean key-value pair. -
-eia
: Pass integer array key-value pairs. -
-efa
: Pass the key-value pair of floating point array.
Example
If you need to pass an integer and a boolean parameter, you can use the following command:
adb shell am start -n / -en max_retries 5 -eb is_active true
In this example,max_retries
is an integer parameter,is_active
is a boolean parameter.
Parses passed parameters
Here I amActivity
In, can be passedIntent
Object to get the passed parameters. For example:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { (savedInstanceState); setContentView(.activity_main); Intent intent = getIntent(); String userId = ("user_id"); String sessionToken = ("session_token"); // Use the obtained parameters } }
For other data types parameters, the correspondingIntent
Methods to obtain, for examplegetIntExtra
、getBooleanExtra
wait.
By using-e
and related options, which can easily pass parameters toActivity
, simulate various conditions during testing and debugging. This makes it more efficient and flexible to verify the different functions of the application.
1.4 Common Errors and Solutions
1.4.1 : Permission Denial
error message:
: Permission Denial: starting Intent { act= cat=[] flg=0x10000000 cmp=/.MainActivity mCallingUid=2000 } from null (pid=29129, uid=2000) not exported from uid 10600
reason: This error occurs when the activity attempted to start is not configured for export or does not have appropriate permissions.
Solution:
Revise: Make sure the target activity is configured as
exported="true"
, so that external calls can be allowed.
<activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="" /> <category android:name="" /> </intent-filter> </activity>
Check permissions: Make sure the app has the appropriate permissions, or try to useadb
The command runs with root permissions.
1.4.2 : Permission Denial: starting Intent { act= cat=[] flg=0x10000000 cmp=/.MainActivity } from null (pid=29219, uid=2000) not exported from uid 10600
error message:
: Permission Denial: starting Intent { act= cat=[] flg=0x10000000 cmp=/.MainActivity mCallingUid=2000 } from null (pid=29219, uid=2000) not exported from uid 10600
reason: This error usually indicates that the target activity is not properly configured for export or startup. Even if the Activity is exported, it may not be set correctlyintent-filter
orlaunchMode
。
Solution:
Configurationintent-filter
: Make sure the activity is configured correctlyintent-filter
, if needed, it should includeMAIN
andLAUNCHER
Actions and categories.
<activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="" /> <category android:name="" /> </intent-filter> </activity>
Check startup mode: If the activity is internally active or does not need to be started externally, consider using other methods to test, or set upandroid:exported="true"
Ensure external calls.
1.4.3 ActivityNotFoundException
error message:
: Unable to find explicit activity class {/.MainActivity}; have you declared this activity in your ?
reason: This error indicates that the system cannot find the specified activity. This may be becauseThe Activity is not correctly declared, or the package and class names are incorrect.
Solution:
examine: Make sure the target activity is already there
Correctly declared in.
<activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="" /> <category android:name="" /> </intent-filter> </activity>
Check package name and class name: make sureadb
The package name and class name in the command are consistent with the actual declaration.
2. Manually record the startup time
To obtain more accurate data, the startup time of each activity can be manually recorded in the code. This method can provide data that is more in line with the actual usage scenario.
2.1 Code
In each activityonCreate
Record the startup time in the method:
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { long startTime = (); (savedInstanceState); setContentView(.activity_main); long elapsedTime = () - startTime; (TAG, "Activity startup time: " + elapsedTime + " ms"); } }
2.2 Capture logs
useadb logcat
Capture startup time log:
adb logcat -s MainActivity
3. Use the interface to record the activity startup time
In order to automatically record the startup time of each activity and avoid repeated writing of code in each activity, you can useinterface.
3.1 Use annotations to mark Chinese names
First, we create a custom annotation to mark the Chinese name of the Activity.
import ; import ; @Retention() public @interface ChineseName { String value(); }
Then, use this annotation on each Activity class.
import ; import ; @ChineseName("My Activity Chinese name") public class MyActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { (savedInstanceState); // Activity Other code... } }
3.2 Create a life cycle callback class
accomplish
Create an implementationThe class of the interface to record the startup time of each activity and use reflection to get the Chinese name.
import ; import ; import ; import ; public class ActivityLifecycleHandler implements { private static final String TAG = "ActivityLifecycleHandler"; @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { long startTime = (); ().getDecorView().post(() -> { long endTime = (); long duration = endTime - startTime; String activityName = getChineseName(activity); (TAG, activityName + " creation time: " + duration + " ms"); }); } @Override public void onActivityStarted(Activity activity) {} @Override public void onActivityResumed(Activity activity) {} @Override public void onActivityPaused(Activity activity) {} @Override public void onActivityStopped(Activity activity) {} @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) {} @Override public void onActivityDestroyed(Activity activity) {} private String getChineseName(Activity activity) { ChineseName annotation = ().getAnnotation(); if (annotation != null) { return (); } else { return ().getSimpleName(); } } }
3.3 Registering Lifecycle Callback
existApplication
Register lifecycle callbacks in the class:
public class MyApp extends Application { @Override public void onCreate() { (); registerActivityLifecycleCallbacks(new AppLifecycleHandler()); } }
3.4 Modification
Make sure to be inSpecify custom
Application
kind:
<application android:name=".MyApp" ...> ... </application>
3.5 Continuous log output
useadb logcat
The command captures the log output of startup time.
adb logcat -s AppLifecycleHandler
Every time you switch a page or start a new activity, the console will output a log message similar to the following:
07-04 14:23:45.123 1234-1234/ D/AppLifecycleHandler: MainActivity startup time: 150 ms
07-04 14:23:47.567 1234-1234/ D/AppLifecycleHandler: SettingsActivity startup time: 180 ms
07-04 14:23:47.567 1234-1234/ D/AppLifecycleHandler: My Activity Chinese name startup time: 180 ms
These logs show the startup time for each activity. Through this data, application performance can be analyzed and optimized.
4. Record all Fragment startup times
Likewise, it can be covered byFragment
Lifecycle method to recordFragment
start time.
4.1 Use annotations to mark Chinese names
Similarly, forFragment
Use the sameChineseName
annotation.
import ; @ChineseName("My Fragment Chinese name") public class MyFragment extends Fragment { // Fragment code...}
4.2 Override Fragment Lifecycle Method
First, create a base classBaseFragment
,coverFragment
ofonCreateView
Method to record eachFragment
start time.
import ; import ; import ; import ; import ; import ; import ; public class FragmentLifecycleHandler extends { private static final String TAG = "FragmentLifecycleHandler"; @Override public void onFragmentViewCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull View v, @Nullable Bundle savedInstanceState) { long startTime = (); ().post(() -> { long endTime = (); long duration = endTime - startTime; String fragmentName = getChineseName(f); (TAG, fragmentName + " view creation time: " + duration + " ms"); }); } private String getChineseName(Fragment fragment) { ChineseName annotation = ().getAnnotation(); if (annotation != null) { return (); } else { return ().getSimpleName(); } } }
4.3 Complete code example
AllFragment
Class inherits fromBaseFragment
。
public class MyFragment extends BaseFragment { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return (.fragment_my, container, false); } }
4.4 Continuous log output
useadb logcat
The command captures the log output of startup time.
adb logcat -s FragmentLifecycle
Each loadFragment
When the console outputs log information similar to the following:
07-04 14:23:45.123 1234-1234/ D/FragmentLifecycle: MyFragment startup time: 120 ms
These logs show eachFragment
start time. Through this data, application performance can be analyzed and optimized.
5. Use third-party tools
In addition to custom implementations, there are many third-party tools and libraries that can help measure and optimize the startup time of your application. Here are some commonly used tools and libraries:
5.1 Alibaba Cloud Mobile Monitoring
Alibaba Cloud Mobile MonitoringProvides a comprehensive performance monitoring solution, including startup time, crash analysis, user behavior analysis and other functions.
Steps to use:
1. Integration SDK: Create a project in the Alibaba Cloud console and download the Alibaba Cloud Mobile Monitoring SDK. Integrate the SDK into Android apps. For specific steps, please refer to the official Alibaba Cloud documentation.
2. Configure performance monitoring: Configure performance monitoring in Alibaba Cloud console, including startup time monitoring and user behavior analysis.
3. View performance data: Log in to the Alibaba Cloud console and visit the Alibaba Cloud Mobile Monitoring section to view the application's startup time, crash reports, and user behavior analysis data.
5.2 Tencent Cloud Mobile Analytics
Tencent Cloud Mobile AnalysisIt provides comprehensive application performance monitoring and user behavior analysis functions, which are suitable for application developers in China.
Steps to use:
1. Integration SDK:
Integrated SDK:
- Create a project in Tencent Cloud Console and download Tencent Cloud Mobile Analysis SDK.
- Integrate the SDK into Android apps. For specific steps, please refer to Tencent Cloud's official documentation.
Configuration performance monitoring:
- Configure performance monitoring and user behavior analysis functions in Tencent Cloud console.
View performance data:
- Log in to Tencent Cloud Console and visit the Tencent Cloud Mobile Analysis section to view the application's startup time, crash reports, and user behavior data.
5.3 Baidu Mobile Statistics
Baidu Mobile StatisticsIt provides application performance monitoring and user behavior analysis functions to help developers understand application performance and user behavior.
Steps to use:
-
Integrated SDK:
- Create a project in Baidu Statistics console and download the Baidu Mobile Statistics SDK.
- Integrate the SDK into Android apps. For specific steps, please refer toBaidu statistics official document.
-
Configuration performance monitoring:
- Configure performance monitoring functions and user behavior analysis in Baidu Statistics console.
-
View performance data:
- Log in to Baidu Statistics Console and visitBaidu Mobile StatisticsIn section, you can view the application startup time, crash reports, and user behavior data.
5.4 Android Profiler
Android ProfilerIt is a set of tools provided by Android Studio that can help monitor application performance in real time, including startup time, memory usage, CPU usage, etc.
Steps to use:
-
Start Android Studio Profiler:
- Open Android Studio and run the app.
- choose
View
>Tool Windows
>Profiler
, and then select the application process.
-
Monitor application startup time:
- In the Profiler window, select
CPU
view. When the application is started, the Profiler records it - CPU usage during startup can help understand startup time and its bottlenecks.
- In the Profiler window, select
-
Analyze performance data:
- Profiler provides a timeline view and detailed performance metrics to help identify performance issues during startup.
- You can view the activity lifecycle, memory usage, and CPU usage of your application to find an entry point for optimization.
5.5 LeakCanary
LeakCanaryIt is an open source memory leak detection library that can help detect and repair memory leaks, thereby indirectly optimizing application startup time and overall performance.
Steps to use:
Integration LeakCanary:
existAdd LeakCanary dependencies to the file:
debugImplementation ':leakcanary-android:2.10'
Automatically detect memory leaks:
LeakCanary automatically monitors the application's memory leak and issues a warning if a leak is found.
Fix memory leaks:
Identify and fix memory leaks to improve application performance and startup speed according to reports provided by LeakCanary. Note Firebase Performance Monitoring
Firebase Performance MonitoringIt is a performance monitoring tool provided by Google, which can help developers monitor the performance of applications, including startup time, network request time, etc. However, because some Google services may be subject to access restrictions in mainland China, the functionality and data transfer of Firebase Performance Monitoring may be affected.
Official address:
Firebase Performance Monitoring Official Documentation
Summarize
Using these third-party tools, you can more comprehensively monitor and optimize your application startup time and overall performance. Three-party libraries and Android Profiler provide real-time performance data and analysis capabilities, while LeakCanary can help detect and fix memory leaks. The combination of these tools and libraries can help improve the user experience and performance of your application.
This is the article about accurately measuring the startup time of Activity and Fragment in Android applications. For more information about Android Activity and Fragment, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!