How to expose Project Module Library to App Module (Android Studio) - android

At first, I am using a single module app for the the Android Application, but now I want to separate the module into app module (core-business logic and UI) and libraries module (HTTP-related and base abstract classes).
I made new libraries module as the library module and start moving some utility code from app to libraries but problem comes. The problem is, I want my app to use the dependency used in libraries module without having to include same dependency in both build.gradle.
In my app module, I want my source code to use the RecyclerView and Retrofit defined in libraries, but I can't do it unless I also include retrofit and recyclerview-v7 in my app/build.gradle.
app/main/src/..../HomeActivity.kt
var gridDataset: RecyclerView? = null // RecyclerView not found in classpath
app/build.gradle
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(":libraries")
libraries/build.gradle
implementation "com.android.support:recyclerview-v7:$support_library_version"
implementation "com.squareup.retrofit2:retrofit:2.4.0"
implementation "com.squareup.retrofit2:converter-gson:2.4.0"
implementation "com.squareup.retrofit2:adapter-rxjava2:2.4.0"
implementation "com.squareup.okhttp3:logging-interceptor:3.8.0"
Where did I go wrong? Or is it simply impossible to do that?

specify your dependencies in libraries/build.gradle using api instead of implementation
This should add these dependencies to the class path for any module depending on your libraries module
api "com.android.support:recyclerview-v7:$support_library_version"
api "com.squareup.retrofit2:retrofit:2.4.0"
api "com.squareup.retrofit2:converter-gson:2.4.0"
api "com.squareup.retrofit2:adapter-rxjava2:2.4.0"
api "com.squareup.okhttp3:logging-interceptor:3.8.0"

Related

Android, avoid duplicate classes error by modifying dependencies

