Best practice for package structure in an MVP project - android

I have an Android Studio project that is using an MVP architecture.
What is the advised packages structure for a project this style
we can do:
app:
screen_name
activityA
presenterA
interfaceA
or:
activities
activityA
activityB
preentors
presentorA
presentorB
etc

Your problem is just only UI part of MVP architectural pattern. Which is View classes along with their corresponding Presenters. And the better solution is the first approach.
App should have package according to features, NOT by the common functionality. We should group together the classes which are getting changed/modify together.
Some developers group source code by layer - like the second approach - because they want to keep the same package structure for ALL the projects they work on. But that is bad decision because it's always HARD to find classes when they are grouped only because they share same parent classes!
Ex: For activities, some developers put them in activity package because all activities extends Activity class. It makes sense because this is activity-ONLY package, BUT it is hard to go through those packages.
For more information, see: android-mvp-architecture and this S.O answer

In addition to the other answers i would recommend to look at android architecture blueprints, which may give you ideas of how to organize and implement your application.

MVP is good choice. You can follow following pattern:
app:
1. activities:
+ interface to represent view (i.e activity)
+ actual activity java class
2. Presenter:
+ interface to represents presenter
+ java class to represent presenter implementation
3. Model:
+ interface to represents model
+ java class to represent model implementation (do network calls here, pass callback to presenter which then gives data to activity)

Related

Android with Hilt: Do I have to inject helper classes?

My app includes many helper classes like the next ones:
A class TMHttp with an "DownloadFile" or "IsOnline" methods (among others).
A TMEmail class with a "SendEmail" method.
A ImageHelper class with a "TakeScreenshot" or "CropBitmap" methods.
TMImport/TMExport classes with "ImportData" and "ExportData" methods.
A TMSession class with "LoginUser", "LogoutUser" and more such methods.
A TMUtils class with methods like "GenerateRandom".
A TMDialog class with methods like "CreateYesNoDialog" ... and many more.
And what I'd need to know -regarding DI- is if I have to inject them where needed -like I do with repository and services- or just create an instance of them. Do I have to inject every class in my app?
I believe there is no strict answer to this question because it depends on the architecture of your project, the principles the team is using, the purpose and the complexity of the helper/util class, etc.
You need to decide it for each such helper/util class particularly, guided by the following advantages of Dependency injection:
Reusability of classes and decoupling of dependencies: It's easier to swap out implementations of a dependency. Code reuse is improved because of inversion of control, and classes no longer control how their dependencies are created, but instead work with any configuration.
Ease of refactoring: The dependencies become a verifiable part of the API surface, so they can be checked at the object-creation time or at compile time rather than being hidden as implementation details.
Ease of testing: A class doesn't manage its dependencies, so when you're testing it, you can pass in different implementations to test all of your different cases.
For example, I would argue like this:
A TMUtils class with methods like "GenerateRandom"
Likely, it's a quite simple helper method that basically can have a standard single implementation; it doesn't depend on other libraries, so I can freely use it without DI.
A class TMHttp with an "DownloadFile" or "IsOnline" methods (among others).
It's heavy and it depends on a lib and Android SDK then it makes sense to inject.
And so on.

Best practice for nested packages/class on Android

Is there any best practice regarding whether or not nested packages and classes is a good idea?
A) nested packages
i.e. Is it a good idea to have
utils
XXX.java
xxxx
XXX.java
XXX.java
model
view
activity
fragment
dialog (dialogfragment)
errors
sth
B) nested class
i.e. Is it a good idea to have
class Const {
class static HOST {
public final static String STAGING = "";
public final static String PRODUCTION = "";
}
class static Foo {
}
}
I would suggest you to take a look at this GitHub https://github.com/googlesamples/android-architecture made by Google developers. It provides samples to build Android apps using different architectural concepts and tools. Hope it helps.
A) There is no specific rule about package but a simple rule of thumb is that you should try to minimize package dependency cycling.
That means one package can depend on an other (or multiple other)
package and use their classes but the required package should minimize
the dependency to the first package. so the dependeny calls should
only go into one direction.
The more common packages are usually Activities, Fragments, Services, Receivers, Adapters, Models, Utilities and Helper Classes, Network and Database Packages.
B) Usually it's not a good practice to define inner classes especially for libraries that parse classes Dynamically like GSON. But if you are defining a Class that is Only used by a Specific Class you can encapsulate First class into the Second one for the sake of re-usability.

Generate Dagger components using Annotation Processor

