최근에 Google 앱의 minSdkVersion이 16 (Jellybean)에서 21 (Lollipop)으로 바뀌 었습니다. 우리가 주로 디버그 빌드를 사용하여 광범위하게 테스트 했음에도 불구하고, 우리는 이제 앱을 시작할 때 주로 오래된 삼성 장치 (주 3 및 S4가 최고 크래셔)와 항상 롤리팝에 대량 생산 충돌을 겪고 있습니다.Samsung Lollipop 기기에서 Android 앱이 다운되다 NoClassDefFoundError
오류가
Fatal Exception: java.lang.NoClassDefFoundError: com.retailconvergence.ruelala.delegate.GoogleLoginDelegate
at com.retailconvergence.ruelala.delegate.LifecycleDelegateManager.addDelegateOfType(LifecycleDelegateManager.java:48)
at com.retailconvergence.ruelala.extensions.activity.LifecycleDelegateActivity.addDelegateOfType(LifecycleDelegateActivity.java:55)
at com.retailconvergence.ruelala.activity.SplashActivity.setupDelegates(SplashActivity.java:198)
at com.retailconvergence.ruelala.activity.SplashActivity.onCreate(SplashActivity.java:60)
at android.app.Activity.performCreate(Activity.java:6288)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758)
at android.app.ActivityThread.access$900(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5942)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
SplashActivity는 응용 프로그램의 초기 런칭 활동이다. 발견되지 않은 클래스는 새로 도입 된 것이 아니라 오래 전에 설립 된 클래스입니다. 참고로,이 최신 릴리스의 일부로 Android Studio 3으로 업그레이드하고 Kotlin 코드를 도입했습니다. 그러나 이러한 문제는 관련이 없다고 생각합니다. 우리는 빌드에서 프로 가드를 사용하지 않습니다.
Dalvik 대신 ART를 사용하는 것과 관련하여 minSdkVersion이 21 이상일 때 빌드에 대한 중요한 변경 사항이 있음을 알고 있습니다. 따라서 여전히보고있는 삼성 Lollipop 장치의 결함이 있는지 궁금합니다. 이제 기본 dex 파일에있는 클래스에 대해?
모듈 수준 build.gradle : 응용 프로그램의 build.gradle에서
dexOptions {
preDexLibraries false
}
:
import java.text.SimpleDateFormat
import java.util.concurrent.TimeUnit
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'io.fabric'
apply plugin: 'spoon'
// Manifest version information
def versionMajor = 4
def versionMinor = 2
def versionPatch = 0
def versionBuild = 0 // bump for dogfood builds, public betas, etc.
ext.versionReleaseDate="OCT-13-2017" // UPDATE THIS WHEN YOU BUMP THE VERSIONS ABOVE FOR A NEW RELEASE MMM-dd-yyy
repositories {
mavenCentral()
maven { url 'https://maven.fabric.io/public' }
maven { url 'http://salesforce-marketingcloud.github.io/JB4A-SDK-Android/repository' }
maven { url "https://maven.google.com" }
maven { url "http://maven.tealiumiq.com/android/releases/" }
}
def getCountOfHoursSinceVersionUpdate() {
def currentDate = new Date()
def format = new SimpleDateFormat("MMM-dd-yyyy")
def buildDate = (Date)format.parse(versionReleaseDate)
return (Integer)((currentDate.getTime() - buildDate.getTime())/TimeUnit.HOURS.toMillis(1))
}
android {
compileSdkVersion 26
buildToolsVersion '26.0.1'
defaultConfig {
targetSdkVersion 25
/**
* Increment versionCode by commit count
*/
versionCode versionMajor * 100000 + versionMinor * 10000 + versionPatch * 1000 + versionBuild + getCountOfHoursSinceVersionUpdate()
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
// Enabling multidex support. :(
multiDexEnabled true
def manifestPath = project(':').file('app/src/androidTest/AndroidManifest.xml')
buildConfigField "String", "MANIFEST_PATH", "\"" + manifestPath + "\""
def resPath = project(':').file('app/src/main/res/')
buildConfigField "String", "RES_PATH", "\"" + resPath + "\""
def assetPath = project(':').file('app/src/prod/assets/')
buildConfigField "String", "ASSET_PATH", "\"" + assetPath + "\""
}
dexOptions {
javaMaxHeapSize "8g"
dexInProcess true // the magic line
}
flavorDimensions "debugDimension"
/**
* productFlavors override defaultConfig properties as well as force gradle to look in the new
* folders that we have created to differentiate the build assets and manifests.
* src/dev, src/prod
*/
productFlavors {
dev {
minSdkVersion 21
applicationId "com.retailconvergence.ruelala.dev"
versionName "${versionMajor}.${versionMinor}.0${versionPatch}"
manifestPlaceholders = [optimizelyId: "optly4740131949"]
dimension "debugDimension"
}
prod {
minSdkVersion 21
applicationId "com.retailconvergence.ruelala"
versionName "${versionMajor}.${versionMinor}.${versionPatch}"
manifestPlaceholders = [optimizelyId: "optly4752051515"]
dimension "debugDimension"
}
}
signingConfigs {
prod {
//the key is up a level, don't include in the modules
storeFile file("../RueLaLaKeystore")
storePassword "Boutiques"
keyAlias "rue la la"
keyPassword "Boutiques"
}
}
buildTypes {
release {
signingConfig signingConfigs.prod
ext.betaDistributionReleaseNotesFilePath = 'release_notes.txt'
ext.betaDistributionGroupAliases = 'AndroidTesters'
ext.betaDistributionNotifications = true
}
debug {
versionNameSuffix '-dev'
signingConfig signingConfigs.prod
// to get coverage report, set testCoverageEnabled to true and run gradle task called createDevelopmentDebugAndroidTestCoverageReport
// Note that test coverage doesn't seem to work on Samsung devices, other brand or emulator should work though
testCoverageEnabled = false
ext.betaDistributionReleaseNotesFilePath = 'release_notes.txt'
ext.betaDistributionGroupAliases = 'AndroidTesters'
ext.betaDistributionNotifications = true
}
}
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
exclude 'LICENSE.txt'
exclude 'LICENSE'
exclude 'READ.ME'
exclude 'README'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
configurations {
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
//include our modules
compile project(':core')
compile project(':data')
//android
final APP_COMPAT_VERSION = '26.1.0'
compile "com.android.support:appcompat-v7:$APP_COMPAT_VERSION"
compile "com.android.support:recyclerview-v7:$APP_COMPAT_VERSION"
compile "com.android.support:design:$APP_COMPAT_VERSION"
compile "com.android.support:multidex:1.0.0"
compile "com.android.support:cardview-v7:$APP_COMPAT_VERSION"
// google
final PLAY_SERVICES_VERSION = '10.2.4'
compile "com.google.android.gms:play-services-wallet:$PLAY_SERVICES_VERSION"
compile "com.google.android.gms:play-services-location:$PLAY_SERVICES_VERSION"
compile "com.google.android.gms:play-services-gcm:$PLAY_SERVICES_VERSION"
compile "com.google.android.gms:play-services-plus:$PLAY_SERVICES_VERSION"
compile "com.google.android.gms:play-services-identity:$PLAY_SERVICES_VERSION"
compile "com.google.android.gms:play-services-analytics:$PLAY_SERVICES_VERSION"
compile "com.google.android.gms:play-services-auth:$PLAY_SERVICES_VERSION"
compile "com.google.android.gms:play-services-maps:$PLAY_SERVICES_VERSION"
// facebook
compile 'com.facebook.android:facebook-android-sdk:4.8.+'
compile 'com.facebook.stetho:stetho:1.1.0'
//markdown4j
compile 'org.commonjava.googlecode.markdown4j:markdown4j:2.2-cj-1.0'
//crashlytics
compile('com.crashlytics.sdk.android:crashlytics:[email protected]') {
transitive = true;
}
//image zoom
compile 'com.github.chrisbanes.photoview:library:1.2.3'
//square
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.makeramen:roundedimageview:2.2.1'
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
compile 'com.jakewharton:butterknife:8.6.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.6.0'
// optimizely
compile('com.optimizely:optimizely:[email protected]') {
transitive = true
}
//braintree
compile 'com.braintreepayments.api:braintree:2.6.0'
compile 'com.braintreepayments.api:data-collector:2.+'
// guava
compile 'com.google.guava:guava:19.0'
// sticky headers
compile 'com.github.mtotschnig:StickyListHeaders:2.7.1'
// expandable recyclerview
compile 'eu.davidea:flexible-adapter:5.0.0-rc2'
//recyclerview animations
compile 'jp.wasabeef:recyclerview-animators:2.2.3'
// tooltip
compile 'com.github.michaelye.easydialog:easydialog:1.4'
// tealium
compile 'com.tealium:library:5.3.0'
// circle indicator
compile 'me.relex:circleindicator:[email protected]'
//testing
final HAMCREST_VERSION = '1.3'
def jUnit = "junit:junit:4.12"
// ExactTarget SDK
compile ('com.salesforce.marketingcloud:marketingcloudsdk:5.0.5') {
exclude module: 'android-beacon-library' //remove to use Proximity messaging
exclude module: 'play-services-location' //remove to use Geofence or Proximity messaging
}
androidTestCompile jUnit
// Unit tests dependencies
testCompile jUnit
testCompile "org.hamcrest:hamcrest-core:$HAMCREST_VERSION"
testCompile "org.hamcrest:hamcrest-library:$HAMCREST_VERSION"
testCompile "org.hamcrest:hamcrest-integration:$HAMCREST_VERSION"
testCompile 'org.robolectric:robolectric:3.1'
testCompile 'org.mockito:mockito-core:1.+'
testCompile 'com.google.guava:guava:19.0'
testCompile("com.android.support:support-v4:$APP_COMPAT_VERSION") {
exclude module: 'support-annotations'
}
testCompile('org.powermock:powermock-api-mockito:1.6.4') {
exclude module: 'objenesis'
}
testCompile('org.powermock:powermock-module-junit4:1.6.4') {
exclude module: 'objenesis'
}
testCompile 'io.reactivex:rxandroid:1.0.1'
testCompile 'io.reactivex:rxjava:1.1.0'
// Espresso
androidTestCompile('com.android.support.test:runner:0.5') {
exclude module: 'support-annotations'
}
androidTestCompile('com.android.support.test:rules:0.5') {
exclude module: 'support-annotations'
}
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2') {
exclude module: 'support-annotations'
}
androidTestCompile('com.android.support.test.espresso:espresso-intents:2.2.2') {
exclude module: 'support-annotations'
}
androidTestCompile('com.android.support.test.espresso:espresso-web:2.2.2') {
exclude module: 'support-annotations'
}
androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2.2') {
exclude module: 'support-annotations'
exclude module: 'recyclerview-v7'
exclude module: 'appcompat-v7'
exclude module: 'design'
exclude module: 'support-v4'
}
// allows java 8 compile
compile 'com.annimon:stream:1.1.2'
// For taking screenshots
androidTestCompile 'com.squareup.spoon:spoon-client:1.7.0'
testCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
compile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
}
apply plugin: 'com.google.gms.google-services'
spoon {
noAnimations = true
grantAllPermissions = true
}
apply plugin: 'devicefarm'
devicefarm {
projectName "Rue Mobile"
devicePool "Smoke Test Pool"
useUnmeteredDevices()
authentication {
accessKey System.getenv("AWS_DEVICE_FARM_ACCESS_KEY")
secretKey System.getenv("AWS_DEVICE_FARM_SECRET_KEY")
}
}