Here are few benefits of channels over rx (IMO):
* Can handle null emissions (and in a safe way, thanks to Kotlin type system)
* Threading is explicit. With Rx, it's often hard to know on what thread pool each piece of code is executed
* ReceiveChannel and SendChannel use on-site variance which can make thinks easier when generic variance is involved.
* It is (a lot) easier to create custom operators with channels.
* When it comes to parallelism, Coroutines are (IMO) way easier to use and produce clearer code.
* pipeline pattern out of the box.
So far, I haven't run in a use case that Rx solved and I couldn't handle in a nice and easy way with Channels. If you know one, i would be interested to look at it.