I'm working on an Android App which follows the MVP architecture pattern. In all my fragments I'm injecting a Presenter. Therefore my Fragments (Views) need to have a Component in which I declare the injects. For example:
#ActivityScope
#Component(
dependencies = AppComponent.class,
modules = {
PresenterModule.class,
InteractorModule.class
}
)
public interface ViewInjectorComponent {
void inject(SelectEventOccurrenceFragment fragment);
void inject(CreateOpponentFragment fragment);
void inject(SelectOpponentFragment fragment);
void inject(TeammatesInvitedFragment fragment);
...
}
Every new View that I add into my App (Fragment) needs to have its entry declared here. I was wondering if It's possible to generate this code automatically with some kind of annotation processor. The App has already several fragments, this component file has easily more than 300 entries. It'd be awesome if I could do something like:
#Injectable
public class MyNewFragment implements MyNewView {
...
}
And then automatically generate the entry in the ViewInjectorComponent file. It's possible? Where should I look at?
The situation you are experiencing may be a consequence of organising your Modules and Components in an unusual way. In particular, grouping laterally (one Component injects all the Presenters) rather than vertically (one component injects the functionality related to SelectOpponentActivity) is problematic.
A good example to follow is in the Google Android Architecture Blueprints GitHub repo. If you peruse the code there, you will see that they have organised functionality related to Tasks inside one Java package together with a separate Component, Module, Presenter etc. This has the nice advantage of being able to restrict accessibility of the constructors of the classes contained therein and fulfilling Effective Java Item 13: Minimize the accesibility of classes and members.
Likewise, you've grouped all your modules together into a Presenter Module and an Interactor Module. The advice from the Dagger 2 official documentation is to organise Modules first for testability and then along functional lines. Again, you can refer to the Blueprint example for how to do this.
Finally, note that there is unavoidably some boilerplate involved in using most DI frameworks like Dagger 2. In a sense, you are exchanging a bigger problem ("how do I deal with all of these constructors?") with much smaller and more manageable problems ("how do I group my Components" etc.).
Update
There is a library called Auto Dagger2 that can generate components for you. See this Github repo. Here is an example of an annotation:
#AutoComponent
#Singleton
public class ExampleApplication extends Application {
}
Which generates the following code:
#Component
#Singleton
public interface ExampleApplicationComponent {
}
Also check out Google Auto if you are interested in code generation tools.
I'm not entirely sure that what I'm going to say is appropriate for an answer, but I'll take a chance here.
Even if you find a way to do what you want, don't do this in production (it is fine if you just want to learn code generation techniques).
The benefits you get from such an approach are small (not writing several lines of trivial code), but consider the drawbacks:
The logic for code generation needs to be written/debugged/maintained
Such an approach will be a violation of "principle of least astonishment"
Code generation is BAD
Note the third point - I really mean it. Usage of code generation always leads to maintenance overhead, therefore it should be used only as a last resort.
Dagger by itself uses code generation, but for a good reason - performance. However, performance is not an issue in your case.
To summarize: your idea is very interesting, but approaches like this should not be used for production applications (unless this functionality is added to Dagger natively).

should presenters(mvP) be injected(dagger2) to views in android?

In the context of developing and android app, should I use presenters directly in views using 'new' or would it be better if I injected them to the view.
Pros/cons for not using injected presenters:
Faster development time, without having to write components and modules.
Presenters are tightly coupled with the views, I don't see this as much of a problem as most of the time presenters are not shared across multiple views(ie. one single view for a presenter).
Might be a problem for testing, as with using dependency injection mock implementations of the presenters can be provided(not sure if this is any useful, need more insight on this).
You're right. Using injection will only help you in the long run. You could either spend 5 minutes setting up your module / component, or you could be just coding.
As long as you don't do proper testing, there is not much difference to it, if you presenter looks like the following
mPresenter = new Presenter();
Assuming you use constructor injection properly, after creating your component, you save some lines as compared to
#Inject Presenter mPresenter;
// onCreate or some other place
{
getComponent().inject(this); /* getComponent() also 4-5 lines */
}
Again. If you use proper constructor injection there is a good chance you don't have many module code. Just creating some component will do.
But you saved some minutes and once you want to do testing this is just some easy refactoring, which can quickly be done.
So why Dagger?
This was assuming your presenter has no dependencies on other objects. But what if it does?
SharedPreferences preferences = getPreferences();
MyStorage storage = new MyStorage(preferences);
mPresenter = new Presenter(storage);
Using something to store your data is properly a good use case. While you just added some more logic about object creation to your activity, the dagger implementation would still look the same.
Even more?
Now let's assume you want to share this storage from above between activities. Now you have to add some logic to your Application or in some other place where you can create a Singleton to use throughout your app.
This will probably not be your only singleton, though, and you will start to clutter up your Application as well. Don't get me started on managing those objects lifecycle, e.g. user logging in or out, make sure to clear that cached data!
Again. The dagger implementation still looks the same. If there is some more logic needed it is well placed in the modules and abstracted with component dependencies.
Once you start thinking I could just create classes that handle object construction and injection you know that you could have just used dagger in the first place ;)
I also wrote a blog post about dagger basics including how constructor injection works, which many beginners are not using properly for some reason.

Android MVP explanation

