Overview

App Performance Management (APM) of HUAWEI AppGallery Connect provides minute-level app performance monitoring capabilities. With the APM SDK, you can quickly integrate APM without coding. APM allows you to view and analyze app performance data collected by APM in AppGallery Connect to comprehensively understand the performance features of your app, helping you quickly and accurately rectify possible performance problems and continuously improve user experience.

What You Will Create

In this codelab, you will build an app that integrates APM. In addition, you can manually trigger network requests to test whether APM can monitor network performance and learn how to view and analyze app performance problems.

What You Will Learn

Development Environment and Skill Requirements

Device Requirements

A device running Android 4.4 or a later version

To integrate AppGallery Connect APM, you must complete the following preparations:

For details, please refer to Integration Preparations.
  1. Sign in to AppGallery Connect and click My projects.
  2. Click your project card and select the app for which you want to enable APM from the app drop-down list on the top.
  3. Go to Quality > APM. If APM is not enabled, click Enable.

Enabling APM

  1. Add the AppGallery Connect plugin of 1.6.0.300 or a later version to the project-level build.gradle file in Android Studio:
    buildscript { repositories { // Add the Maven repository. maven { url 'https://developer.huawei.com/repo/' } } dependencies { // To benefit from the latest APM features, update your Android gradle plugin. // Dependency to version 3.5.3 or later. classpath 'com.android.tools.build:gradle:3.5.3' // if you had add agc plugin dependence, please update the version to 1.6.2.300. if not, please add agc plugin dependence classpath 'com.huawei.agconnect:agcp:1.6.2.300' } }
  2. Enable APM in the app-level build.gradle file in Android Studio:
    apply plugin: 'com.android.application' // Apply the AppGallery Connect plugin. apply plugin: 'com.huawei.agconnect'**enableAPMS**nabl**true**S to true, indicating that the APMS plugin has taken effect. agcp { enableAPMS true } android { //.. }

Integrating the APM SDK

If you are using Android Studio, you need to integrate the APM SDK into your Android Studio project before development.

  1. Sign in to AppGallery Connect and click My projects.
  2. Click your project card and select an app from the app drop-down list on the top.
  3. Go to Project settings > General information, and click agconnect-services.json under App information to download the configuration file.
  4. Copy the agconnect-services.json file to your app's module directory.
  5. Open the app-level build.gradle file and add the following code to integrate the APM SDK:
    dependencies { // Add the APM SDK library dependency. implementation 'com.huawei.agconnect:agconnect-apms:1.5.2.307' }
  6. Find the app-level proguard-rules.pro file (confusion configuration file), and add the following items:
    -keep class com.huawei.agconnect.apms.**{*;} -dontwarn com.huawei.agconnect.apms.** -keep class com.hianalytics.android.**{*;} -keep class com.huawei.updatesdk.**{*;} -keep class com.huawei.hms.**{*;} -keep interface com.huawei.hms.analytics.type.HAEventType{*;} -keep interface com.huawei.hms.analytics.type.HAParamType{*;} -keepattributes Exceptions, Signature, InnerClasses, LineNumberTable
  7. Click Sync Now to synchronize the configuration.
  8. Compile and run your app. By now, the APM SDK has been integrated. You can then view app performance data in AppGallery Connect.

(Optional sections are designed to help you better understand the APM service.)
You can create a layout page in your Android Studio project and add nine buttons, as shown in the following figure.

For details about the layout, please refer to the following code in the activity_main.xml file:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <LinearLayout android:layout_width="300dp" android:layout_height="wrap_content" android:gravity="center" android:orientation="vertical"> <Button android:id="@+id/btn_network" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="SEND NETWORK REQUEST" /> <Button android:id="@+id/enable_apms_off" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="APMS COLLECTION OFF" /> <Button android:id="@+id/enable_apms_on" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="APMS COLLECTION ON" /> <Button android:id="@+id/enable_apms_anr_off" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="APMS ANR MONITOR OFF" /> <Button android:id="@+id/enable_apms_anr_on" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="APMS ANR MONITOR ON" /> <Button android:id="@+id/custom_normal_event" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="SEND CUSTOM EVENT" /> <Button android:id="@+id/custom_normal_event_by_annotation" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="SEND CUSTOM EVENT BY ANNOTATION" /> <Button android:id="@+id/custom_network_event" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="SEND CUSTOM NETWORK EVENT" /> <Button android:id="@+id/anr_test" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="TRIGGER ANR" /> </LinearLayout> </LinearLayout>

You can manually trigger a network request and check whether the network performance data is normal on the performance management page of APM.

  1. Create the HttpUtil.java file, add the following code, and define the request sending method:
    static private String URL = "https://developer.huawei.com/consumer/en/"; static private MediaType MEDIATYPE = MediaType.parse("text/x-markdown; charset=utf-8"); static private String REQUESTBODY = "apms http request test"; static public void oneRequest() { OkHttpClient okHttpClient = new OkHttpClient(); Request request = new Request.Builder() .url(URL) .post(RequestBody.create(MEDIATYPE, REQUESTBODY)) .build(); okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.d("apmsAndroidDemo", "onFailure: " + e.toString()); } @Override public void onResponse(Call call, Response response) throws IOException { Log.d("apmsAndroidDemo", "onResponse: Success"); } }); }
  2. In the onCreate method in the main activity, call the oneRequest method to report a network event when the SEND NETWORK REQUEST button is tapped.
    Button sendNetworkRequestBtn = findViewById(R.id.btn_network); sendNetworkRequestBtn.setOnClickListener(view -> { Log.d("apmsAndroidDemo", "send network request."); HttpUtil.oneRequest(); });

