there's an option to attach a debugger to an installed app from android studio
I used to use it but, recently I joined a new company and it's not working showing me that error after selecting the process
this is my Gradle code I've:
plugins {
id("com.android.application")
id("kotlin-android")
id("kotlin-android-extensions")
id("kotlin-kapt")
id("androidx.navigation.safeargs")
id("com.google.firebase.firebase-perf")
id("com.google.firebase.crashlytics")
id("com.google.firebase.appdistribution")
id("com.github.triplet.play") version "2.8.0"
}
android {
compileSdkVersion 30
buildToolsVersion '30.0.3'
ndkVersion '21.3.6528147'
defaultConfig {
ndk.abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
applicationId "xxx.xxx.xxx"
minSdkVersion 21
targetSdkVersion 30
versionCode gitVersionCode
versionName gitVersionName
multiDexEnabled true
vectorDrawables.useSupportLibrary = true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {
arguments += ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}
testOptions {
animationsDisabled = true
}
sourceSets {
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
}
signingConfigs {
appGallery{
keyAlias "XXXXX"
keyPassword "XXXXX"
storeFile file("XXXXX")
storePassword "XXXXX"
}
playStore {
keyAlias "XXXXX"
keyPassword "XXXXX"
storeFile file("XXXXX")
storePassword "XXXXX"
}
config {
storeFile file("XXXXX")
storePassword "XXXXX"
keyPassword "XXXXX"
keyAlias "XXXXX"
}
}
lintOptions {
checkReleaseBuilds false
abortOnError false
}
bundle {
language {
enableSplit = false
}
}
buildTypes {
debug {
signingConfig signingConfigs.config
getIsDefault().set(true)
minifyEnabled false
debuggable true
jniDebuggable false
shrinkResources false
zipAlignEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro', '$playcoreDir/proguard/common.pgcfg', '$playcoreDir/proguard/per-feature-proguard-files'
manifestPlaceholders = [isEnableCrashReporting: "false"]
}
release {
signingConfig signingConfigs.config
minifyEnabled true
shrinkResources true
zipAlignEnabled true
debuggable false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro', '$playcoreDir/proguard/common.pgcfg', '$playcoreDir/proguard/per-feature-proguard-files'
manifestPlaceholders = [isEnableCrashReporting: "true"]
}
unitTestVariants.all {
it.mergedFlavor.manifestPlaceholders += [isEnableCrashReporting: "false"]
}
externalNativeBuild {
ndkBuild {
path 'src/main/jni/Android.mk'
}
}
}
flavorDimensions "audience"
productFlavors {
appGallery {
dimension "audience"
setProperty("archivesBaseName", "XXX")
signingConfig signingConfigs.appGallery
buildConfigField "String", "BASE_URL", "\"XXXXX\""
firebaseAppDistribution {
releaseNotes = "Version XXXXX"
serviceCredentialsFile = file(firebaseServiceAcc)
appId = firebaseAppId
groups = "XXXX"
apkPath = "app/build/outputs/apk/appGallery/release/XXX-appGallery-release.apk"
}
}
playStore {
dimension "audience"
setProperty("archivesBaseName", "XXX")
buildConfigField "String", "BASE_URL", "\"XXXXX\""
signingConfig signingConfigs.playStore
}
staging {
dimension "audience"
getIsDefault().set(true)
signingConfig signingConfigs.playStore
setProperty("archivesBaseName", "XXX")
versionNameSuffix "-Staging"
buildConfigField "String", "BASE_URL", "\"XXXX\""
firebaseAppDistribution {
releaseNotes = "Development Version\nUrl : XXXXX"
serviceCredentialsFile = file(firebaseServiceAcc)
appId = firebaseAppId
groups = "XXXXX"
apkPath = "app/build/outputs/apk/staging/release/XXX-staging-release.apk"
}
}
}
buildFeatures {
dataBinding true
}
testOptions {
unitTests.includeAndroidResources = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/ASL2.0'
exclude("META-INF/*.kotlin_module")
}
}
play {
serviceAccountCredentials = file(googlePlayServiceAcc)
track = "beta"
defaultToAppBundles = true
resolutionStrategy = "auto"
releaseStatus = "completed"
updatePriority = 5
userFraction = 1.0
}
dependencies {
// my libs
}
apply plugin: 'com.google.gms.google-services'
so, it'd be nice if anyone helped me to solve this issue
HINT: normal debug run working but, it's taking time to build & run in debug mode
Related
I am using Android's Dynamic delivery for one of my feature. I have separated the code for the feature. I am also using the Navigation component in my project.
I can see dynamicfeature being downloaded from the progress bar and after downloading I am using Navigation component to navigate to Fragment2.
However, when I am trying to navigate from Fragment1 which is in my "app" to Fragment2 which is in my "dynamicfeature" I am getting below exception.
Fatal Exception: android.content.res.Resources$NotFoundException: com.sample.sample.debug.dynamicfeature:navigation/dynamic_feature_nav
at androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.replaceWithIncludedNav(DynamicIncludeGraphNavigator.kt:95)
at androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.navigate(DynamicIncludeGraphNavigator.kt:79)
at androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.navigate(DynamicIncludeGraphNavigator.kt:40)
at androidx.navigation.NavController.navigate(NavController.java:1049)
at androidx.navigation.NavController.navigate(NavController.java:935)
at androidx.navigation.NavController.navigate(NavController.java:868)
at androidx.navigation.NavController.navigate(NavController.java:854)
at androidx.navigation.NavController.navigate(NavController.java:1107)
at com.compass.corelibrary.extensions.NavControllerExtensionsKt.navigateSafeSource(NavControllerExtensions.kt:18)
My app's build.gradle file is like this
apply plugin: 'com.android.application'
apply plugin: 'com.google.firebase.firebase-perf'
apply plugin: 'com.heapanalytics.android'
apply plugin: 'kotlin-android'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'com.compass.jacoco.jacoco-android'
apply plugin: "androidx.navigation.safeargs.kotlin"
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'
apply plugin: 'jacoco'
apply plugin: 'kotlinx-serialization'
ext.versionMajor = 2
ext.versionMinor = 35
ext.versionPatch = 0
ext.minimumSdkVersion = 21
android {
compileSdkVersion 31
defaultConfig {
applicationId "com.sample.sample"
minSdkVersion project.ext.minimumSdkVersion
targetSdkVersion 31
versionCode Integer.parseInt(project.VERSION_CODE)
versionName project.VERSION_NAME
testInstrumentationRunner "com.sample.SampleAndroidJUnitRunner"
ext {
heapEnabled = true
heapAutoInit = true
heapEnvId = HEAP_KEY_GAMMA
}
}
signingConfigs {
beta {
keyAlias "circleci-beta-key-alias"
keyPassword "password"
storeFile file("circleci-beta-key.keystore")
storePassword "password"
}
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/ASL2.0'
exclude 'META-INF/kotlinx-coroutines-core.kotlin_module'
exclude 'META-INF/kotlinx-serialization-runtime.kotlin_module'
}
flavorDimensions "version"
productFlavors {
debugFlavor {
getIsDefault().set(true)
dimension "version"
applicationIdSuffix ".debug"
matchingFallbacks = ["release", "debug"]
manifestPlaceholders = [
auth0Domain: "#string/com_auth0_domain_staging",
auth0Scheme: "sample",
facebookLoginProtocolScheme: "#string/fb_login_protocol_scheme_staging",
facebookAppId: "#string/facebook_app_id_staging",
facebookProvider: "#string/facebook_provider_staging"
]
}
alphaFlavor {
dimension "version"
applicationIdSuffix ".alpha"
matchingFallbacks = ["release", "debug"]
manifestPlaceholders = [
auth0Domain: "#string/com_auth0_domain_staging",
auth0Scheme: "sample",
facebookLoginProtocolScheme: "#string/fb_login_protocol_scheme_staging",
facebookAppId: "#string/facebook_app_id_staging",
facebookProvider: "#string/facebook_provider_staging"
]
}
betaFlavor {
dimension "version"
applicationIdSuffix ".beta"
matchingFallbacks = ["release", "debug"]
manifestPlaceholders = [
auth0Domain: "#string/com_auth0_domain_staging",
auth0Scheme: "sample",
facebookLoginProtocolScheme: "#string/fb_login_protocol_scheme_staging",
facebookAppId: "#string/facebook_app_id_staging",
facebookProvider: "#string/facebook_provider_staging"
]
}
rcFlavor {
dimension "version"
applicationIdSuffix ".rc"
matchingFallbacks = ["release", "debug"]
manifestPlaceholders = [
auth0Domain: "#string/com_auth0_domain_staging",
auth0Scheme: "sample",
facebookLoginProtocolScheme: "#string/fb_login_protocol_scheme_staging",
facebookAppId: "#string/facebook_app_id_staging",
facebookProvider: "#string/facebook_provider_staging"
]
}
playStoreFlavor {
dimension "version"
matchingFallbacks = ["release", "debug"]
manifestPlaceholders = [
auth0Domain: "#string/com_auth0_domain_prod",
auth0Scheme: "compass",
facebookLoginProtocolScheme: "#string/fb_login_protocol_scheme_prod",
facebookAppId: "#string/facebook_app_id_prod",
facebookProvider: "#string/facebook_provider_prod"
]
ext.heapEnvId = HEAP_KEY_PRODUCTION
}
}
buildTypes {
debug {
getIsDefault().set(true)
debuggable true
multiDexEnabled true
signingConfig signingConfigs.beta
matchingFallbacks = ["release", "debug"]
buildConfigField "boolean", "ENABLE_LEAK_CANARY", enableLeakCanary
testCoverageEnabled false
FirebasePerformance {
instrumentationEnabled false
}
}
release {
minifyEnabled true
shrinkResources true
productFlavors.alphaFlavor.signingConfig signingConfigs.beta
productFlavors.betaFlavor.signingConfig signingConfigs.beta
productFlavors.rcFlavor.signingConfig signingConfigs.beta
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
matchingFallbacks = ["release", "debug"]
}
}
dexOptions {
javaMaxHeapSize "4g"
}
testOptions {
unitTests {
includeAndroidResources = true
// Added to ensure timezone is America/New_York for testing purposes
all{
jvmArgs '-Duser.timezone=America/New_York'
systemProperty 'robolectric.dependency.repo.url', 'https://repo1.maven.org/maven2'
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets {
androidTest { java.srcDirs = ['src/androidTest/kotlin'] }
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
buildFeatures {
viewBinding true
dataBinding true
compose true
}
composeOptions {
kotlinCompilerExtensionVersion '1.0.5'
}
dynamicFeatures = [':dynamicfeature']
preBuild.dependsOn ktlintFormat
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//All the dependencies are here.
}
My Dynamic Feature build.gradle looks like
apply plugin: 'com.android.dynamic-feature'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'androidx.navigation.safeargs.kotlin'
android {
compileSdk 31
defaultConfig {
minSdk 21
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
debug {
getIsDefault().set(true)
debuggable true
matchingFallbacks = ["release", "debug"]
}
release {
matchingFallbacks = ["release", "debug"]
}
}
flavorDimensions "version"
productFlavors {
debugFlavor {
getIsDefault().set(true)
dimension "version"
matchingFallbacks = ["release", "debug"]
}
alphaFlavor {
dimension "version"
matchingFallbacks = ["release", "debug"]
}
betaFlavor {
dimension "version"
matchingFallbacks = ["release", "debug"]
}
rcFlavor {
dimension "version"
matchingFallbacks = ["release", "debug"]
}
playStoreFlavor {
dimension "version"
matchingFallbacks = ["release", "debug"]
}
}
buildFeatures {
viewBinding true
dataBinding true
}
}
dependencies {
implementation project(':app')
}
I am navigating to Fragment2 which is in "dynamicfeature" from Fragment1 which is in "app". Fragment1 is hosted by MainActivity which is in "app".
My app's navigation graph has entry as
<include-dynamic
android:id="#+id/me_dynamic_feature"
app:moduleName="dynamicfeature"
app:graphResName="dynamic_feature_nav"
app:graphPackage="${applicationId}.dynamicfeature" />
I was able to resolve this issue. Apparently, if you use <include-dynamic> tag for navigating into the dynamic feature module. You have to specify ProgressFragment which extends AbstractProgressFragment and specify it as app:progressDestination.
Also since Fragment1 is in base app, which is hosted by activity in base app. We need to override attachBaseContext method in this activity too like below. This will fix the case where same exception was occurring at the subsequent launch.
override fun attachBaseContext(newBase: Context) {
super.attachBaseContext(newBase)
SplitCompat.installActivity(this)
}
I have to value in the app module BuildConfig, but I want to use this value from the other module. how can I do it?
1-This is app Gradle:
applicationVariants.all { variant ->
def privacyUrl = "https://www.google.com/privacy-policy"
def termsUrl = "https://www.gogle.com/terms-of-service/"
variant.buildConfigField "String", "URL_PRIVACY_POLICY", "\"${privacyUrl}\""
variant.buildConfigField "String", "URL_TERMS_OF_USE", "\"${termsUrl}\""
if (variant.name.startsWith("development")) {
def domain = "https://api.dev.google.com/"
def countryCode = "+63"
variant.buildConfigField "String", "BASE_URL", "\"${domain}\""
variant.buildConfigField "String", "COUNTRY_CODE", "\"${countryCode}\""
} else if (variant.name.startsWith("staging")) {
def domain = "https://api.stage.google.com/"
def countryCode = "+0000"
variant.buildConfigField "String", "COUNTRY_CODE", "\"${countryCode}\""
variant.buildConfigField "String", "BASE_URL", "\"${domain}\""
}
//production
else {
def domain = "https://api.google.com/"
def countryCode = "+000"
variant.buildConfigField "String", "BASE_URL", "\"${domain}\""
variant.buildConfigField "String", "COUNTRY_CODE", "\"${countryCode}\""
}
}
2-This is profile module gradle:
android {
compileSdk Versions.compile_sdk_version
defaultConfig {
minSdk Versions.min_sdk_version
targetSdk Versions.target_sdk_version
versionCode Versions.version_code
versionName Versions.version_name
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
enableCompose(this)
}
I want to use privacyUrl and termsUrl in the profile module but I don't have access to the app module BuldConfig
I am facing this error during the build:
"D8 does not support main-dex inputs and outputs when compiling to API level 21 and above"
If i set minifyEnabled to true in debug buildType everything works fine, but if i set it to false i just get this error.
My gradle file:
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.generalbytes.batm"
minSdkVersion 17
targetSdkVersion 22
multiDexEnabled true
ndk {
abiFilters 'armeabi-v7a'
}
}
useLibrary 'org.apache.http.legacy'
testOptions {
unitTests.all {
enabled !useDummyBitRafael.toBoolean()
}
}
signingConfigs {
release {
storeFile rootProject.file(releaseStoreFile)
storePassword releaseStorePassword
keyAlias releaseKeyAlias
keyPassword releaseKeyPassword
}
debug {
storeFile rootProject.file(releaseStoreFile)
storePassword releaseStorePassword
keyAlias releaseKeyAlias
keyPassword releaseKeyPassword
}
}
buildFeatures {
dataBinding = true
viewBinding = true
}
buildTypes {
debug {
minifyEnabled false
}
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
lintOptions {
tasks.lint.enabled = false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
testOptions {
unitTests.returnDefaultValues = true
}
Any ideas?
I just click "refresh gradle dependencies" from Android studio Gradle view and then the problem disappear.
I do not know why this problem happened I opened my android studio and it does not load the view of my RecyclerView and some other widgets, since I cleaned the cache also used the Rebuild Project but the problem persists, I would appreciate your support
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:scrollbarStyle="outsideOverlay"
android:scrollbarThumbVertical="#android:color/transparent"
android:scrollbars="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:listitem="#layout/item_list_specialties_list"
tools:itemCount="6"
tools:layoutManager="android.support.v7.widget.LinearLayoutManager"
tools:spanCount="1" />
</RelativeLayout>
here is the buildgradle
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
apply from: "$rootProject.rootDir/app/config.gradle" //Compile Play Store
//apply from: "$rootProject.rootDir/app/config-share-fabric.gradle" //Compile Fabric
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file("keystore.properties")
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
def serverProperties = new Properties()
def serverPropertiesFile = rootProject.file("server.properties")
serverProperties.load(new FileInputStream(serverPropertiesFile))
def configuration = ext.configuration
def configurationUser = ext.configurationUser
def configurationSpecialist = ext.configurationSpecialist
def configurationSeller = ext.configurationSeller
android {
compileSdkVersion configuration.compileSdk
buildToolsVersion configuration.buildTools
defaultConfig {
applicationId configuration.applicationId
minSdkVersion configuration.minimumSdk
targetSdkVersion configuration.targetSdk
vectorDrawables.useSupportLibrary = true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testHandleProfiling true
testFunctionalTest true
multiDexEnabled true
resConfigs("es", "en")
manifestPlaceholders = [
projectName : configuration.projectName,
fabricApiKey: "17fdb5821b7ac5a50e3250fb679a180d9ab54889"
]
resValue("string", "project_name", "\"${configuration.projectName}\"")
// Used by Room, to test migrations
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation":
"$projectDir/schemas".toString()]
}
}
}
//See https://stackoverflow.com/a/36931232
/*sourceSets {
main {
res.srcDirs = [
'src/main/res',
'src/main/res/drawable',
'src/main/res/drawable/splash',
'src/main/res/drawable/selectors'
]
}
}*/
signingConfigs {
debug {
keyAlias keystoreProperties['keyAliasDebug']
keyPassword keystoreProperties['keyPasswordDebug']
storeFile file(keystoreProperties['storeFileDebug'])
storePassword keystoreProperties['storePasswordDebug']
}
configReleaseUser {
keyAlias keystoreProperties['keyAliasUser']
keyPassword keystoreProperties['keyPasswordUser']
storeFile file(keystoreProperties['storeFileUser'])
storePassword keystoreProperties['storePasswordUser']
}
configReleaseSpecialist {
keyAlias keystoreProperties['keyAliasSpecialist']
keyPassword keystoreProperties['keyPasswordSpecialist']
storeFile file(keystoreProperties['storeFileSpecialist'])
storePassword keystoreProperties['storePasswordSpecialist']
}
configReleaseSeller {
keyAlias keystoreProperties['keyAliasSeller']
keyPassword keystoreProperties['keyPasswordSeller']
storeFile file(keystoreProperties['storeFileSeller'])
storePassword keystoreProperties['storePasswordSeller']
}
}
flavorDimensions "app", "server"
productFlavors {
user {
dimension "app"
applicationId configurationUser.applicationId
versionCode configurationUser.versionCode
versionName "${configurationUser.versionMajor}.${configurationUser.versionMinor}" +
".${configurationUser.versionPath}-${configurationUser.versionClasifier}"
proguardFile 'user-proguard-rules.pro'
testApplicationId "pe.com.linkup.android.test.user"
}
specialist {
dimension "app"
applicationId configurationSpecialist.applicationId
versionCode configurationSpecialist.versionCode
versionName "${configurationSpecialist.versionMajor}.${configurationSpecialist.versionMinor}" +
".${configurationSpecialist.versionPath}-${configurationSpecialist.versionClasifier}"
proguardFile 'specialist-proguard-rules.pro'
testApplicationId "pe.com.linkup.android.test.specialist"
}
seller {
dimension "app"
applicationId configurationSeller.applicationId
versionCode configurationSeller.versionCode
versionName "${configurationSeller.versionMajor}.${configurationSeller.versionMinor}" +
".${configurationSeller.versionPath}-${configurationSeller.versionClasifier}"
proguardFile 'seller-proguard-rules.pro'
testApplicationId "pe.com.linkup.android.test.seller"
}
//Desarrollo Local
local {
dimension "server"
applicationIdSuffix ".local"
}
//Desployment Fabric
dev {
dimension "server"
applicationIdSuffix ".dev"
}
//Desployment PlayStore - Testing
staging {
dimension "server"
//applicationIdSuffix ".staging"
}
//Desployment PlayStore - Production
production {
dimension "server"
}
}
// Configura específicamente cada Flavor
productFlavors.all { flavor ->
switch (flavor.name) {
case "user":
flavor.manifestPlaceholders.put("appName", configurationUser.appName)
flavor.resValue("string", "app_name", "\"${configurationUser.appName}\"")
break
case "specialist":
flavor.manifestPlaceholders.put("appName", configurationSpecialist.appName)
flavor.resValue("string", "app_name", "\"${configurationSpecialist.appName}\"")
break
case "seller":
flavor.manifestPlaceholders.put("appName", configurationSeller.appName)
flavor.resValue("string", "app_name", "\"${configurationSeller.appName}\"")
break
case "local":
flavor.buildConfigField("String", "BASE_URL", "\"${serverProperties['baseUrlLocal']}\"")
flavor.buildConfigField("String", "CLIENT_ID", "\"${serverProperties['clientIdLocal']}\"")
flavor.buildConfigField("String", "CLIENT_SECRET", "\"${serverProperties['clientSecretLocal']}\"")
flavor.buildConfigField("String", "GRANT_TYPE", "\"${serverProperties['grantTypeLocal']}\"")
break
case "dev":
flavor.buildConfigField("String", "BASE_URL", "\"${serverProperties['baseUrlDev']}\"")
flavor.buildConfigField("String", "CLIENT_ID", "\"${serverProperties['clientIdDev']}\"")
flavor.buildConfigField("String", "CLIENT_SECRET", "\"${serverProperties['clientSecretDev']}\"")
flavor.buildConfigField("String", "GRANT_TYPE", "\"${serverProperties['grantTypeDev']}\"")
break
case "staging":
flavor.buildConfigField("String", "BASE_URL", "\"${serverProperties['baseUrlStaging']}\"")
flavor.buildConfigField("String", "CLIENT_ID", "\"${serverProperties['clientIdStaging']}\"")
flavor.buildConfigField("String", "CLIENT_SECRET", "\"${serverProperties['clientSecretStaging']}\"")
flavor.buildConfigField("String", "GRANT_TYPE", "\"${serverProperties['grantTypeStaging']}\"")
break
case "production":
flavor.buildConfigField("String", "BASE_URL", "\"${serverProperties['baseUrlProduction']}\"")
flavor.buildConfigField("String", "CLIENT_ID", "\"${serverProperties['clientIdProduction']}\"")
flavor.buildConfigField("String", "CLIENT_SECRET", "\"${serverProperties['clientSecretProduction']}\"")
flavor.buildConfigField("String", "GRANT_TYPE", "\"${serverProperties['grantTypeProduction']}\"")
break
default:
break
}
}
// Configura las variantes merged. Ejm: applicationId ya viene unido con el applicationIdSuffix
applicationVariants.all { variant ->
def name = variant.name
if (name.contains("Local")) {
def filesAuthorityValue = variant.applicationId + ".fileProvider"
variant.mergedFlavor.manifestPlaceholders.put("filesAuthority", filesAuthorityValue)
variant.buildConfigField("String", "FILES_AUTHORITY", "\"${filesAuthorityValue}\"")
} else if (name.contains("Dev")) {
def filesAuthorityValue = variant.applicationId + ".fileProvider"
variant.mergedFlavor.manifestPlaceholders.put("filesAuthority", filesAuthorityValue)
variant.buildConfigField("String", "FILES_AUTHORITY", "\"${filesAuthorityValue}\"")
} else if (name.contains("Staging")) {
def filesAuthorityValue = variant.applicationId + ".fileProvider"
variant.mergedFlavor.manifestPlaceholders.put("filesAuthority", filesAuthorityValue)
variant.buildConfigField("String", "FILES_AUTHORITY", "\"${filesAuthorityValue}\"")
} else if (name.contains("Production")) {
def filesAuthorityValue = variant.applicationId + ".fileProvider"
variant.mergedFlavor.manifestPlaceholders.put("filesAuthority", filesAuthorityValue)
variant.buildConfigField("String", "FILES_AUTHORITY", "\"${filesAuthorityValue}\"")
}
}
buildTypes {
debug {
//applicationIdSuffix ".debug"
minifyEnabled false
debuggable true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
productFlavors.user.signingConfig signingConfigs.debug
productFlavors.specialist.signingConfig signingConfigs.debug
productFlavors.seller.signingConfig signingConfigs.debug
buildConfigField "boolean", "LOG", "true"
// disable crashlytics
buildConfigField "boolean", "ENABLE_CRASHLYTICS", "false"
ext.enableCrashlytics = false
}
relebug {
//applicationIdSuffix ".relebug"
minifyEnabled false
debuggable true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField "boolean", "LOG", "true"
// disable crashlytics
buildConfigField "boolean", "ENABLE_CRASHLYTICS", "false"
ext.enableCrashlytics = false
matchingFallbacks = ['release']
}
release {
zipAlignEnabled true
minifyEnabled true
shrinkResources true
debuggable false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
productFlavors.user.signingConfig signingConfigs.configReleaseUser
productFlavors.specialist.signingConfig signingConfigs.configReleaseSpecialist
productFlavors.seller.signingConfig signingConfigs.configReleaseSeller
buildConfigField "boolean", "LOG", "false"
// enable crashlytics
buildConfigField "boolean", "ENABLE_CRASHLYTICS", "true"
ext.enableCrashlytics = true
}
}
// Ignora algunas variantes de compilación para su visualización en la BuildVariant
variantFilter { variant ->
def app = variant.getFlavors().get(0).name
def server = variant.flavors.get(1).name
def isRelease = variant.buildType.name.contains('release')
def isRelebug = variant.buildType.name.contains('relebug')
def isDebug = variant.buildType.name.contains('debug')
if (server.contains('local')) {
variant.setIgnore(false)
} else if (server.contains('dev')) {
variant.setIgnore(false)
} else if (server.contains('staging')) {
variant.setIgnore(false)
} else if (server.contains('production')) {
variant.setIgnore(true) //Temporal
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE-FIREBASE.txt'
exclude 'META-INF/NOTICE'
}
lintOptions {
abortOnError false
lintConfig file("../lint.xml")
}
dexOptions {
jumboMode true
//incremental true
}
testOptions {
reportDir "$rootDir/test-reports"
resultsDir "$rootDir/test-results"
unitTests {
returnDefaultValues = true
all {
jvmArgs '-XX:MaxPermSize=256m'
if (it.name == 'testDebugUnitTest') {
systemProperty 'debug', 'true'
}
}
}
}
//Renombrar Apk de salida
applicationVariants.all { variant ->
variant.outputs.all { output ->
def projectName = "linkup"
def formattedDate = new Date().format('yyyyMMdd', TimeZone.getTimeZone("UTC"))
def apkName = "${projectName}-${variant.flavorName}-${variant.versionName}-${variant.versionCode}-${formattedDate}-${variant.buildType.name}" + ".apk"
def apkDirectory = "${output.outputFile.parent}/apk/${variant.flavorName}/${variant.buildType.name}"
//outputFileName = new File(apkDirectory, apkName)
outputFileName = apkName
}
}
crashlytics {
enableNdk true
androidNdkOut 'src/main/obj'
androidNdkLibsOut 'src/main/libs'
}
}
repositories {
jcenter()
google()
mavenCentral()
maven { url "https://jitpack.io" }
maven { url 'https://maven.fabric.io/public' }
}
apply from: "$rootProject.rootDir/app/library.gradle"
def library = ext.library
def libraryTest = ext.libraryTest
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation library.support_appcompat
implementation library.support_recyclerview
implementation library.support_v4
implementation library.support_v13
implementation library.support_design
implementation library.support_cardview
implementation library.support_customtabs
implementation library.support_annotations
implementation library.support_vector_drawable
implementation library.support_constraint
implementation library.support_multidex
implementation library.firebase_core
implementation library.firebase_auth
implementation library.firebase_database
implementation library.firebase_storage
implementation library.firebase_messaging
implementation library.firebase_config
implementation library.firebase_invites
implementation library.exoplayer_core
implementation library.exoplayer_ui
implementation library.exoplayer_dash
implementation library.butterknife
annotationProcessor library.butterknife_compiler
implementation library.retrofit2
implementation library.retrofit2_converter_gson
implementation library.logging_interceptor
implementation library.glide
implementation library.joda_time
implementation library.shortcut_badger
implementation library.smiley_rating
//Room
implementation library.room
annotationProcessor library.room_compiler
implementation library.room_assets
//GMS
implementation library.play_services_location
implementation library.play_services_maps
// Crashlytics
implementation(library.crashlytics) {
transitive = true
}
// Crashlytics NDK
implementation(library.crashlytics_ndk) {
transitive = true
}
implementation library.spinner_date_picker
//Testing
testImplementation libraryTest.junit
testImplementation libraryTest.mockito_core
testImplementation libraryTest.robolectric
testImplementation libraryTest.robolectric_shadows
//UI testing
// Espresso dependenciesVersions
androidTestImplementation(libraryTest.expresso_core, {
exclude group: 'com.android.support', module: 'support-annotations'
})
}
configurations.all {
resolutionStrategy.force library.support_annotations
resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.2'
}
//TODO: Pendiente -> https://howards543.ddns.net/gradle-script-with-multi-flavor-resource-management/
task("copyGoogleServicesJson", type: Copy) {
println 'copyGoogleServicesJson'
from('$rootProject.rootDir/app/services/dev/google-services.json')
into("$rootProject.rootDir/app")
include('*.json')
}
//apply from: "$rootProject.rootDir/setup/artifacts.gradle"
apply plugin: 'com.google.gms.google-services'
Just based on the dependencies, these were added correctly and the code did not move, my buildgradle structure it in this way where I use library.gradle to call the libraries by version and this is the specic code of the implementation of the RecyclerView.
ext.versions = [
supportLib : '28.0.0'
]
def version = ext.versions
ext.library = [
support_recyclerview : 'com.android.support:recyclerview-v7:' + version.supportLib
]
Use Fragment with RecyclerView and Activity host for this Fragment.
I'm trying to run instrumentation tests on Android ( or Espresso tests for that matter ). The error that I'm getting both from Android Studio and console is:
Tests on Nexus_5X_API_23_2(AVD) - 6.0 failed: Unable to find instrumentation info for:
ComponentInfo{com.android.example.country1.demo.debug.test/android.support.test.runner.AndroidJUnitRunner}
com.android.builder.testing.ConnectedDevice > No tests found.[Nexus_5X_API_23_2(AVD) - 6.0] FAILED
No tests found. This usually means that your test classes are not in the form that your test runner expects (e.g. don't inherit from TestCase or lack #Test annotations).
Here is my build.gradle:
buildscript {
repositories {
jcenter()
}
}
apply plugin: 'com.android.application'
android {
signingConfigs {
release
}
compileSdkVersion 23
buildToolsVersion '24.0.0rc3'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
defaultConfig {
versionName "1"
versionCode 1
minSdkVersion 14
targetSdkVersion 23
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testProguardFile 'proguard-test-rules.pro'
}
buildTypes {
debug {
debuggable true
minifyEnabled true
applicationIdSuffix ".debug"
versionNameSuffix ".debug"
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-debug.pro'
}
release {
minifyEnabled true // this is a default setting
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
flavorDimensions "version", "country"
productFlavors {
country1 {
dimension "country1"
applicationId "com.android.example.country1"
proguardFile 'src/country1/proguard-country1.pro'
}
country2 {
dimension "country2"
applicationId "com.android.example.country2"
proguardFile 'src/country2/proguard-country2.pro'
}
demo {
dimension "version"
}
prod {
dimension "version"
}
}
applicationVariants.all { variant ->
def flavorString = variant.getVariantData().getVariantConfiguration().getFlavorName()
def mergedFlavour = variant.getVariantData().getVariantConfiguration().getMergedFlavor();
if (flavorString.toLowerCase().contains("democountry1")) {
mergedFlavour.setApplicationId("com.android.example.country1.demo")
mergedFlavour.versionName = android.defaultConfig.versionName + ".country1.demo";
...
}
if (flavorString.toLowerCase().contains("prodcountry1")) {
mergedFlavour.setApplicationId("com.android.example.country1")
mergedFlavour.versionName = android.defaultConfig.versionName + ".country1";
...
}
if (flavorString.toLowerCase().contains("democountry2")) {
mergedFlavour.setApplicationId("com.android.example.country2.demo")
mergedFlavour.versionName = android.defaultConfig.versionName + ".country2.demo";
...
}
if (flavorString.toLowerCase().contains("prodcountry2")) {
mergedFlavour.setApplicationId("com.android.example.country2")
mergedFlavour.versionName = android.defaultConfig.versionName + ".country2";
...
}
}
dexOptions {
incremental true
preDexLibraries false
javaMaxHeapSize "4G"
}
}
def props = new Properties()
if (rootProject.file("release.properties").exists()) {
props.load(new FileInputStream(rootProject.file("release.properties")))
android.signingConfigs.release.storeFile rootProject.file(props.keyStore)
android.signingConfigs.release.storePassword props.storePassword
android.signingConfigs.release.keyAlias props.keyAlias
android.signingConfigs.release.keyPassword props.keyPassword
} else {
android.signingConfigs.release.storePassword = 'storePassword'
android.signingConfigs.release.keyAlias = 'keyAlias'
android.signingConfigs.release.keyPassword = 'keyPassword'
}
dependencies {
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:support-v4:23.3.0'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-jackson:2.0.2'
...
testCompile 'junit:junit:4.12'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
androidTestCompile 'com.squareup.retrofit2:retrofit-mock:2.0.2'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
androidTestCompile 'com.squareup.spoon:spoon-client:1.5.1'
//Version resolutins
androidTestCompile 'com.google.code.findbugs:jsr305:3.0.0'
androidTestCompile 'com.android.support:support-annotations:23.3.0'
}
Note: I know there are a lot of similar questions but after a couple of days of searching and trying solutions I have not found something that works for me.
UPDATE :
Instrumentation test case:
public class RegulatorRestApiAdapterTest extends InstrumentationTestCase {
private MockRetrofit mockRetrofit;
private Retrofit retrofit;
#Override
public void setUp() throws Exception {
retrofit = new Retrofit.Builder().baseUrl("http://test.com")
.client(new OkHttpClient())
.addConverterFactory(JacksonConverterFactory.create())
.build();
NetworkBehavior behavior = NetworkBehavior.create();
mockRetrofit = new MockRetrofit.Builder(retrofit)
.networkBehavior(behavior)
.build();
}
#SmallTest
public void testEcho() throws Exception {
BehaviorDelegate<BackendRestApi> delegate = mockRetrofit.create(BackendRestApi.class);
RegulatorRestApi mockBackendRestApi = new MockBackendRestApi(delegate);
Echo echo = new Echo();
echo.setEchoRequest("EchoString");
//Actual Test
Call<Echo> call = mockBackendRestApi .echo(echo);
Response<Echo> echoResponse = call.execute();
//Asserting response
Assert.assertTrue(echoResponse.isSuccessful());
Assert.assertEquals("EchoString", echoResponse.body().getEchoResponse());
}
}
Espresso test:
#RunWith(AndroidJUnit4.class)
#LargeTest
public class EspressoTest {
#Rule
public ActivityTestRule<LoginActivity> mActivityRule =
new ActivityTestRule<>(LoginActivity.class);
#Test
public void findViewPerformActionAndCheckAssertion() {
// Find Button and Click on it
onView(withId(R.id.numpad_ok)).perform(click());
// Find TextView and verify the correct text that is displayed
onView(withId(R.id.text_view_rocks)).check(matches(withText(
mActivityRule.getActivity().getString(R.string.android_testing_rocks))));
}
}
Both tests fail with the same error and code of neither reaches execution. I'm using Android version 6 and successfully execute Instrumentation and Espresso test examples from the Internet on the same emulator.
I managed to finally resolve it. It might be useful to someone else so I'm posting here.
The way that I was setting application ID was interfering with test application. Although in Android Studio it looked like it was installing application with correct package name when I checked on the device itself the test application ID was lacking ".demo" from "version" flavor dimension.
I made use of the newly introduced ( for flavors )
applicationIdSuffix = ".demo"
Source : http://android-developers.blogspot.bg/2015/12/leveraging-product-flavors-in-android.html
Here is the modified section of my build.gradle:
defaultConfig {
applicationId "com.example"
versionName "1"
versionCode 1
minSdkVersion 14
targetSdkVersion 23
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testProguardFile 'proguard-test-rules.pro'
}
buildTypes {
debug {
debuggable true
minifyEnabled true
applicationIdSuffix ".debug"
versionNameSuffix ".debug"
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-debug.pro'
}
release {
minifyEnabled true // this is a default setting
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
flavorDimensions "country", "version"
productFlavors {
country1 {
dimension "country1"
applicationIdSuffix = ".country1"
proguardFile 'src/country1/proguard-country1.pro'
}
country2 {
dimension "country2"
applicationIdSuffix = ".country2"
proguardFile 'src/country2/proguard-country2.pro'
}
demo {
dimension "version"
applicationIdSuffix = ".demo"
}
prod {
dimension "version"
}
}
So far I don't think
versionNameSuffix
is usable with flavors so the code below remains.
applicationVariants.all { variant ->
def flavorString = variant.getVariantData().getVariantConfiguration().getFlavorName()
def mergedFlavour = variant.getVariantData().getVariantConfiguration().getMergedFlavor();
if (flavorString.toLowerCase().contains("country1demo")) {
mergedFlavour.versionName = android.defaultConfig.versionName + ".country1.demo";
...
}
if (flavorString.toLowerCase().contains("country1prod")) {
mergedFlavour.versionName = android.defaultConfig.versionName + ".country1";
...
}
if (flavorString.toLowerCase().contains("country2demo")) {
mergedFlavour.versionName = android.defaultConfig.versionName + ".country2.demo";
...
}
if (flavorString.toLowerCase().contains("country2prod")) {
mergedFlavour.versionName = android.defaultConfig.versionName + ".country2";
...
}
}