Executes all injecting processes of MPM. All execution processes are ignored if set as \n true.
mpm
true
Installs an SDK for MPM. The MPM library cannot be used if set to false.
crash
true
Installs an SDK for Crash. The Crash library cannot be used if set to false.
core
true
Installs the IMQA Core SDK. The Core library cannot be used if set to false.
repackaging
true
Sets repackaging mode. Injection is performed during compilation if set to false.
lifecycle
true
Allows activity lifecycle injecting. The activity map is hidden if set to false.
event_listener
true
Allows event listener injecting. Event information is not collected if set to false.
fragment_lifecycle
true
Sets whether to collect fragments or not. The rendering speed of the fragment is not collected if set to false.
webview
true
Allows WebView related injecting. HTTP/S requests in the WebView are not collected if set to false.
network
true
Wraps the network collection method. Network-related response speed is not collected if set to false.
manifest_location
""
You can manually set the manifest location of the current build environment. The plugin automatically searches if not set.
flavor
""
You can manually set the flavor of the current build environment. The plugin automatically searches if not set.
mapping_upload
true
Automatically uploads a mapping file when it is created.
map_upload_server
"http://mpm.imqa.io"
Wraps the network collection method. Network-related response speed is not collected if set to false.
project_key
""
Sets the project key for the current app. Additional setting is required to upload the “mapping.txt” file properly. An upload failure message may appear in the build log if not set.
Description of file runtime setting values
Option Name
Default Value
Description
buildType
false
Sets whether IMQA collects data.
- true: Do not collect data.
- false: Collects data.
printLog
false
Sets whether to output the log. Outputs IMQA logs if set to true.
dump_interval
5000
Sets the dump interval in ms (milliseconds).
file_interval
5
Sets the interval of saving dumps in a file in minutes.
upload_period
false
Sets whether to upload a file periodically. Uploads a file according to the FileInterval while the app is running. Uploads collected data while executing the app again only if set to false.
socket_tracing
true
Sets the function of collecting information related to the socket. Collects and saves network communication information using the socket while the app is running, if set to true.
http_tracing
true
Sets the function of collecting HTTP related information. Collects and saves HTTP information while the app is running, if set to true.
keep_file_on_fail
true
Sets whether to leave the measured performance file until upload is successful. Keeps the file inside until the upload is successful. If set to false, the file is deleted even if upload fails.
mpm_server_url
Sets the URL of the MPM server.
force_https
false
Establishes HTTPS communication by ignoring the certificate (SSL) of the upload server if set to false.
end_date
(none)
Sets the end date.
os_version_limit_list
[]
Sets the OS version to run.
app_version_limit_list
[]
Sets the app version to run.
dump_size_max
10
Sets the maximum usage of dump data. (in MB)
behavior_max
15
Sets the maximum number of behavior analysis data.
Gradle File
You can change the IMQA MPM installation mode using gradle.
app.gradle
ext {/** * @Default false * Executes all injecting processes of MPM. * All execution processes are ignored if set to true. */ IMQAStop =false/** * @Default true * Allows activity lifecycle injecting. * The activity map is hidden if set to false. */ IMQALifecycle =true/** * @Default true * Allows event listener injecting. * Event information is not collected if set to false. */ IMQAEventListener =true/** * @Default false * Allows injecting related to WebView. * HTTP/S requests in the WebView are not collected if set to false. */ IMQAWebview =false/** * @Default true * Sets whether to collect fragments or not. * The rendering speed of the fragment is not collected if set to false. */ IMQAFragment =true/** * @Default true * Wraps the network collection method. * Network-related response speed is not collected if set to false. */ IMQANetwork =true/** * @Default "" * You can manually set the flavor of the current build environment. * The plugin automatically searches if not set. */ IMQAFlavor ="debug";/** * @Default "/build/intermediates/manifests/full/" * You can manually set the manifest location of the current build environment. * The plugin automatically searches if not set. */ IMQAManifestLocation ="/build/intermediates/manifests/full/"/** * @Default true * Sets repackaging mode. * Injection is performed during compilation if set to false. */ IMQARepackaging =false/** * @Default true * Automatically uploads a mapping file when it is created. * If not set, “mapping.txt” for each app version should be uploaded by connecting to IMQA. */ IMQAMappingUpload =true/** * @Default "" * Sets the project key for the current app. * Additional setting is required to upload the “mapping.txt” file properly. * An upload failure message may appear in the build log if not set. */ IMQAProjectKey ="";/** * @Default "http://mpm.imqa.io" * Input the host name to upload the “mapping.txt” file. * Additional setting is required to upload the “mapping.txt” file properly. * An upload failure message may appear in the build log if not set. */ IMQAMapUploadServer ="http://mpm.imqa.io"}
MPM Run Option
You can change the IMQA MPM mode using parameters or options.
MyApplication.java
@OverridepublicvoidonCreate() { super.onCreate();io.imqa.core.IMQAOption imqaOption =new io.imqa.core.IMQAOption();/* * Default value: true * Sets execution mode. * true: Runs in release mode only. * false: Runs in debug mode only. */imqaOption.setBuildType(false);/* * Default value: false * Sets whether to output the log. * true: Outputs the IMQA log. */imqaOption.setPrintLog(true);/* * Default value: 5000 (ms) * Sets the dump interval in ms (milliseconds). */imqaOption.setDumpInterval(3000);/* * Default value: 5 (minutes). * Sets the interval of saving dumps in a file in minutes. */imqaOption.setFileInterval(1);/* * Default value: false * Sets whether to upload a file periodically. * true: Uploads a file according to the FileInterval while the app is running. * false: Uploads collected data while executing the app again. */imqaOption.setUploadPeriod(true);/* * Deprecated * Default value: true * Sets the function of collecting information related to the socket. * true: Collects and saves network communication information using the socket while the app is running. * false: The IMQA socket collection function is not set. */imqaOption.setNetworkTracing(false);/* * Default value: true * Sets the function of collecting information related to the socket. * true: Collects and saves network communication information using the socket while the app is running. * false: The IMQA socket collection function is not set. */imqaOption.setSocketTracing(false);/* * Default value: true * Sets the function of collecting HTTP related information. * true: Collects and saves HTTP information while the app is running. * false: The IMQA HTTP collection function is not set. */imqaOption.setHttpTracing(false);/* * Default value: true * Sets whether to leave the measured performance file until upload is successful. * true: Keeps the file inside until the upload is successful. * false: The file is deleted even if upload fails. */imqaOption.setKeepFileAtUploadFail(false);/* * Default value: false * Establishes HTTPS communication by ignoring the certificate (SSL) of the upload server. * true: Ignores the certificate and establishes HTTPS communication. * false: Checks the certificate and establishes HTTPS communication. */imqaOption.setForceHttps(true);/* * Default value : null * Sets the end date. * Date: End date */imqaOption.setEndDate(Date);/* * Default value : false * Gets option settings from the server. Requests to the collection server set with setServerUrl. * Sets as the highest priority option. If not responded, it will be operated with the option set in the code. * true: Gets options from the server. * false: Operates with the option set in the code. */imqaOption.setRemoteConfig(true);/* * Default value : 3000 * Sets a time-out when getting remote server options. * When a time-out occurs, it operates with the option set in the code. * int : timeout (ms) */imqaOption.setRemoteTimeout(3000);/* * 기본값 : ArrayList<Integer> * Sets the OS version to run. * int : Running OS version */imqaOption.addOSVersionLimitList(Build.VERSION_CODES.O);/* * Default value : OSProhibit * Does not activate the SDK under the version in question. * int : Running OS version */imqaOption.getOSProhibitVersionLimitList().addOSProhibitVersionLimitBelow(Build.VERSION_CODES.M);/* * Default value : ArrayList<String> * Sets the app version to run. * String : Running app version */imqaOption.addAppVersionLimitList("1.1");/* * Default value : null * Specifies the URL that will be excluded from collection. * By default, host and pathname will apply. Query value match can be added as an option. * String : Target url * boolean : query matching status (e.g.,: After the question mark (?) in https://abc.com/search?foo=bar) */imqaOption.getURLBlacklist().addBlacklistURL("https://abc.com/search",false);/* * Default value : ArrayList<AccessPoint> * Sets the app version to run. * One AP for each AccessPoint object. If no unique value is set among three options, it will be deemed true. * As SSID and BSSID require location authority, * “ACCESS_FINE_LOCATION” or “ACCESS_COARSE_LOCATION” should be added to use this authority. * AccessPoint: Active SSID, BSSID, IP */io.imqa.core.network.AccessPoint ap =new io.imqa.core.network.AccessPoint();ap.setSsid("IMQA");ap.setBssid("cc:40:d0:f7:a5:d7");ap.setIpAddress("192.168.0.1");imqaOption.addWifiLimitList(ap);/* * Default value : 10 * Sets the maximum usage of dump data. * int : Maximum usage (in MB) */imqaOption.setDumpSizeMax(10);/* * Default value : 15 * Sets the maximum number of behavior analysis data. * int: maximum count */imqaOption.setBehaviorLengthMax(15);/* * Default value : 'IMQA-ADDITIONAL-KEY' * Inputs additional header information when establishing HTTP communication. * String: Name of the additional header key */imqaOption.setAdditionalHeader(true,"MY-HEADER");// 또는imqaOption.setAdditionalHeader(true);imqaOption.setAdditionalHeaderKey("MY-HEADER");io.imqa.mpm.IMQAMpmAgent.getInstance().setOption(imqaOption) // Sets the option to decide the MPM operation method..setContext(this,BuildConfig.FLAVOR) // Initializes the application context..setProjectKey("PROJECT_KEY") // Sets the project key of the IMQA MPM client..init() // Initializes the registered options.
Executing independent MPM
You can execute IMQA MPM Injector in a specific task. However, if you use the above method, codes may not be inserted normally depending on the executed location.
app.gradle
// apply plugin: 'io.imqa' // Should be deactivated for independent execution.
// You must manually insert this part because auto-insert function is canceled.
dependencies {
implementation 'io.imqa:imqa-core:2.27.5'
implementation 'io.imqa:imqa-mpm-client:2.27.9'
implementation 'io.imqa:imqa-crash-client:2.27.5'
}
// Creates with a constructor because it is a plugin object (uses static internally.)
io.imqa.IMQAPlugin imqaPlugin = new io.imqa.IMQAPlugin()
// Sets basic IMQA options (IMQAOption, BuildOption, imqa-service.json.)
imqaPlugin.init(project)
// Creates with a constructor because it is an action object (uses static internally.)
// Reflects IMQA options in app.gradle. Reflects the basic information of the development environment (build tool, variants, etc.). Inserts IMQA dependency automatically.
new io.imqa.injector.GJavacAction(project.name).setConfiguration(project)
android.applicationVariants.all { variant ->
// A variable name must be inserted into doLast Lamda when setting.
// If the variable name is not specified, an error occurs because the built-in gradle “task” is called.
variant.javaCompile.doLast { task ->
// Executes CompileAction at the current location based on the above settings.
// If there are Kotlin codes in the project, add the codes below:
new io.imqa.injector.CompileAction(
io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.kotlin,
project.name,
io.imqa.injector.GJavacAction.convertBuildType(variant.getBuildType()),
io.imqa.injector.GJavacAction.makeFlavor(variant.getBuildType().name, variant)
)
.execute(task)
// Gradle 3.2 ~ 3.4, 4.0, 4.1 : io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.javacCompileClasses
// Gradle 3.5 and later io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.javacClasses
// Other versions: io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.classes
new io.imqa.injector.CompileAction(
io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.javacCompileClasses,
project.name,
io.imqa.injector.GJavacAction.convertBuildType(variant.getBuildType()),
io.imqa.injector.GJavacAction.makeFlavor(variant.getBuildType().name, variant)
)
.execute(task)
}
}
Setting network collection
The IMQA MPM framework automatically measures network collection, but for specific libraries, manual settings must be made.
Responding to AsyncHttpClient
When requesting a network using the AsyncHttpClient library, please add the following.
MainActivity.java
...AsyncHttpClient client =newAsyncHttpClient();...HttpData httpData =newHttpData();client.get(this, url,newAsyncHttpResponseHandler() { @Override public void onStart() {// Enter network request informationURI uri =this.getRequestURI();httpData.setHostName(uri.getHost());httpData.setMethod("get"); // get | post httpData.setProtocol(uri.getScheme());httpData.setPathName(uri.getPath()); } @Override public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {// Enter network response code ( if successful ) httpData.setStatus(statusCode +""); } @Override public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {// Enter network response code ( if failure ) httpData.setStatus(statusCode +""); } @Override public void onFinish() {// Network collection progress ( Upon completion of request ) httpData.setEndTime(System.currentTimeMillis());HttpCollector.collect(httpData); }});...
2. Setting ProGuard
ProGuard is a tool used to make the APK as small as possible in size by removing unused resources and shortening the name of classes or methods. When using ProGuard or DexGuard, the original class and method name can be displayed on the crash report by uploading the mapping file as below:
Preparation
If ProGuard is used in a project under development, the source code is obfuscated, making the analysis difficult. In this case, obfuscated codes can be analyzed using the generated mapping.txt file.
Add the following to ProGuard rules (proguard-rules.pro):
A file is created in the app/build/outputs/mapping/debug (or release)/mapping.txt directory. (The file location may differ a little depending on the buildType and flavor.)
You need to connect to http://crash.imqa.io to upload the file created in this way.
When uploading the file, its name must be named as “mapping.txt” or “map.txt”.
Upload process
1. Select “Setting” at the project menu.
2. Click the [File Upload] button to open the upload window.
3. Click the [Choose File] button that matches the app version specified in the gradle and upload the “mapping.txt” file.
4. If you click the [Upload] button, the crash information collected afterwards will be displayed after analysis.
When the latest version of the app is released, please register additional mapping files of the same app version in order to view the version’s crash information.
3. MPM Webview Guide
WebView HTTP request
Setting the web server
To collect WebView data, the IMQA Webview JavaScript library should be inserted into the web page that provides WebView. If you wish, you can also download the file and share it via web server.
(It is recommended to directly import and use this if a Cross-Origin Resource Sharing (CORS) problem occurs.)
For information on how to install the Agent when using MPM / WPM integration, refer to ‘IMQA WPM/WCrash Installation Guide > 1.2. Please refer to 'Using WPM / MPM integration (Installing WebAgent + WebviewAgent)'.
Inserting a WebView file
<!--IMQA Webview Agent(ver. 1.1.3 earlier) --><scripttype="text/javascript"src="https://cdn.imqa.io/agent/webview-agent-1.1.2.js"crossorigin></script><!-- If you want to apply it asaminfile: --><scripttype="text/javascript"src="https://cdn.imqa.io/agent/webview-agent-1.1.2.min.js"crossorigin></script>
MPM collects WebView-related pages and requests. To enable the collection, you need to set up options and add MPMWebviewInterface. Additionally, error information occurring in WebView can be collected. To collect Webview Crash, you must add CrashWebviewBridge.
IMQA Client can collect HttpsURLConnection based network requests. Add the following when requesting an HttpsURLConnection based network.
HttpsURLConnection
MainActivity.java
...// Wraps the HttpsURLConnection object with ConnectionWrapper.URL url =newURL("https://some.host.com");HttpsURLConnection conn = (HttpsURLConnection) ConnectionWrapper.wrap((HttpsURLConnection) url.openConnection());...
MainActivity.kt
...// Wraps the HttpsURLConnection object with ConnectionWrapper.var url : URL =URL("https://some.host.com")var conn : HttpsURLConnection =ConnectionWrapper.wrap(url.openConnection() as HttpsURLConnection ) as HttpsURLConnection...
Responding to OkHttp
IMQA Client can collect OkHttp based network requests. Add the following when requesting an OkHttp based network.
OkHttp Client
1. OkHttp3
MainActivity.java
...// Add MPMInterceptor to OkHttpClientOkHttpClient client =new OkHttpClient.Builder().addNetworkInterceptor(newMPMInterceptor()).build();...// Run OkHttpClient with the added interceptorResponse response =client.newCall(request).execute();...
MainActivity.kt
...// Add MPMInterceptor to OkHttpClientval builder :OkHttpClient.Builder=OkHttpClient.Builder()val client : OkHttpClient =IMQAManager.wrapOkhttp(builder).addNetworkInterceptor(MPMInterceptor()).build();...// Run OkHttpClient with the added interceptor.val response : Response =client.newCall(request).execute()...
2. Retrofit 2.0
MainActivity.java
...// Add MPMInterceptor to OkHttpClientOkHttpClient client =new OkHttpClient.Builder().addNetworkInterceptor(newMPMInterceptor()).build();...new Retrofit.Builder().baseUrl(host).client(client) // Use OkHttpClient with the added interceptor.build();...
MainActivity.kt
...// Add MPMInterceptor to OkHttpClientval builder :OkHttpClient.Builder=OkHttpClient.Builder()val client : OkHttpClient =IMQAManager.wrapOkhttp(builder).addNetworkInterceptor(MPMInterceptor()).build();...val retrofit =Retrofit.Builder().baseUrl(host).client(client) // Use OkHttpClient with the added interceptor.build()...
Responding to the image loading library
1. Picasso
For Picasso, OkHttp is selected as a default downloader when using OkHttp. Add the following to add an interceptor to this downloader. First, add OkHttp3Downloader dependency.
// The downloader that MPMInterceptor is added in advance should be inserted before initializing Picasso's Singleton instance.Picasso.setSingletonInstance(new Picasso.Builder(this).downloader(newOkHttp3Downloader(new OkHttpClient.Builder().addInterceptor(new MPMInterceptor()).build() )).build());
2. Glide
For Glide, HttpUrlConnection is used as the default HTTP library. Set OkHttpClient in the registry to use OkHttp.