2

As part of working on the development of a new API, I am learning to use Kotlin. Initially I want the Kotlin API to be used within a Java (Android) project, but in the long term I hope to adopt Kotlin entirely.

As part of improving the implementation of a long-running process, I want to use coroutines. Specifically, a channel producer from the kotlinx.coroutines package.

For example:

fun exampleProducer() = produce {
    send("Hello")
    delay(1000)
    send("World")
}

What is the best way to consume this in Java? I am okay with adding temporary 'helper' functions to Kotlin and/or Java.

rhashimoto
  • 15,650
  • 2
  • 52
  • 80
Steven Jeuris
  • 18,274
  • 9
  • 70
  • 161

2 Answers2

2

The easiest way to interop channels with Java is via Reactive Streams. Both Rx and Project Reactor are supported out-of-the-box. For example, add kotlinx-coroutines-rx2 to your dependicies and you'll be able to use rxFlowable builder:

fun exampleFlowable() = rxFlowable<String> {
    send("Hello")
    delay(1000)
    send("World")
}

This function returns an instance of Flowable, which is specifically designed for ease-of-use from Java, for example, you can do in Java:

exampleFlowable().subscribe(t -> System.out.print(t));
Roman Elizarov
  • 27,053
  • 12
  • 64
  • 60
1

Currently, assuming Java 8 is used and lambdas are available, I rely on a helper function defined in Kotlin which allows passing a callback to consume incoming results.

The helper method in Kotlin:

fun exampleProducerCallback( callback: (String) -> Unit ) = runBlocking {
    exampleProducer().consumeEach { callback( it ) }
}

This is then consumed in Java as:

ApiKt.exampleProducerCallback( text -> {
    System.out.print( text );
    return Unit.INSTANCE; // Needed since there is no void in Kotlin.
} );

Explanation on why return Unit.INSTANCE is needed can be found in this answer.

Steven Jeuris
  • 18,274
  • 9
  • 70
  • 161
  • I am totally new to Kotlin and have no idea whether or not this is idiomatic. I merely posted my current solution to let you know where I am at right now. Perhaps there are better alternatives available? – Steven Jeuris Nov 10 '17 at 17:44
  • 1
    An obvious improvement is using `callback: Consumer` instead. – Alexey Romanov Nov 10 '17 at 20:17