Where should LocationManager be placed in MVP?

Thread Starter

Rank:

None

Points:

Posts:

Joined:

Oct 29, 2018

Im refactoring my messy Activity code to a MVP architecture, but Im not sure where to put LocationManager and permission checks...any help please? Thanks, Dani

Best Answer

I'm not really surprised you haven't found much guidance on this, because I've looked for exactly the kind of information you require, and found it lacking. Basically, this isn't an exact science, and there are a multitude of different ways you can structure your code.
Rather than get hung up on patterns - and honestly, if you're tying yourself in knots trying to massage the code into a prescribed architectural pattern, then that leads me to question if it's the right approach.
I tend to apply some basic principles when I'm trying to come up with a software architecture:

- I try to write my code in such a way that it makes testing easy. Testing is a much neglected part of software development, and quite often it's not done properly.
- Program to the interface. Interfaces are a great way of decoupling your classes, and providing lots of flexibility in your design.
- Keep things cohesive. That means not mixing a lot of different functionality in the same class. If a class is called DBHelper, then it should only be concerned with database stuff.
- Aim for loose coupling - that is all about reducing the dependencies between classes. There's a great pattern that can help you with this, it's called 'Dependency Injection'.

But really, Android apps are heavily UI based, so a lot time your code revolves around Activities, and responding to user input. With the apps I've built, I didn't really feel the need to construct a complicated architecture.

When you say you moved the LocationManager to the 'model', what do you mean by that? What constitutes the 'model' in your application?
Maybe if you placed your code in a Github repo we could get some more context around the code fragments you've presented. Because it's a little difficult to visualise the full picture.

Note: I just saw your most recent post while writing this response. I'll have a look at the article.

Thread Starter

Rank:

None

Points:

Posts:

Joined:

Oct 29, 2018

The logical place for that would be in the model, which contains the business logic, and database access components.

Click to expand...

Thanks form your response!

Thats what I did at first time, the only problem I see is that the Model gets coupled with permissions API of Android SDK and you have to provide methods in all layers of the MVP to show and check permissions, isnt it? Any way to gently solve this?

Moderator

Rank:

Points:

Posts:

Joined:

Oct 16, 2015

Sometimes a consequence of having a layered architecture, is the need for 'pass through' methods. But without seeing your code, I can't really say anything very specific. Can you provide some sample code to illustrate the problems you're having?

Thread Starter

Rank:

None

Points:

Posts:

Joined:

Oct 29, 2018

Sometimes a consequence of having a layered architecture, is the need for 'pass through' methods. But without seeing your code, I can't really say anything very specific. Can you provide some sample code to illustrate the problems you're having?

Click to expand...

Yes of course, I don't have the code now at home but I will try to give you a specific example of the problem I'm facing with the MVP:

LocationManager requires to check location permissions just before calling the method (or supress warning with annotation), so the decision on where to put it in the MVP is not straightforward.

This code used to be in my Activity and worked fine having the Context and all the SDK Android imports available:

When triying to deocuple things with MVP architecture I decided leaving the permissions-related code in the Activity and moving LocationManager to the Model(is that even a good decision? what other choices are?):

To avoid checking permissions in the Model I have to: 1) provide a pass-through methods in the Presenter so that the View can call the requestLocation() of the Model when the permission is granted and 2) either supress warnings (Annotation) or wrap with a try-catch in the requestLocation() call in the Model to avoid compilation error.

I have considered aadding pass-through methods to check permissions, moving permissions and LocationManager to the Presenter, encapsulate LocationManager with a Helper class and some others options, but none of them feel good to me. It ends up being everything coupled with Android SDK and / or with dirty interfaces for the VMP layers.

The decision on where to put the permissions-realated code, how to manage permissions in Presenter and Model and where to put the calls to Android SDK services or managers seems to be a bit arbitrary depending on which article / post you read. Also, some of them say that no Android SDK code or imports can be placed in Presenter or Model in the benefit of testability (or purity), but I find that the result is lots of boilerplate and pass-through methods.

To be honest, I have not been able to find two articles / posts that are consistent with the approach on how to handle these things in MVP and none of them cover the problem in detail ("it depends"). The Android Developers page does not give any guidance on this either... :-(

Moderator

Rank:

Points:

Posts:

Joined:

Oct 16, 2015

I'm not really surprised you haven't found much guidance on this, because I've looked for exactly the kind of information you require, and found it lacking. Basically, this isn't an exact science, and there are a multitude of different ways you can structure your code.
Rather than get hung up on patterns - and honestly, if you're tying yourself in knots trying to massage the code into a prescribed architectural pattern, then that leads me to question if it's the right approach.
I tend to apply some basic principles when I'm trying to come up with a software architecture:

- I try to write my code in such a way that it makes testing easy. Testing is a much neglected part of software development, and quite often it's not done properly.
- Program to the interface. Interfaces are a great way of decoupling your classes, and providing lots of flexibility in your design.
- Keep things cohesive. That means not mixing a lot of different functionality in the same class. If a class is called DBHelper, then it should only be concerned with database stuff.
- Aim for loose coupling - that is all about reducing the dependencies between classes. There's a great pattern that can help you with this, it's called 'Dependency Injection'.

But really, Android apps are heavily UI based, so a lot time your code revolves around Activities, and responding to user input. With the apps I've built, I didn't really feel the need to construct a complicated architecture.

When you say you moved the LocationManager to the 'model', what do you mean by that? What constitutes the 'model' in your application?
Maybe if you placed your code in a Github repo we could get some more context around the code fragments you've presented. Because it's a little difficult to visualise the full picture.

Note: I just saw your most recent post while writing this response. I'll have a look at the article.

Moderator

Rank:

Points:

Posts:

Joined:

Oct 16, 2015

I think some applications fit so naturally with MVC. Web applications in particular were made for that pattern, no question about it.
But do put your code up on Github, and if I get some time, I'll look over it.

Thread Starter

Rank:

None

Points:

Posts:

Joined:

Oct 29, 2018

When you say you moved the LocationManager to the 'model', what do you mean by that? What constitutes the 'model' in your application?

Click to expand...

The Model in my app is only a class that stores some values in memory, such as the current location and a list of alerts, and encapsulates the calls to LocationManager. Here is where the coupling with Android SDK ocurrs. The Model has a reference to the Presenter to notify changes in data that have to be represented on the View (in my case, the Activity).

Moderator

Rank:

Points:

Posts:

Joined:

Oct 16, 2015

Ah right, I see what you mean. Yes I sometimes found myself passing around references to a Context (Activity) in another class, so it could update the UI. I was never totally comfortable with that approach, but I just lived with it, as I couldn't really see a cleaner way of doing it.