android 调试中的结构初始化非常慢
very slow fabric initialization in android debug
我正在尝试在 android 上集成 fabric(包括 crashlytics 和 NDK 支持和答案),我让它们工作了。
但是,当我尝试调试我的应用程序时,fabric 需要很长时间(大约 500 万)才能完成它的工作。
这是日志:
10-16 11:41:49.680 1534-1559/? V/WindowManager: Relayout Window{326db3dd0 u0 Starting app.company.com}: viewVisibility=0 req=2048x1536 WM.LayoutParams{(0,0)(fillxfill) sim=#20 ty=3 fl=#81830518 pfl=0x20011 wanim=0x103038a vsysui=0x600 needsMenuKey=2 naviIconColor=0}
10-16 11:41:49.701 1534-1559/? D/WindowManager: finishDrawingWindow: Window{326db3dd0 u0 Starting app.company.com} mDrawState=DRAW_PENDING
10-16 11:41:49.714 1534-1559/? I/WindowManager: Screen frozen for +113ms due to Window{326db3dd0 u0 Starting app.company.com}
10-16 11:41:49.945 21418-21684/app.company.com W/art: Verification of io.fabric.sdk.android.services.settings.Settings io.fabric.sdk.android.services.settings.Settings.initialize(io.fabric.sdk.android.Kit, io.fabric.sdk.android.services.common.IdManager, io.fabric.sdk.android.services.network.HttpRequestFactory, java.lang.String, java.lang.String, java.lang.String) took 173.644ms
10-16 11:44:51.139 21418-21684/app.company.com W/art: Verification of boolean io.fabric.sdk.android.services.settings.Settings.loadSettingsSkippingCache() took 181.194s
10-16 11:44:51.164 21418-21418/app.company.com D/libcrashlytics: Initializing libcrashlytics version 1.1.5
10-16 11:44:51.165 21418-21418/app.company.com D/libcrashlytics: Attempting to load unwinder...
10-16 11:49:24.955 21418-21684/app.company.com W/art: Verification of java.lang.String io.fabric.sdk.android.services.common.AbstractSpiCall.overrideProtocolAndHost(java.lang.String) took 303.615ms
10-16 11:49:25.366 21418-21418/app.company.com D/libcrashlytics: Done; using libunwind
10-16 11:49:25.366 21418-21418/app.company.com D/libcrashlytics: Attempting to register signal handler...
10-16 11:49:25.367 21418-21418/app.company.com D/libcrashlytics: Signal handler registered.
10-16 11:49:25.370 21418-21418/app.company.com D/libcrashlytics: Initializing native crash handling successful.
如您所见,
Verification of boolean io.fabric.sdk.android.services.settings.Settings.loadSettingsSkippingCache() took 181.194s
花了将近300万,
Attempting to load unwinder...
也赚了300万
当我尝试在没有附加调试器的情况下启动应用程序时(只是 运行 而不是在 android studio 中进行调试),应用程序启动得很好。
任何关于在哪里寻找这个问题的指导将不胜感激。
吉扬
编辑 1:
稍加挖掘后,实际上是 JniNativeApi 调用
System.loadLibrary("crashlytics");
首先,这需要很多时间。第二次冻结还不知道。
这很奇怪,因为图书馆看起来很轻(libcrashlytics.so 大约 600ko)
编辑 2:
这是我的 gradle 构建的结构:
在顶层 proj.android 文件夹中有一个 build.gradle,其中包含所有子项目通用的所有配置选项(abiFilters、minSdkVersion ...):
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
ext {
minSdkVersion = 24
targetSdkVersion = 26
compileSdkVersion = 26
buildToolsVersion = '26.0.1'
abiFilters = [
'XXX'
]
cppDebugFlags = [
'YYYYYY'
]
cppReleaseFlags = [
'ZZZZZ'
]
arguments = [
'-DANDROID_TOOLCHAIN=clang',
'-DANDROID_PLATFORM=android-24',
'-DANDROID_STL=c++_static',
'-DANDROID_CPP_FEATURES=rtti exceptions'
]
}
task wrapper(type: Wrapper) {
gradleVersion = '4.1'
}
task clean(type: Delete) {
delete 'stuff'
}
然后我的所有子项目都有一个 build.gradle 文件(1 com.android.application 和 4 com.android.library)
我认为库 build.gradle 文件不相关,因为我没有在其中放置任何与结构相关的初始化,所以这是我的 build.gradle 主要应用程序:
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
// These docs use an open ended version so that our plugin
// can be updated quickly in response to Android tooling updates
// We recommend changing it to the latest version from our changelog:
// https://docs.fabric.io/android/changelog.html#fabric-gradle-plugin
classpath 'io.fabric.tools:gradle:1.24.2'
}
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
repositories {
maven { url 'https://maven.fabric.io/public' }
}
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
sourceSets.main {
res.srcDir "res"
assets.srcDirs 'sources'
jniLibs.srcDirs "jni"
java.srcDirs "java sources dirs"
manifest.srcFile "AndroidManifest.xml"
}
defaultConfig {
applicationId 'app.company.com'
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 2
versionName '0.1'
ndk {
moduleName "moduleName"
abiFilters rootProject.ext.abiFilters.join(",").split(",")
}
externalNativeBuild {
cmake {
cppFlags rootProject.ext.cppReleaseFlags.join(",").split(",")
arguments rootProject.ext.arguments.join(",").split(",")
targets "target"
}
}
}
buildTypes {
debug {
externalNativeBuild {
cmake {
cppFlags rootProject.ext.cppDebugFlags.join(",").split(",")
}
// to do: swap those two lines when when debug testing will be done
ext.alwaysUpdateBuildId = false // Whosebug NOTE: commenting this line doesn't change anything to the problem
//ext.enableCrashlytics = false
}
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "../../CMakeLists.txt"
}
}
aaptOptions {
cruncherEnabled = false
noCompress 'zspine', 'zparticles', 'gz'
}
}
crashlytics {
enableNdk true
manifestPath 'AndroidManifest.xml'
// are these needed?
// Whosebug NOTE: I tried put the values that are given in the docs, but it doesn't seems to change anything
//androidNdkOut 'build/intermediates/cmake/release/obj'
//androidNdkLibsOut 'build/intermediates/bundles/default/jni'
}
// Whosebug NOTE: here are some task definition to automatically update sources, I don't think they are relevant to the matter at hand
...
dependencies {
compile fileTree(dir:'someJars')
compile('com.crashlytics.sdk.android:crashlytics:2.7.0@aar') {
transitive = true;
}
compile('com.crashlytics.sdk.android:crashlytics-ndk:1.1.6@aar') {
transitive = true;
}
debugCompile project(path: ':lib1', configuration: 'debug')
debugCompile project(path: ':lib2', configuration: 'debug')
debugCompile project(path: ':lib3', configuration: 'debug')
debugCompile project(path: ':lib4', configuration: 'debug')
releaseCompile project(path: ':lib1', configuration: 'release')
releaseCompile project(path: ':lib2', configuration: 'release')
releaseCompile project(path: ':lib3', configuration: 'release')
releaseCompile project(path: ':lib4', configuration: 'release')
}
我还在清单中添加了
中的 api 键
...
<application android:label="@string/app_name"
android:icon="@drawable/icon">
<!-- name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="name" />
<meta-data android:name="io.fabric.ApiKey"
android:value="API Key"
/>
...
最后我在 activity 的 onCreate 方法中设置 Fabric,如下所示:
// TODO uncomment this when testing's over
//Crashlytics crashlyticsKit = new Crashlytics.Builder().core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build()).build();
//Fabric.with(this, crashlyticsKit);
Fabric fabric = new Fabric.Builder(this).kits(new Crashlytics(), new CrashlyticsNdk())
.debuggable(true)
.build();
Fabric.with(fabric);
非常感谢您的快速回答,希望补充信息对您有所帮助!
编辑 3
我在几个设备上测试过(galaxy tab s3 @7.0 & google pixel C @7.1.1),没有任何区别,问题仍然存在。
我现在不太清楚,但是我重新启动笔记本电脑后问题就消失了。我猜这与 adb 调试器不知何故卡住了有关?
我正在尝试在 android 上集成 fabric(包括 crashlytics 和 NDK 支持和答案),我让它们工作了。
但是,当我尝试调试我的应用程序时,fabric 需要很长时间(大约 500 万)才能完成它的工作。
这是日志:
10-16 11:41:49.680 1534-1559/? V/WindowManager: Relayout Window{326db3dd0 u0 Starting app.company.com}: viewVisibility=0 req=2048x1536 WM.LayoutParams{(0,0)(fillxfill) sim=#20 ty=3 fl=#81830518 pfl=0x20011 wanim=0x103038a vsysui=0x600 needsMenuKey=2 naviIconColor=0}
10-16 11:41:49.701 1534-1559/? D/WindowManager: finishDrawingWindow: Window{326db3dd0 u0 Starting app.company.com} mDrawState=DRAW_PENDING
10-16 11:41:49.714 1534-1559/? I/WindowManager: Screen frozen for +113ms due to Window{326db3dd0 u0 Starting app.company.com}
10-16 11:41:49.945 21418-21684/app.company.com W/art: Verification of io.fabric.sdk.android.services.settings.Settings io.fabric.sdk.android.services.settings.Settings.initialize(io.fabric.sdk.android.Kit, io.fabric.sdk.android.services.common.IdManager, io.fabric.sdk.android.services.network.HttpRequestFactory, java.lang.String, java.lang.String, java.lang.String) took 173.644ms
10-16 11:44:51.139 21418-21684/app.company.com W/art: Verification of boolean io.fabric.sdk.android.services.settings.Settings.loadSettingsSkippingCache() took 181.194s
10-16 11:44:51.164 21418-21418/app.company.com D/libcrashlytics: Initializing libcrashlytics version 1.1.5
10-16 11:44:51.165 21418-21418/app.company.com D/libcrashlytics: Attempting to load unwinder...
10-16 11:49:24.955 21418-21684/app.company.com W/art: Verification of java.lang.String io.fabric.sdk.android.services.common.AbstractSpiCall.overrideProtocolAndHost(java.lang.String) took 303.615ms
10-16 11:49:25.366 21418-21418/app.company.com D/libcrashlytics: Done; using libunwind
10-16 11:49:25.366 21418-21418/app.company.com D/libcrashlytics: Attempting to register signal handler...
10-16 11:49:25.367 21418-21418/app.company.com D/libcrashlytics: Signal handler registered.
10-16 11:49:25.370 21418-21418/app.company.com D/libcrashlytics: Initializing native crash handling successful.
如您所见,
Verification of boolean io.fabric.sdk.android.services.settings.Settings.loadSettingsSkippingCache() took 181.194s
花了将近300万,
Attempting to load unwinder...
也赚了300万
当我尝试在没有附加调试器的情况下启动应用程序时(只是 运行 而不是在 android studio 中进行调试),应用程序启动得很好。
任何关于在哪里寻找这个问题的指导将不胜感激。
吉扬
编辑 1:
稍加挖掘后,实际上是 JniNativeApi 调用
System.loadLibrary("crashlytics");
首先,这需要很多时间。第二次冻结还不知道。
这很奇怪,因为图书馆看起来很轻(libcrashlytics.so 大约 600ko)
编辑 2:
这是我的 gradle 构建的结构:
在顶层 proj.android 文件夹中有一个 build.gradle,其中包含所有子项目通用的所有配置选项(abiFilters、minSdkVersion ...):
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
ext {
minSdkVersion = 24
targetSdkVersion = 26
compileSdkVersion = 26
buildToolsVersion = '26.0.1'
abiFilters = [
'XXX'
]
cppDebugFlags = [
'YYYYYY'
]
cppReleaseFlags = [
'ZZZZZ'
]
arguments = [
'-DANDROID_TOOLCHAIN=clang',
'-DANDROID_PLATFORM=android-24',
'-DANDROID_STL=c++_static',
'-DANDROID_CPP_FEATURES=rtti exceptions'
]
}
task wrapper(type: Wrapper) {
gradleVersion = '4.1'
}
task clean(type: Delete) {
delete 'stuff'
}
然后我的所有子项目都有一个 build.gradle 文件(1 com.android.application 和 4 com.android.library)
我认为库 build.gradle 文件不相关,因为我没有在其中放置任何与结构相关的初始化,所以这是我的 build.gradle 主要应用程序:
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
// These docs use an open ended version so that our plugin
// can be updated quickly in response to Android tooling updates
// We recommend changing it to the latest version from our changelog:
// https://docs.fabric.io/android/changelog.html#fabric-gradle-plugin
classpath 'io.fabric.tools:gradle:1.24.2'
}
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
repositories {
maven { url 'https://maven.fabric.io/public' }
}
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
sourceSets.main {
res.srcDir "res"
assets.srcDirs 'sources'
jniLibs.srcDirs "jni"
java.srcDirs "java sources dirs"
manifest.srcFile "AndroidManifest.xml"
}
defaultConfig {
applicationId 'app.company.com'
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 2
versionName '0.1'
ndk {
moduleName "moduleName"
abiFilters rootProject.ext.abiFilters.join(",").split(",")
}
externalNativeBuild {
cmake {
cppFlags rootProject.ext.cppReleaseFlags.join(",").split(",")
arguments rootProject.ext.arguments.join(",").split(",")
targets "target"
}
}
}
buildTypes {
debug {
externalNativeBuild {
cmake {
cppFlags rootProject.ext.cppDebugFlags.join(",").split(",")
}
// to do: swap those two lines when when debug testing will be done
ext.alwaysUpdateBuildId = false // Whosebug NOTE: commenting this line doesn't change anything to the problem
//ext.enableCrashlytics = false
}
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "../../CMakeLists.txt"
}
}
aaptOptions {
cruncherEnabled = false
noCompress 'zspine', 'zparticles', 'gz'
}
}
crashlytics {
enableNdk true
manifestPath 'AndroidManifest.xml'
// are these needed?
// Whosebug NOTE: I tried put the values that are given in the docs, but it doesn't seems to change anything
//androidNdkOut 'build/intermediates/cmake/release/obj'
//androidNdkLibsOut 'build/intermediates/bundles/default/jni'
}
// Whosebug NOTE: here are some task definition to automatically update sources, I don't think they are relevant to the matter at hand
...
dependencies {
compile fileTree(dir:'someJars')
compile('com.crashlytics.sdk.android:crashlytics:2.7.0@aar') {
transitive = true;
}
compile('com.crashlytics.sdk.android:crashlytics-ndk:1.1.6@aar') {
transitive = true;
}
debugCompile project(path: ':lib1', configuration: 'debug')
debugCompile project(path: ':lib2', configuration: 'debug')
debugCompile project(path: ':lib3', configuration: 'debug')
debugCompile project(path: ':lib4', configuration: 'debug')
releaseCompile project(path: ':lib1', configuration: 'release')
releaseCompile project(path: ':lib2', configuration: 'release')
releaseCompile project(path: ':lib3', configuration: 'release')
releaseCompile project(path: ':lib4', configuration: 'release')
}
我还在清单中添加了
中的 api 键...
<application android:label="@string/app_name"
android:icon="@drawable/icon">
<!-- name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="name" />
<meta-data android:name="io.fabric.ApiKey"
android:value="API Key"
/>
...
最后我在 activity 的 onCreate 方法中设置 Fabric,如下所示:
// TODO uncomment this when testing's over
//Crashlytics crashlyticsKit = new Crashlytics.Builder().core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build()).build();
//Fabric.with(this, crashlyticsKit);
Fabric fabric = new Fabric.Builder(this).kits(new Crashlytics(), new CrashlyticsNdk())
.debuggable(true)
.build();
Fabric.with(fabric);
非常感谢您的快速回答,希望补充信息对您有所帮助!
编辑 3
我在几个设备上测试过(galaxy tab s3 @7.0 & google pixel C @7.1.1),没有任何区别,问题仍然存在。
我现在不太清楚,但是我重新启动笔记本电脑后问题就消失了。我猜这与 adb 调试器不知何故卡住了有关?