In short, Dependency graph looks like this, and there's a duplicate class error because Libary1_modified and Library1 have the same classes..
App => Library1_modified
App => Library2 => Library1
In detail....
I modified a android library and built a jar file (https://github.com/segmentio/analytics-android)
I'm using the built jar using
implementation fileTree(dir: "libs", include: ["*.jar"])
Then I wanted to use another library which depends on the above library (the unmodified version)
(https://github.com/segmentio/analytics-react-native)
The dependency from the second library to the first library is stated as
dependencies {
api 'com.segment.analytics.android:analytics:4.+'
}
When I build it complains there are duplicate classes .
And yes because my.jar is the modified version of com.segment.analytics.android:analytics:4.+ there are indeed duplicate definitions.
How to use my.jar or my version of the library
I found two workaround
First solution
let Library2 depend on modified Library1 and share it with App via api
Concretely, I moved api fileTree(dir: "libs", include: ["*.jar"]) and the jar file to Library2 and removed the dependency from App.
Second solution
let App depend on Library1, and exclude library1 when depending on Library2 via exclude
implementation (project(':#segment_analytics-react-native')) {
exclude group: 'com.segment.analytics.android', module: 'analytics'
}

Unresolved reference "Searcher"

Trying to integrate instant search in my Android app, but "Searcher" is unresolved.
I have the following dependencies currently, am I missing any?
implementation "com.algolia:algoliasearch-android:3.27.0"
implementation "com.algolia:algoliasearch-client-kotlin-jvm:1.0.0"
implementation 'com.algolia:instantsearch-androidx:1.15.2'
implementation "io.ktor:ktor-client-android:1.2.2"
include core dependency also
implementation 'com.algolia:instantsearch-androidx-core:1.15.2'
The latest release of instantsearch-androidx is lacking its transitive dependencies. The issue was reported on GitHub, you can follow its progress there - likely a new version will soon be released with the appropriate dependencies packaged.
As a workaround, you can add the dependencies yourself to your application - depending on the InstantSearch features you use, you might need some or all of the following:
implementation "com.algolia:instantsearch-androidx:$VERSION_INSTANTSEARCH"
implementation "com.algolia:instantsearch-androidx-core:$VERSION_INSTANTSEARCH"
implementation 'com.algolia:algoliasearch-android:3.27.0'
implementation 'org.greenrobot:eventbus:3.1.1'
implementation 'com.github.bumptech.glide:glide:4.7.1'

Cannot resolve symbol ViewModelProviders

I am working on Android ViewModel architecture component but I am getting the above mentioned error when trying to initialize a ViewModel in an AppCompatActivity.
import android.arch.lifecycle.ViewModelProviders;
ViewModelProviders.of(this).get(CounterViewModel.class);
There are a few questions and articles related to this, and they pointed towards adding the lifecycle:extensions and lifecycle:viewmodel dependencies in the app gradle file, but I am still getting the error.
implementation "android.arch.lifecycle:extensions:1.1.1"
implementation "android.arch.lifecycle:viewmodel:1.1.1"
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
The package android.arch.lifecycle does not contain the class ViewModelProviders and it only has ViewModelProvider class.
What else needs to be added to access the ViewModelProviders class?
Edit :
Dependencies in app/build.gradle:
dependencies {
implementation project(':lifecycle')
implementation project(':base')
implementation "android.arch.lifecycle:extensions:1.1.1"
implementation "android.arch.lifecycle:viewmodel:1.1.1"
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
}
android.arch.lifecycle:extensions:1.1.1 definitely has android.arch.lifecycle.ViewModelProviders. You can see it in Android Studio, if you open the "External Libraries" portion of the project tree and examine the library contents:
Some possible reasons for not finding the import include:
You have implementation "android.arch.lifecycle:extensions:1.1.1" in the wrong place (it should be in the dependencies closure of the module's build.gradle file, such as app/build.gradle)
You did not sync Android Studio with the Gradle build files (you are normally prompted to do this, but you can do it manually from File > Sync Project with Gradle Files from the Android Studio main menu)
You do not need both lifecycle:extensions and lifecycle:viewmodel in your build.gradle file, remove
implementation "android.arch.lifecycle:viewmodel:1.1.1"
and it should be fine now. Also, you may want to migrate to AndroidX and use the 2.0.0 versions of the library.
ViewModelProviders is now deprecated. Use ViewModelProvider instead.
If you are configuring in libary, you can modify the implementation to api

Dagger2 annotation processor is not working

I try to use Dagger2 in my Android project;
When I use apt, every things is right.But apt is not supported in AndroidStudio 3.0, so I use annotation processor.But no Dagger2 code created after I click "Make Project";
And I'm sure the annotetion processing is enable in AndroidStudio,because the Butterknife annotation processor is all right.
the follow is the build.gradle:
dependencies {
annotationProcessor 'com.google.dagger:dagger-android-processor:2.13'
compile 'com.google.dagger:dagger-android:2.13'
compile 'com.google.dagger:dagger-android-support:2.13'
compile 'com.jakewharton:butterknife:8.6.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.6.0'
}
use this in android studio 3.0 version
implementation 'com.google.dagger:dagger:2.9'
annotationProcessor 'com.google.dagger:dagger-compiler:2.9'
these are the dependences for dagger2 and butter in andriod studio 3.0
//ButterKniffe
compile "com.jakewharton:butterknife:8.8.1"
kapt "com.jakewharton:butterknife-compiler:8.8.1"
//dagger
compile "com.google.dagger:dagger:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
It is one of the breaking changes coming with gradle:3.0 that Google announced at IO17 gradle:3.0
the compile configuration is now deprecated and should be replaced by implementation or api
From the gradle docs :
Dependencies appearing in the api configurations will be transitively exposed to consumers of the library, and as such will appear on the compile classpath of consumers.
Dependencies found in the implementation configuration will, on the other hand, not be exposed to consumers, and therefore not leak into the consumers' compile classpath. This comes with several benefits:
List item dependencies do not leak into the compile classpath of consumers anymore, so you will never accidentally depend on a transitive dependency
faster compilation thanks to reduced classpath size
less recompilations when implementation dependencies change: consumers would not need to be recompiled
cleaner publishing: when used in conjunction with the new maven-publish plugin, Java libraries produce POM files that distinguish exactly between what is required to compile against the library and what is required to use the library at runtime (in other words, don't mix what is needed to compile the library itself and what is needed to compile against the library).
The compile configuration still exists but should not be used as it will not offer the guarantees that the api and implementation configurations provide.

Android Gradle Implementation vs CompileOnly Performance

The docs mention that implementation provides significant build time improvements over compile/api. What about compileOnly?
My use case is a multi-module (sorry I don't like Gradle's multi-project terminology) project, where I have an Android app, and multiple libraries that the app depends on (implementation). Some of the libraries also depend on one another. Should I use implementation or compileOnly when declaring dependencies in the library modules? My app module will be using implementation to depend on those artifacts, so I don't need them to be transitive through the library modules.
The api configuration should be used for dependencies that are exported to external modules (transitive dependency). Vice-Versa implementation configuration should be used for dependencies that are internal to the component (not transitive dependency).
implementation vs compileOnly:
There is no similarity in their job, compileOnly is
a configuration inherited from java-plugin
required at compile time
also not included in the runtime classpath or exposed to dependent
projects.
So compileOnly doesn't replace the implementation configuration job e.g:
implementation 'com.android.support:appcompat-v7:25.1.0' // can't use compileOnly here
testCompile 'junit:junit:4.12'
compile "com.google.dagger:dagger:2.8" // can't use here also
annotationProcessor "com.google.dagger:dagger-compiler:2.8" // can't use here also
compileOnly 'javax.annotation:jsr250-api:1.0' // we can use compileOnly here because it's required on run time only.
Since your case is a "multi-module", you have to use the api configuration, until you reach the final module it's better to use implementation.
Following graph describe those configurations:
Performance?
I think api requires more memory because gradle will snapshot every class in that transitive module, vice versa implementation is a preferred configuration because (as mentioned above) it's used for its own internal implementations.

Categories

Resources