I add the Timber dependency to my Java Core Library Module build.gradle file:
implementation 'com.jakewharton.timber:timber:4.6.0'
Although it did not give an error when gradle synchronizes, I cannot see or use Timber class in the Core Library.
I add the Timber dependency to my Java Core Library Module build.gradle file:
implementation 'com.jakewharton.timber:timber:4.6.0'
Although it did not give an error when gradle synchronizes, I cannot see or use Timber class in the Core Library.
Timber has a dependency on android.util.Log so it cannot be used in a pure Java module.
Decoupling the library from Android has been proposed but the creator of the library has decided against it. https://github.com/JakeWharton/timber/pull/63
The 5.0.0-SNAPSHOT version of Timber now supports usage in Java modules by using the jdk
artifact.
<dependency>
<groupId>com.jakewharton.timber</groupId>
<artifactId>timber-jdk</artifactId>
<version>5.0.0-SNAPSHOT</version>
</dependency>
If anyone looking at Timber (Without android dependency) for mutli-module android project. Use timber-jdk
like below.
In project's build.gradle
file.
allprojects {
repositories {
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}
}
In individual module build.gradle
file (Example: Domain or remote module)
implementation "com.jakewharton.timber:timber-jdk:5.0.0-SNAPSHOT"
With this you should be able to implement Timber
without android framework dependency
If you have multi-module project, you can use Timber in pure Java/Kotlin with a tiny bit of abstraction involved, no external libraries.
Example with Kotlin and Koin:
In pure kotlin module create a big imposter, Timber.kt:
interface ILogger {
fun d(message: String)
fun e(message: String)
fun e(throwable: Throwable, message: String)
fun i(message: String)
}
object Timber: ILogger, KoinComponent {
private val logger: ILogger by inject()
override fun d(message: String) = logger.d(message)
override fun e(message: String) = logger.e(message)
override fun e(throwable: Throwable, message: String) = logger.e(throwable, message)
override fun i(message: String) = logger.i(message)
}
In app module create TimberLogger.kt:
import timber.log.Timber
class TimberLogger : ILogger {
override fun d(message: String) = Timber.d(message) // this is real timber this time
override fun e(message: String) = Timber.e(message)
override fun e(throwable: Throwable, message: String) = Timber.e(throwable, message)
override fun i(message: String) = Timber.i(message)
}
In app module, inject TimberLogger implementation into your fake Timber:
val appModule = module {
single<ILogger> { TimberLogger() }
}
Now you can simply call Timber.d("message") statically from anywhere.
If you have 2+ pure modules to use Timber in, consider creating Utils module and include it in rest of them, so it's available everywhere.