Panchaksharappa, Varuna

Mobile App Performance (MAP) SDK Integration Guide - ReactNative (Android)

 

Instructions for adding the Mobile App Performance(MAP) SDK to your ReactNative app for Android.

Required For Setup

  • You must be an Akamai Ion customer to use this SDK. If you are not on ION and would like to know more, please reach out to us at specialist@akamai.com
  • MAP SDK License Key - Follow the steps given in our getting started guide to activate MAP SDK from the marketplace.

Example Project

For your convenience, we've created a Sample App/project that you can use to get started and learn about using MAP SDK with ReactNative.

 

Getting Started

Network Interception
  • Network requests will be automatically instrumented as long as they are sent from java.net.URLConnection. 

  • Another way to access content over the network in an app is through WebViews. SDK provides an API for developers which delegates all network-related requests originating from WebViews to the MAP SDK.

  • If network requests are made through OkHttpClient or the library that uses it (examples are Picassa, Retrofit, etc.), the OkHttpClient needs to be configured to use the MAP interceptor.

The SDK  also collects network-related statistics (such as HTTP time to first byte, request size, response size, duration, etc.) alongside serving content. These stats are sent periodically to a server and can be later accessed via portal. 

 

Requirements and Dependencies

 

The SDK supports API 15 and above. The target/compile SDK should be atleast set to API 28 and it is also required by Google for any app updates from November 2019. Google no longer maintains support libraries up until version 28 and has made androidx the default support library in Android Studio. MAP SDK has migrated from Android Support libraries to androidx-packaged library artifacts. This will not only make our SDK better, but also allows us to use the latest Jetpack features. If you have not migrated to androidx library artifacts, add the following two lines to your gradle.properties file to use MAP SDK.

android.useAndroidX=true
android.enableJetifier=true

Androidx also requires minimum build tools version to be set at 'com.android.tools.build:gradle:3.2.0'  in the root build.gradle file. The minimum gradle version should be set at gradle-4.6 in the gradle-wrapper.properties. MAP SDK has a dependency on Work Manager ('androidx.work:work-runtime:2.2.0') and the dependency is automatically pulled in to your project.

 

1. Installing the Android SDK

1.1 In Android Studio, open the build.gradle file in the app directory (not the one in the root folder ) and edit the dependencies sub-section to include aka-map. Use the latest version of aka-map from jcenter

implementation 'com.akamai.android:aka-map:21.30.+'

1.2 The project gradle file should have jcenter() by default. If not, add it as shown below.

jcenter()

1.3 The SDK requires following permissions for full functionality: 

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

2. Integration with your Android Application

Initialization 

MAP SDK is initialized automatically and the client does not have to explicitly initialize the SDK. After initialization, the SDK needs to be registered with an API key.

2.1. Enable the SDK

Client AndroidManifest.xml will need to be updated in order to complete the SDK integration.  

In the Application tag add the below : 

<!-- Refers to sdk init file in res/xml/ -->
<meta-data
android:name="com.akamai.android.sdk"
android:resource="@xml/akamai_sdk_init" />

The SDK uses an XML file to look up the license key to authorize the client app. This information is stored in a file android_sdk_init.xml in the client app’s resources folder. The sample file is shown below.

Segments are associated with MAP SDK’s preposition feature. Providing the segments in the XML file will consider as subscription request.  Any content associated with the subscribed segments automatically starts getting prepositioned based on network policy( wifi/cellular) defined.

2.2. In …./main/res/xml (create if it doesn’t exist!) folder, add a new file android_sdk_init.xml.

<?xml version="1.0" encoding="utf-8"?>
<com_akamai_sdk_init>
<com_akamai_map_license_key>Add MAP License Key</com_akamai_map_license_key>
<com_akamai_map_segments>Add MAP segments</com_akamai_map_segments>
</com_akamai_sdk_init>

2.3. Download/Add the AkaOkHttpInterceptor.java in your project.

