MPM SDKインストール
IMQA MPMをAndroidプロジェクトに追加すると、JavaとKotlinで開発したアプリで発生するアプリケーションの性能問題を様々な視点から確認することができます。
Min SDK : 14
Target SDK : 33
Build Tool : ~7.2
Gradle Wrapper : ~ 7.1.3
Kotlin : ~ 1.3.21
Android Studio : ~ Giraffe
IMQAプロジェクトページでAndroidプロジェクトを作成してプロジェクトキーを受け取ったらインストールを実行してください。
1. Gradle Pluginインストール
「app.gradle」ファイルで「buildscript」内の「dependencies」ブロックに「imqa-mpm-injector」と上段に「plugin」を追加してください。一般的に「<project_dir>/app/build.gradle」にあります。
ファイルをアップデート後にGradleファイルを同期させる必要があります。
// Add Build script dependencies
buildscript {
repositories {
mavenCentral()
}
dependencies {
// Add dependencies.
classpath 'io.imqa:imqa-mpm-injector:2.25.7' ...
}
}
java
...
dependencies {
// Add 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'
}
}
io.imqa.IMQAPlugin imqaPlugin = new io.imqa.IMQAPlugin()
imqaPlugin.init(project)
new io.imqa.injector.GJavacAction(project.name).setConfiguration(project)
android.applicationVariants.all { variant ->
variant.javaCompile.doLast { task ->
new io.imqa.injector.CompileAction(
io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.javacClasses,
project.name,
io.imqa.injector.GJavacAction.convertBuildType(variant.getBuildType()),
io.imqa.injector.GJavacAction.makeFlavor(variant.getBuildType().name,
variant)
).execute(task)
}
}
kotlin
...
dependencies {
// Add 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'
}
}
io.imqa.IMQAPlugin imqaPlugin = new io.imqa.IMQAPlugin()
imqaPlugin.init(project)
new io.imqa.injector.GJavacAction(project.name).setConfiguration(project)
android.applicationVariants.all { variant ->
variant.javaCompile.doLast { task ->
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)
}
}
java + kotlin
...
dependencies {
// Add 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'
}
}
io.imqa.IMQAPlugin imqaPlugin = new io.imqa.IMQAPlugin()
imqaPlugin.init(project)
new io.imqa.injector.GJavacAction(project.name).setConfiguration(project)
android.applicationVariants.all { variant ->
variant.javaCompile.doLast { task -> {
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)
new io.imqa.injector.CompileAction(
io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.javacClasses,
project.name,
io.imqa.injector.GJavacAction.convertBuildType(variant.getBuildType()),
io.imqa.injector.GJavacAction.makeFlavor(variant.getBuildType().name,
variant)
).execute(task)
}
}
}
...
project.home=Path of project (ex:/user/workspace/project1)
#Add only Kotlin project
project.kotlin.path=$PROJECT_HOME/app/build/tmp/kotlin-classes
#Add only Java project
project.java.path=$PROJECT_HOME/app/build/intermediates/javac/debug/classes
#Path to built manifest file
project.manifest.path=$PROJECT_HOME/app/build/intermediates/merged_manifest/debug/AndroidManifest.xml
#gradle action
project.task.execute=:assemble
Kotlin DSL
buildscript {
repositories {
mavenCentral()
}
dependencies {
// Add dependencies.
classpath("io.imqa:imqa-mpm-injector:2.25.6") ...
}
}
java
...
dependencies {
// Add 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")
}
}
val imqaPlugin: io.imqa.IMQAPlugin = io.imqa.IMQAPlugin()
imqaPlugin.init(project)
io.imqa.injector.GJavacAction(project.name)
android.applicationVariants.all {
val variant = this
val javaCompileTask = variant.javaCompileProvider?.get()
javaCompileTask?.doLast {
val task = this
io.imqa.injector.CompileAction(
io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.javacClasses, project.name,
io.imqa.injector.GJavacAction.convertBuildType(variant.buildType),
io.imqa.injector.GJavacAction.makeFlavor(variant.buildType.name, variant)
).execute(task)
}
}
kotlin
...
dependencies {
// Add 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")
}
}
val imqaPlugin: io.imqa.IMQAPlugin = io.imqa.IMQAPlugin()
imqaPlugin.init(project)
io.imqa.injector.GJavacAction(project.name)
android.applicationVariants.all {
val variant = this
val javaCompileTask = variant.javaCompileProvider?.get()
javaCompileTask?.doLast {
val task = this
io.imqa.injector.CompileAction(
io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.kotlin, project.name,
io.imqa.injector.GJavacAction.convertBuildType(variant.buildType),
io.imqa.injector.GJavacAction.makeFlavor(variant.buildType.name, variant)
).execute(task)
}
}
java + kotlin
...
dependencies {
// Add 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")
}
}
val imqaPlugin: io.imqa.IMQAPlugin = io.imqa.IMQAPlugin()
imqaPlugin.init(project)
io.imqa.injector.GJavacAction(project.name)
android.applicationVariants.all {
val variant = this
val javaCompileTask = variant.javaCompileProvider?.get()
javaCompileTask?.doLast {
val task = this
io.imqa.injector.CompileAction(
io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.kotlin, project.name,
io.imqa.injector.GJavacAction.convertBuildType(variant.buildType),
io.imqa.injector.GJavacAction.makeFlavor(variant.buildType.name, variant)
).execute(task)
io.imqa.injector.CompileAction(
io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.javacClasses, project.name,
io.imqa.injector.GJavacAction.convertBuildType(variant.buildType),
io.imqa.injector.GJavacAction.makeFlavor(variant.buildType.name, variant)
).execute(task)
}
}
2. グラドルプラグイン(Gradle Plugin)詳細設定
アプリプロジェクト構造が基本的なAndroid Project構造でない場合、gradleのdaemonを利用したクイックビルド設定になっている場合、またはSDK適用が正しくできない場合(ネイティブ画面ロード時間(ウェブビューX)、ネットワーク応答時間などが収集できない場合 に適用可能です。
「app.gradle」ファイルで、「buildscript」内の「dependencies」ブロックに「imqa-mpm-injector」と上部に「plugin」を追加します。 通常は ‘<project_dir>/app/build.gradle’ にあります。
ファイルをアップデート後にGradleファイルを同期させる必要があります。
java
...
dependencies {
// Add 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'
}
}
io.imqa.injector.IMQABuildOption imqaBuildOption = new io.imqa.injector.IMQABuildOption();
imqaBuildOption.setProjectHomePath("Path of project")
// Path of project (ex:/user/workspace/project1)
imqaBuildOption.setAndroidManifestPath("Path to built manifest file")
// Path to built manifest file (ex:/user/workspace/project1/app/build/intermediates/merged_manifest/debug/AndroidManifest.xml)
imqaBuildOption.setJavaBuildPath("")
// Add only java project (ex:/user/workspace/project1/app/build/intermediates/javac/debug/classes)
io.imqa.IMQAPlugin imqaPlugin = new io.imqa.IMQAPlugin()
imqaPlugin.init(project, imqaBuildOption)
new io.imqa.injector.GJavacAction(project.name).setConfiguration(project)
android.applicationVariants.all { variant ->
variant.javaCompile.doLast { task ->
new io.imqa.injector.CompileAction(
io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.javacClasses,
project.name,
io.imqa.injector.GJavacAction.convertBuildType(variant.getBuildType()),
io.imqa.injector.GJavacAction.makeFlavor(variant.getBuildType().name,
variant),
imqaBuildOption
).execute(task)
}
}
kotlin
...
dependencies {
// Add 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'
}
}
io.imqa.injector.IMQABuildOption imqaBuildOption = new io.imqa.injector.IMQABuildOption();
imqaBuildOption.setProjectHomePath("Path of project")
// Path of project (ex:/user/workspace/project1)
imqaBuildOption.setAndroidManifestPath("Path to built manifest file")
// Path to built manifest file (ex:/user/workspace/project1/app/build/intermediates/merged_manifest/debug/AndroidManifest.xml)
imqaBuildOption.setKotlinBuildPath("")
// Add only kotlin project (ex:/user/workspace/project1/app/build/tmp/kotlin-classes/debug)
io.imqa.IMQAPlugin imqaPlugin = new io.imqa.IMQAPlugin()
imqaPlugin.init(project, imqaBuildOption)
new io.imqa.injector.GJavacAction(project.name).setConfiguration(project)
android.applicationVariants.all { variant ->
variant.javaCompile.doLast { task ->
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),
imqaBuildOption
).execute(task)
}
}
java + kotlin
...
dependencies {
// Add 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'
}
}
io.imqa.injector.IMQABuildOption imqaBuildOption = new io.imqa.injector.IMQABuildOption();
imqaBuildOption.setProjectHomePath("")
// Path of project (ex:/user/workspace/project1)
imqaBuildOption.setAndroidManifestPath("")
// Path to built manifest file (ex:/user/workspace/project1/app/build/intermediates/merged_manifest/debug/AndroidManifest.xml)
imqaBuildOption.setJavaBuildPath("")
// Add only java project (ex:/user/workspace/project1/app/build/intermediates/javac/debug/classes)
imqaBuildOption.setKotlinBuildPath("")
// Add only kotlin project (ex:/user/workspace/project1/app/build/tmp/kotlin-classes/debug)
io.imqa.IMQAPlugin imqaPlugin = new io.imqa.IMQAPlugin()
imqaPlugin.init(project, imqaBuildOption)
new io.imqa.injector.GJavacAction(project.name).setConfiguration(project)
android.applicationVariants.all { variant ->
variant.javaCompile.doLast { task ->
new io.imqa.injector.CompileAction(
io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.javacClasses,
project.name,
io.imqa.injector.GJavacAction.convertBuildType(variant.getBuildType()),
io.imqa.injector.GJavacAction.makeFlavor(variant.getBuildType().name,
variant),
imqaBuildOption
).execute(task)
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),
imqaBuildOption
).execute(task)
}
}
Kotlin DSL
java
...
dependencies {
// 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")
}
}
val imqaBuildOption: io.imqa.injector.IMQABuildOption = io.imqa.injector.IMQABuildOption();
imqaBuildOption.projectHomePath = "" // Path of the project (ex:/user/workspace/project1)
imqaBuildOption.javaBuildPath = "" // Add only java project (ex:/user/workspace/project1/app/build/intermediates/javac/debug/classes)
imqaBuildOption.androidManifestPath = "" // Path to built manifest file (ex:/user/workspace/project1/app/build/intermediates/merged_manifest/debug/AndroidManifest.xml)
val imqaPlugin: io.imqa.IMQAPlugin = io.imqa.IMQAPlugin()
imqaPlugin.init(project,imqaBuildOption)
io.imqa.injector.GJavacAction(project.name)
android.applicationVariants.all {
val variant = this
val javaCompileTask = variant.javaCompileProvider?.get()
javaCompileTask?.doLast {
val task = this
io.imqa.injector.CompileAction(
io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.javacClasses,
project.name,
io.imqa.injector.GJavacAction.convertBuildType(variant.buildType),
io.imqa.injector.GJavacAction.makeFlavor(variant.buildType.name, variant),
imqaBuildOption
).execute(task)
}
}
kotlin
...
dependencies {
// Add 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")
}
}
val imqaBuildOption: io.imqa.injector.IMQABuildOption = io.imqa.injector.IMQABuildOption();
imqaBuildOption.projectHomePath = "" // Path of the project (ex:/user/workspace/project1)
imqaBuildOption.kotlinBuildPath = "" // Add only kotlin project
(ex:/user/workspace/project1/app/build/tmp/kotlin-classes/debug)
imqaBuildOption.androidManifestPath = "" // Path to built manifest file (ex:/user/workspace/project1/app/build/intermediates/merged_manifest/debug/AndroidManifest.xml)
val imqaPlugin: io.imqa.IMQAPlugin = io.imqa.IMQAPlugin()
imqaPlugin.init(project,imqaBuildOption)
io.imqa.injector.GJavacAction(project.name)
android.applicationVariants.all {
val variant = this
val javaCompileTask = variant.javaCompileProvider?.get()
javaCompileTask?.doLast {
val task = this
io.imqa.injector.CompileAction(
io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.kotlin,
project.name,
io.imqa.injector.GJavacAction.convertBuildType(variant.buildType),
io.imqa.injector.GJavacAction.makeFlavor(variant.buildType.name, variant),
imqaBuildOption
).execute(task)
}
}
java + kotlin
...
dependencies {
// Add 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")
}
}
val imqaBuildOption: io.imqa.injector.IMQABuildOption = io.imqa.injector.IMQABuildOption();
imqaBuildOption.projectHomePath = "" // Path of project (ex:/user/workspace/project1)
imqaBuildOption.javaBuildPath = "" // Add only java project (ex:/user/workspace/project1/app/build/intermediates/javac/debug/classes)
imqaBuildOption.kotlinBuildPath = "" // Add only kotlin project
(ex:/user/workspace/project1/app/build/tmp/kotlin-classes/debug)
imqaBuildOption.androidManifestPath = "" // Path to built manifest file (ex:/user/workspace/project1/app/build/intermediates/merged_manifest/debug/AndroidManifest.xml)
val imqaPlugin: io.imqa.IMQAPlugin = io.imqa.IMQAPlugin()
imqaPlugin.init(project,imqaBuildOption)
io.imqa.injector.GJavacAction(project.name)
android.applicationVariants.all {
val variant = this
val javaCompileTask = variant.javaCompileProvider?.get()
javaCompileTask?.doLast {
val task = this
io.imqa.injector.CompileAction(
io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.kotlin,
project.name,
io.imqa.injector.GJavacAction.convertBuildType(variant.buildType),
io.imqa.injector.GJavacAction.makeFlavor(variant.buildType.name, variant),
imqaBuildOption
).execute(task)
io.imqa.injector.CompileAction(
io.imqa.injector.util.BuildOption.BUILD_LOCATION_TYPE.javacClasses,
project.name,
io.imqa.injector.GJavacAction.convertBuildType(variant.buildType),
io.imqa.injector.GJavacAction.makeFlavor(variant.buildType.name, variant),
imqaBuildOption
).execute(task)
}
}
3. Android Manifestに権限追加
AndroidManifest.xmlに発生したクラッシュ情報をアップロードするため、インターネット権限を与える必要があります。
<uses-permission android:name="android.permission.INTERNET"/>
4. ソースコードにIMQA初期化コード挿入
IMQA開始コード作成
ActivityではなくApplicationクラスに挿入する必要があります。
このとき、「PROJECT_KEY」部分にコピーした「Project Key」の値を挿入してください。
...
@Override
public void onCreate() {
super.onCreate();
io.imqa.core.IMQAOption imqaOption = new io.imqa.core.IMQAOption();
imqaOption.setBuildType(false);
imqaOption.setUploadPeriod(true);
imqaOption.setKeepFileAtUploadFail(false);
imqaOption.setDumpInterval(10000);
imqaOption.setFileInterval(5);
imqaOption.setHttpTracing(true);
io.imqa.mpm.IMQAMpmAgent.getInstance()
.setOption(imqaOption) // Sets an option to decide the MPM operation method.
.setContext(this, BuildConfig.FLAVOR)
// Initializes the application context. (Insert an empty string if there is no flavor)
.setProjectKey("PROJECT_KEY")
// Sets the project key of the IMQA MPM client.
.init();
// Initializes and executes the registered option.
...
}
...
...
override fun onCreate() {
super.onCreate()
val imqaOption : IMQAOption = io.imqa.core.IMQAOption()
imqaOption.setBuildType(false)
imqaOption.setUploadPeriod(true)
imqaOption.setKeepFileAtUploadFail(false)
imqaOption.setDumpInterval(10000)
imqaOption.setFileInterval(5)
imqaOption.setHttpTracing(true)
io.imqa.mpm.IMQAMpmAgent.getInstance()
.setOption(imqaOption)
// Sets an option to decide the MPM operation method.
.setContext(this, BuildConfig.FLAVOR)
// Initializes the application context. (Insert an empty string if there is no flavor)
.setProjectKey("PROJECT_KEY")
// Sets the project key of the IMQA MPM client.
.init();
// Initializes and executes the registered option.
...
}
...
MPM Mode Option
IMQA MPM実行オプションをパラメータやOptionを利用して変更することができます。Android MPM Configuration Optionsで実行オプションを確認してください。
短縮モード
短縮モードを利用すると、IMQA MPMを初期化することができます。
...
override fun onCreate() {
super.onCreate()
io.imqa.mpm.IMQAMpmAgent.getInstance()
.setContext(this, BuildConfig.FLAVOR) // Initializes the application context. (Insert an empty string if there is no flavor)
.setProjectKey("PROJECT_KEY") // Sets the project key of the IMQA MPM client.
.init() // Initializes and executes the registered option.
...
}
...
...
override fun onCreate() {
super.onCreate()
io.imqa.mpm.IMQAMpmAgent.getInstance()
.setContext(this, BuildConfig.FLAVOR) // Initializes the application context. (Insert an empty string if there is no flavor)
.setProjectKey("PROJECT_KEY") // Sets the project key of the IMQA MPM client.
.init() // Initializes and executes the registered option.
...
}
...
HTTPS (API level > 27)
Android API 28から強化されたネットワークセキュリティポリシーにより、HTTPSリクエストが必要となりました。 これを解決するためには、以下の措置を講じる必要があります。
認証されたHTTPSリクエスト IMQAサーバーで認証されたHTTPSのリクエストを行って正常に収集してください。
...
imqaOption.setServerUrl('https://collector.imqa.io');
...
強制HTTPリクエスト このflagを設定すると、すべてのcleartextトラフィックに対して許可処理を実行できます。
...
<application
...
android:usesCleartextTraffic="true"
/>
...
Zstandard圧縮アルゴリズムを使用
一般的なgzipではないセキュリティ性、圧縮効率が高くなったZstandard圧縮アルゴリズムを使用することができます。これを使用するためには、次の設定が必要です。(* Zstandard圧縮方式は有料版のみ利用可能です。)
MPM Mode Optionの設定 IMQAの開始コードを挿入するとき、設定においてzstdを使用するかどうかを設定することができます。
...
imqaOption.setCompressZstd(true);
...
Zstdライブラリに追加 「app.gradle」ファイルで「buildscript」内の「dependencies」ブロックに「zstd-jni」aarライブラリを追加します。
...
dependencies {
// Add dependencies.
...
implementation 'com.github.luben:zstd-jni:1.5.2-3@aar'
...
}
}
5. 現在のバージョンで発生する可能性のある不具合
ASM
ASMを使用するライブラリと衝突が発生することがあります。
APK Repackaging
APK Repackaging中にソースのライン情報が消えます。ライン情報を含めたい場合は、自動挿入機能をCompile中に実行する必要があります。
Library情報収集
Libraryに追加されたclassファイルは、自動挿入機能が実行されません。Libraryで実行される情報も収集したい場合は、自動挿入機能をAPK Repackaging中に実行してください。
6. インストール型顧客の必須設定事項
IMQAインストール型をご利用される顧客会社の場合、必ず収集サーバーを設定してください。
...
@Override
public void onCreate() {
super.onCreate();
io.imqa.core.IMQAOption imqaOption = new io.imqa.core.IMQAOption();
/*
* Default value: 'https://collector.imqa.io'
* Sets the MPM server URL.
* String: Server information
*/
imqaOption.setServerUrl('https://(IPAddress)');
io.imqa.mpm.IMQAMpmAgent.getInstance()
.setOption(imqaOption) // Sets the option to decide the MPM operation method.
.setContext(this, BuildConfig.FLAVOR) // AInitializes the application context. (Insert an empty string if there is no flavor)
.setProjectKey("PROJECT_KEY") // Sets the project key of the IMQA MPM client.
.init() // Initializes and executes the registered option.
...
}
...
Last updated