You can manually trigger an ANR event and check whether the ANR data is normal on the performance management page of APM.

  1. Add the following tap event in the onCreate method, and click TRIGGER ANR.
    this.findViewById(R.id.anr_test).setOnClickListener(v -> { Log.d("apmsAndroidDemo", "trigger ANR"); anrTestEnable = true; });
  2. To simulate an ANR error, add the following code to the outer layer of the onCreate method in the MainActivity.java file.
    private boolean anrTestEnable = false; @Override public boolean dispatchKeyEvent(KeyEvent event) { if (anrTestEnable) { try { Thread.sleep(20000); } catch (InterruptedException e) { e.printStackTrace(); } } return super.dispatchKeyEvent(event); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (anrTestEnable) { try { Thread.sleep(20000); } catch (InterruptedException e) { e.printStackTrace(); } } return super.dispatchTouchEvent(ev); }
  3. Tap the TRIGGER ANR button for several times until the pop-up indicating ANR is displayed.

Reporting Custom Events

You can manually trigger a custom event and check whether the custom performance indicators are normal on the performance management page of APM.
Reporting Custom Events by Calling an API

  1. Set the button tap event for the SEND CUSTOM EVENT button in MainActivity.java.
    findViewById(R.id.custom_normal_event).setOnClickListener(v -> { Log.d("apmsAndroidDemo", "send a custom event"); sendCustomEvent(); });
  2. Add the following code to the MainActivity.java file to define a custom event, and add the ProcessingResult and Status properties and the ProcessingTimes indicator to the event. When the button is tapped, data can be reported to the cloud.
    // Define a custom event. public void sendCustomEvent() { CustomTrace customTrace = APMS.getInstance().createCustomTrace("CustomEvent1"); customTrace.start(); // code you want trace businessLogicStart(customTrace); businessLogicEnd(customTrace); customTrace.stop(); } public void businessLogicStart(CustomTrace customTrace) { customTrace.putMeasure("ProcessingTimes", 0); for (int i = 0; i < 5; i++) { customTrace.incrementMeasure("ProcessingTimes", 1); } } public void businessLogicEnd(CustomTrace customTrace) { customTrace.putProperty("ProcessingResult", "Success"); customTrace.putProperty("Status", "Normal"); }

