Hi all I am using Clean Architecture (Data, Domain, Presentation layers) to build app but I am confu...
l
Hi all I am using Clean Architecture (Data, Domain, Presentation layers) to build app but I am confused in which layer should put BroadcastReceiver. I am using BroadcastReceiver for listening Battery changes like whether the charger is connected or not to show In UI etc. According to this https://stackoverflow.com/questions/59576331/android-specific-code-in-clean-architecture I should put BroadcastReceiver in Data layer because it is giving me data. But I think it is android component it should be in presentation layer. Please answer this . Thanks
v
Data layer is the right place to put BR. Btw, no rules like all Android components to be placed in presentation layer. If you did so, it's like breaking the presentation constraints (BR or Content Providers are not UI elements)
👍 1
l
Thank you Vivek. I have applied the same rule thanks a lot.
👍 1
v
Domain layer is what I guessed, because we can stop passing `Context`s to the data layer. Or if you put the BR in the data layer, keeping it behind an interface with DI will be better I think. Here's some pseudo-code implementations that I can think of: /data/chargeinfo/ChargeInfoProvider.kt
Copy code
interface ChargeInfoProvider{
   fun start(onData: (Int) -> Unit)
   fun stop()
}
/data/chargeinfo/impl/AndroidBRProvider.kt
Copy code
class AndroidBRProvider(
   val context: Context // Inject this
): ChargeInfoProvider {
  
    fun start(onData: (Int) -> Unit){
      // setup BR
      BR.onRecieve {
         onData(value)
      }
    }

    fun stop() = // stop BR
}
/data/chargeinfo/ChargeInfoRepository.kt
Copy code
class ChargeInfoRepository(
  val provider: ChargeInfoProvider // Inject this
){
   val flow // to expose data

   fun start(){
     provider.start() { data ->
       // update flow
     }
   }

   fun stop() = provider.stop()
}
c
I would definitelt not put BRs in the domain layer. I prefer to keep my domain Android-free. Passing context to data layer is fine. You might not need the context for some categories of data layer operations like network requests but you might need it for other categories like using a Room database, making Bluetooth communication etc. The repository-implementation example above makes sense, especially if the interface is declared in the domain layer and the implementation is in the data layer. Then using DI to tie it all together makes perfect sense.
👍 5
l
I have put my BR in data layer using callback flow so that I don't neet to start and stop it manually it will done automatically on flow collect and cancel. And then RepositoryImpl in data layer to access the BR then Repository interface in domain layer to pass data to the presentation layer. And it is working perfectly.
👍 1
Thanks all for suggestions.
v
@curioustechizen I see a cyclic dependency there which breaks the UDF principle:
...if the interface is declared in the domain layer and the implementation is in the data layer.
That will make the data layer depend upon the domain layer for that interface. So I suggest keeping the interface in the data layer itself so that the dependency is always in only one direction: Data ⬆️ Domain ⬆️ UI
l
But domain layer is not allowed to access data layer files. We can use domain layer files in data layer and presentation layer. Domain layer is the inner layer and it should not know about upper layer..
👍 1
c
@Vishnu Haridas I had the same confusion when I started working with so-called "clean architectures". And there is no right or wrong answer. Google's recommendation is for the UI -> Domain -> Data However in the community it is more like UI -> Domain <- Data
In my projects, domain modules are pure kotlin library modules (as opposed to Android library modules) so they don't have access to any Android-specific APIs.
But even if you follow Google's recommendation and to UI -> Domain -> Data, even then to me it feels like BR belongs in the data layer.
💯 3
v
Oh got it, the "clean" in the context of this discussion is Uncle Bob's clean I think. Google doesn't name the architecture like "clean", so whenever people say "clean" architecture in the context of Android, I think of the Google's new recommendation which is UI > Domain > Data. Google's architecture is what I follow. It should be named properly to avoid confusion with Uncle Bob's "clean" IMO 😄
c
To be frank, I dislike the name "clean" because it is pretentious. It is as if other architectures are not clean. I'm not a big fan of Uncle Bob either 😄
v
Yea, I agree, BR should go into the data layer (just like Room is there in the data layer, which is another Android dependency). What's your take on the Services/FgServices?
v
IMO, depends on what it does. Binder service should be in data layer. But FgService can be in Presentation (Eg: Music app shows content to user via notification but pulls record thru Content Provider which placed at data layer)
c
Yeah I agree with Vivek. Services that do purely data related work (download stuff from internet, sync data over Bluetooth etc) can be in data layer. The moment you have notifications, it gets into "it depends" territory. The main problem is data layer usually has access to application Context only and this might not be sufficient for showing notification text etc. Specifically, application Context might not react soon enough to configuration changes like language change.
v
The architecture will need a "platform" layer too!
v
No, because all platform codes fall under either presentation or data layer context
659 Views