2.4. Create a class named CustomNetworkModule and use AkaOkHttpInterceptor as below :

public class CustomNetworkModule implements OkHttpClientFactory {
  public OkHttpClient createNewNetworkModuleClient() {
      return new OkHttpClient.Builder()
              .connectTimeout(60, TimeUnit.MILLISECONDS)
              .readTimeout(60, TimeUnit.MILLISECONDS)
              .writeTimeout(60, TimeUnit.MILLISECONDS)
              .cookieJar(new ReactCookieJarContainer())
              .addInterceptor(new AkaOkHttpInterceptor())
              .build();
  }
}

2.5. In your MainActivity.java :

OkHttpClientProvider.setOkHttpClientFactory(new CustomNetworkModule());

2.6. Run the app

react-native run-android

 

Troubleshooting

If you run into any issues, see our general Troubleshooting section.

See our ReactNative Example Project for more help.

 

Debug logs

You need to set the log level to debug to see the debug logs associated with map-sdk.

Logger.setLevel(Logger.LEVEL.DEBUG);

 

Success

  • SDK discovered

D/AkaSDKLogger: Initialized com.akamai.android.aka_common, version D/AkaSDKLogger: ComponentContainer: Initialized com.akamai.android.sdk, 

D/AkaSDKLogger: AkaInitProvider: AkaCommon initialization successful through CP.

  • Sync started

D/AkaSDKLogger: AkaBackgroundService: com.akamai.anaina.FULL_SYNC

  • Interception started:

D/AkaSDKLogger: External Url Stream handler to handle http/s stream:: com.akamai.android.sdk.AkaMap

  • Config requested

D/AkaSDKLogger: Request headers for Url: https://configuration-map.akamai.com/config?id=

  • Config received

D/AkaSDKLogger: d: Capabilities: {"license_hash":

  • Prepositioning triggered 

D/AkaSDKLogger: AnaWebContentDownloader: WebContent: Queued for download  11, policy  0

  • Analytics success

D/AkaSDKLogger: AkaWebAnalyticsHandler: sendWebAccAnalytics: 200

  • Push notification

D/AkaSDKLogger: PushMessagingService: Fcm rcv Prepare sync

Failures

  • Wrong library

ERROR: Failed to resolve: com.akamai.android:aka-map:21.*.*

Solution: Integration step is wrong. Add jcenter() in the project build.gradle

  • Missing config file reference

E/AkaSDKLogger: Couldn't find resource file for meta-data key com.akamai.android.sdk!

Solution: Check akamai_sdk_init.xml file is in res/xml and reference it  in the AndroidManifest.xml

Wrong key

E/AkaSDKLogger: AkaConfigHandler: getConfig with exception:java.io.FileNotFoundException:

E/AkaSDKLogger: AkaSyncController: sync: SDK is not active

Solution: Ensure that licenseKey is added in akamai_sdk_init.xml.

Verifying Content Logs

  • Content served from Universal Cache

    • D/AkaSDKLogger: D/AkaSDKLogger: AkaURLConnection: Stats: URL: https://www.akamai.com/, Type: CACHE_FETCH_ADHOC, Connection: cellular/LTE, RespCode: 200, ContentLength: 251167, StartTime: 1523471307223, Duration: 55, Ttfb: 6

  • Content served from Preposition Cache

    • D/AkaSDKLogger: D/AkaSDKLogger: AkaURLConnection: Stats: URL: https://www.akamai.com/, Type: CACHE_FETCH, Connection: cellular/LTE, RespCode: 200, ContentLength: 251167, StartTime: 1523471307223, Duration: 55, Ttfb: 6

  • Content served from Network

    • D/AkaSDKLogger: D/AkaSDKLogger: AkaURLConnection: Stats: URL: https://www.akamai.com/, Type: CACHE_MISS, Connection: cellular/LTE, RespCode: 200, ContentLength: 251167, StartTime: 1523471307223, Duration: 55, Ttfb: 6