Regarding point 1. Buffer is just a capacity of 64 with buffer overflow set to suspend. I don't agree with dropping events. By definition they are "important" which is why SharedFlow was rejected as an option. I also don't agree with unlimited buffers as it introduces unlimited memory consumption, which results in just strangeness when that situation actually hits. Finally, regardless of the buffer settings you aren't forced to use the suspending `send` for channels. `offer` exists and is useable, though I'm not sure why you'd use it. Launching a coroutine isn't expensive, though it is verbose in this case.
Regarding point 2. I do lightly cover and link to SingleLiveEvent, LiveEvent and a few other solutions however in the interest of not making the article a 25 minute read I didn't go into depth of each.
Regarding point 3. I see that as an implementation detail. I do agree it's possible to fire off multiple events of the same type which can result in the situation you describe. I don't see it as the responsibility of the view model or the event emitter to manage that. (For my own work I check whether the current destination can actually perform the given action before navigating to it.) I suppose one would have to have a stream that conflates individual event types within the stream but preserves the different events and the order. Sounds messy.
Regarding point 4. Multiple observers for non-conflated events AND events that are considered important enough to not be dropped is problematic. Consider what happens when there are multiple events on a flow waiting to be observed. The first observer drains at least part of the flow. A second observer added immediately afterward has effectively missed an event. If we go back to just one observer no events will be missed. I suppose if you still wanted multiple observer you could then add a `.shareIn` operator call but that would accept the fact that events can be dropped. Personally I find multiple observers for event flows inconsistent with the importance that none will be dropped or unobserved.
The reason for the Fragment observer is that it delays observing until the viewLifecycleOwnerLiveData has emitted a value. Until that has happened it's not safe to observe the viewLifecycle owner. This makes it possible to register your event observers without worrying about the lifecycle state of the fragment.
As for the bug/lint error, I can't seem to see the same issue. Can you share something that demonstrates it?