I try to understand what the best way is to program a "clean" Android app. I found an interesting article about it where they use a kind of a 3 layer architecture.
Now I read that android uses the MVP design pattern and try to understand this. The way I understand the MVP principle (in the android context) is that:
the Model layer are the logic classes
the presenter are the classes that are "linked" to an XML (the activities)
the passive view are the XML's.
Is this correct?
When this is correct, is it then also correct that the 3 layer model fits perfectly in the MVP principle because:
the presentation layer from the 3 layer architecture fits in the presenter layer of MVP
The business and the data layer from the 3 layer architecture fits perfectly in the model part of the MVP?
I hope my questions are clear because it is a complicated topic for me.
Maybe this clears up my vision (way of thinking) about this...
first thing I wanted to clarify is that MVP or any other pattern for that matter is no specific of Android dev and, can be applied to any other framework.
I think you got the gist of it:
view is usually implemented by activities and fragments and will contain the reference to the presenter
the presenter is that middle man between the view and model. Retrieves data from the model and returns it already formatted to the view so it doesn't need to do anything else but display it.
the model can be seen in a simplistic way as the "data provider". It can be as complex as you want, using internal db, lots of clases etc.
If you are interested in Android apps architecture I suggest you watch this talk given at Android dev summit this year. It is one of the bests I've seen
https://www.youtube.com/watch?v=BlkJzgjzL0c
Even though this question has an answer, I don't think this answer is complete by any means.
MVP is a general concept which can have many various implementations, some of which differ substantially. Moreover, the concept itself is very ambiguous - different people can have different concepts in mind when they say MVP. One of the most widespread ones is shown in the below picture:
Regardless of implementation, the general definitions of MVP components are:
Model: abstraction of "application state storage". The definition of what the "state" is and how it is stored are implementation details. Model implementations should not have dependency on View or Presenter.
View: abstraction of "user interface". The definition of who the "user" is and how it interacts with the View are implementation details. View implementations should not have dependency on Model or Presenter.
Presenter: encapsulates application's business logic. Presenter processes user input events received from view, and alters application's state stored in model in response. Presenter also processes changes of application's state stored in model and updates view in response. Presenter usually depends on both the View and the Model.
If you need more information about MVP in context of Android development, you can find it in this post: MVP and MVC Architectural Patterns in Android
Important issues which need to be addressed while implementing MVP in android are activity leaks which cause memory leaks and app crashes due to background process updating closed activity.
Due to presenter having reference to activity, if presenter can't be garbage collected, activity will stay in memory.
Both of the issues can be solved by using life cycle methods of activity or fragment and releasing resources in those methods so that memory leaks and app crashes are prevented.
Cleaning up of resources related background work can be easily implemented using RXJava, for more information about MVP and MVP with RXJava, see http://www.zoftino.com/android-model-view-presenter-mvp-pattern-example
Here is simplest way to implement MVP pattern in your application android_mvp_login_sample
As you have come to know basics of Clean Architechure. The following example depicts how actual your MVP pattern is implemented.
Example:
interface BaseContract {
interface BaseView {
//Methods for View
void onDoSomething();
}
interface BasePresenter {
void doSomething();
}
}
class BaseMainPresenter implements BaseContract.BasePresenter {
BaseContract.BaseView view;
BaseMainPresenter(BaseContract.BaseView view) {
this.view = view;
}
#Override
public void doSomething() {
if (view != null)
view.onDoSomething();
}
}
class DemoClass implements BaseContract.BaseView {
//Create object of Presenter
/****
* Example :
* BaseMainPresenter baseMainPresenter = new BaseMainPresenter(this);
*/
#Override
public void onDoSomething() {
//Deal with Context here.
}
}
Refer below link for sample Actual implementation with scenario & learn more about Clean Architechure : https://github.com/android10/Android-CleanArchitecture
Here on github
https://github.com/saksham24/Android-Firebase-Mvp-Mvc-Mvvm-chat
i made a repo containing 3 applications with same functionality but written in 3 different android patterns(Mvc, Mvp, Mvvm)
Understanding three different pattern is quite easy if we get a simple good example on them so i made a repo to contribute my knowledge to this developer community.
Also the repository is written using proper java guidelines and conventions(including naming and packages, modules) so people looking for such project can also view this repository.
now
if you want to know the difference between android Mvp,Mvc, MvvM see this explanation by realm
https://academy.realm.io/posts/eric-maxwell-mvc-mvp-and-mvvm-on-android/
if you want to compare three pattern see this wonder full blog https://thinkmobiles.com/blog/mvp-vs-mvvm-android-patterns/
Now I read that android uses the MVP design pattern and try to
understand this. The way I understand the MVP principle (in the
android context) is that:
the Model layer are the logic classes
the presenter are the classes that are "linked" to an XML (the activities)
the passive view are the
XML's.
Is this correct?
Not fully: for the Model layer it is true, but for the Presenter it is not. The Presenter is not linked to XML although it has reference to the View through its constructor. The View is the Activity/Fragment in android.
You might want to check here for a sample MVP app for android.

Categories

Resources