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,130
  • 2
  • 44
  • 78
Steven Jeuris
  • 17,256
  • 8
  • 69
  • 149

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
  • 24,327
  • 10
  • 57
  • 59
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
  • 17,256
  • 8
  • 69
  • 149
  • 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