Reporting Custom Events by Annotation

  1. Set the button tap event for the SEND CUSTOM EVENT BY ANNOTATION button in MainActivity.java.
    findViewById(R.id.custom_normal_event_by_annotation).setOnClickListener(v -> { Log.d("apmsAndroidDemo", "send a custom event by annotation"); sendCustomEventByAnnotation(); });
  2. Add the following code to MainActivity.java to define a custom event. When the button is tapped, the event can be reported to the cloud.
    private void sendCustomEventByAnnotation() { customEventHandle(); } // Define a custom event by annotation. @AddCustomTrace(name = "CustomEvent2") public void customEventHandle() { }

Reporting Custom Network Events by Calling an API

  1. Set the button tap event for the SEND CUSTOM NETWORK EVENT button in MainActivity.java.
    findViewById(R.id.custom_network_event).setOnClickListener(v -> { Log.d("apmsAndroidDemo", "send a custom network event"); new Thread(HttpUtil::customNetworkEvent).start(); });
  2. Add the following code to HttpUtil.java to define a custom event, call an API to set the URL and number of bytes to be sent before the network connection starts, set the response code, response size, and response type after a network response, and set the property that specifies the actual transmitted data size and property that contains exception information. All these properties can be reported to the cloud when the SEND CUSTOM NETWORK EVENT button is tapped.
    static public void customNetworkEvent() { OkHttpClient okHttpClient = new OkHttpClient(); Request request = new Request.Builder() .url(URL) .post(RequestBody.create(MEDIATYPE, REQUESTBODY)) .build(); // Define a custom network event. NetworkMeasure networkMeasure = APMS.getInstance().createNetworkMeasure(URL, "POST"); networkMeasure.setBytesSent(request.headers().byteCount()); long bytesRecive = 0L; networkMeasure.start(); try { Response response = okHttpClient.newCall(request).execute(); networkMeasure.setStatusCode(response.code()); if (response.body() != null) { networkMeasure.setBytesReceived(response.body().contentLength()); networkMeasure.setContentType(Objects.requireNonNull(response.body().contentType()).toString()); bytesRecive = dealResponseBody(response.body()); response.body().close(); } networkMeasure.putProperty("TransferBytes", String.valueOf(bytesRecive)); networkMeasure.stop(); } catch (IOException e) { networkMeasure.setStatusCode(0); classErrorMessage(networkMeasure, e); networkMeasure.putProperty("ErrorMessage", e.getMessage()); networkMeasure.putProperty("Transfer Bytes", String.valueOf(bytesRecive)); networkMeasure.stop(); } } private static void classErrorMessage(NetworkMeasure networkMeasure, Exception e) { if (e instanceof UnknownHostException) { networkMeasure.putProperty("ErrorMessage", "DNS resolution failure"); } } private static long dealResponseBody(ResponseBody body) throws IOException { InputStream inputStream = body.byteStream(); byte[] result = new byte[1000]; long len = 0; long readBytes = 0; while ((len = inputStream.read(result)) != -1) { readBytes += len; } return readBytes; }

Enabling/Disabling Performance Data Collection

  1. Add the code for calling APMS.enableCollection to enable performance data reporting when the APMS COLLECTION ON button is tapped.
    findViewById(R.id.enable_apms_on).setOnClickListener(v -> { Log.d("apmsAndroidDemo", "enable Collection"); APMS.getInstance().enableCollection(true); });
  2. Add the code for disabling performance data reporting when the APMS COLLECTION OFF button is tapped.
    findViewById(R.id.enable_apms_off).setOnClickListener(v -> { Log.d("apmsAndroidDemo", "disable Collection"); APMS.getInstance().enableCollection(false); });
  3. Package and run the app, and tap SEND NETWORK REQUEST to report a network event.

Enabling/Disabling ANR Monitoring

  1. Create two buttons named APMS ANR MONITOR ON and APMS ANR MONITOR OFF in the app activity layout file to enable and disable ANR monitoring, respectively.
  2. Tap APMS ANR MONITOR ON to call enableAnrMonitor to enable ANR monitoring.
    findViewById(R.id.enable_apms_anr_on).setOnClickListener(v -> { Log.d("apmsAndroidDemo", "enable ANR Collection"); APMS.getInstance().enableAnrMonitor(true); });
  3. ANR monitoring is enabled by default. To disable it, tap APMS ANR MONITOR OFF.
    findViewById(R.id.enable_apms_anr_off).setOnClickListener(v -> { Log.d("apmsAndroidDemo", "disable ANR Collection"); APMS.getInstance().enableAnrMonitor(false); });
  4. Compile and run your app, and tap the TRIGGER ANR button to trigger an ANR error.

During app debugging, you can enable the APM debug log function to check whether the APM performance monitoring is running properly. Add the meta-data element to the AndroidManifest.xml file of your app.

<application> <!-- Set this flag to 'true', debug logs of APM will be printed in logcat, default value is 'false'--> <meta-data android:name="apms_debug_log_enabled" android:value="true" /> </application>

The Logcat log filter function allows you to filter performance monitoring logs of app launches, app screen rendering, and HTTP/HTTPS network requests. These logs are marked as com.huawei.agc.apms so that you can filter them by entering apms in the Logcat window of IDE, as shown in the following figure.

Checking the Overview

  1. Sign in to AppGallery Connect and click My projects.
  2. Click your project card and select an app from the app drop-down list on the top.
  3. Go to Quality > APM.
  4. On the Overview tab page, you can check the issues and indicator overview in the past 30 days for your app.
    The indicator overview includes the launch duration (by version), slow frame rate (top 5 activities), frozen frame rate (top 5 activities), network request duration (top 5 countries/regions), and network request success rate (by time). Based on important performance indicators on this page, you can identify app issues in a timely manner.

Viewing Network Analysis

  1. Click the Network analysis tab. This tab page records the number of requests, response time, and request success rate of each URL. You can filter them by time.
  2. Click View details of a request. The request details page is displayed, containing the request duration and request success rate.

Viewing Custom Network Event Analysis

There is no separate entry for viewing custom network events. The procedure is the same as that for viewing network analysis data. If any property is set, you can view the request duration and request success rate of that property by clicking View details.

Viewing Custom Event Analysis

  1. Click the App analysis tab. This tab page displays the list of reported custom events, including the custom event name, median value, number of samples, and the button for viewing details.
  2. Click View details next to CustomEvent1 to view the distribution of the time required for the custom event. Click the ProcessingTimes tab page to view the distribution of the ProcessingTimes measurement. The multi-dimensional analysis information is displayed at the bottom. You can check the distribution of ProcessingTimes under the custom properties Status and ProcessingResult.

Viewing ANR Data

  1. Click the ANR analysis tab. The ANR report is displayed. This page displays the ANR trend information, including top 5 problems in last 24 hours (sorted by affected-user rate), number of ANR occurrences, number of affected users, and affected-user rate distribution in different dimensions such as time, device model, OS version, and app version, as well as the list of ANR errors categorized by type.
  2. Click a card of a problem among the top 5 problems. The details page of this ANR error type is displayed, containing metrics such as the affected-user rate, ANR rate (number of ANR occurrences divided by number of app launches), number of occurrences, affected-user count trend over time, and affected-user count distribution by device model, app version, and OS version.
  3. Click View details next to a record in the Records list to view the details of the record.

Well done. You have successfully created an app that integrates APM of AppGallery Connect and learned how to view and analyze app performance data on the app performance management page.

API Reference

Sample code

Code copied