GithubHelp home page GithubHelp logo

androidmvp's Introduction

👋 Hi there, my name is Antonio Leiva

I'm a Kotlin Freelance Trainer, Kotlin GDE and JetBrains Training Partner

https://github.com/antoniolg

I help developers reach their goals with my training and mentoring.

Learn with me

🎁 Free Masterclass: Revienta tu productividad en Android con Kotlin / Boost your Android productivity with Kotlin

🥉 Book: Kotlin For Android Developers
🥈 Training: Kotlin Para Desarrolladores Android / Kotlin for Android Developers
🥇 Program: Architect Coders

Skills:

Android
Kotlin
Android_Studio

Find me at:

Spanish

Web YouTube LinkedIn Instagram Twitter

English

Web YouTube LinkedIn Instagram Twitter

Contact me:

Email

Email

androidmvp's People

Contributors

antoniolg avatar evin1- avatar foens avatar msbaek avatar petrulak avatar rafaeltoledo avatar sanpetch avatar yaorugang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

androidmvp's Issues

More advanced use cases

Could you share some tips for more advanced scenarios.
By this I mean cases, when we should somehow interact with android framework layer.
Let's say we wanted to login via Google Signin (from Google Play Services), this approach requires GoogleApiClient and tightly coupled to method onActivityResult. This is just an example, for simplicity it could be slightly changed.

From my point of view example provided is great, very simple and intuitive, but when it comes to real use cases, questions appears.

Cheers.

There is a loose coupling between View and Model in main package

Thanks for your pioneering wonderful work on MVP in android.
After reviewing the code, I found something not consistent with the passive view MVP that you are implementing. The thing is that in your 'MainActivity' (View), an instance of 'FindInteractorImpl' (Model) is passed as an argument to the 'MainPresenter' constructor. This makes a coupling between View and Model, which is not admissible in passive view implementation on MVP, which rules out any such relation in the UML graph. Please correct me If I am wrong.

Interactor being instantiated in the View

In the MainActivity you're creating the Presenter by passing in a new instance of the interactor.
That means that the view knows about an inner layer of the app, which is that interactor.
Should it be like that? In theory, the view should only know about its closest inner layer, which is the presenter, but it shouldn't know about that interactor.

Thanks and good job!

Interactor what in MVP

Why do we use Interactor in Mvp ?Presenter can maka it What Interactor do,can I see it as a model?or,it is a model

Memory Leak in Activity?

The PresenterCompl will hold reference of IView(Activity), so that the Activity's heap can not be recyled when it was onDestroyed.

LoginInteractor中的一个小问题

LoginInteractor类中我直接按照你的写法好像不行,改成下面这种就可以了,

Handler().postDelayed(Runnable {
       }, 2000)

不知道是否因为我新建的项目采用的是AndroidX的原因

Where to reach domain layer from MVP

I'm trying to understand this pattern, and it seems clearer and clearer. Im a javascript developer, and React Native made me want to learn more about native android dev.

I've got the point that MVP resides in the pres' layer. I've got the point that we also reach backend data thanks to interactors and getting some DTOs (aka model in our cases).

I use to work with remote domain layer, using REST APIs entrypoints. But sometime, I've to deal with client side logic for offline treats or state mutations, some stuff like that.

I know that I shouldn't put this kind of computation inside of the presentation layer, and I was thinking of "deduping" (not really, but using a simplified version of my remote domain) in another module my business domain.

But the problem still exists, I have now two modules :

  • my pres layer with MVP
  • my domain layer, pure Java classes, no Android sdk classes

But I don't know where to connect both of these to create a scaling architecture. Like, where should I call my domain services ? In interactor ? In presenter ?

I m a bit confused for this part ^^'

Unit tests

Could you add a simple unit testing of this architecture?

how make request for one api

I like this project, but i am confused about how to organize my requests for one api and how to organize my access for database.

How about life cycles ?

The presenter is recreated each time a new instance is created, as during a rotation. This doesn't address one of the main Android issues.

Let's say you got a network request, initiated by the presenter of the activity before rotation, how can the new instance take advantage of the request pending or resolved ?

Is this package structure correct?

In my attempt to understand MVP I have structured the classes in their own package, where each packaged is named as: model, view, presentor, in respect to the classes role. Is it correctly done?

udklip

Import this project

Are you still maintaining this code?
I was not able to import this project into a IDE (Eclipse, Android studio) because there seems to be a problem with the src files. They are in the wrong directory.
thx fridolin

DI with your MVP example

Hi there!

First of all, very nice and clear example of how MVC could be implemented. I have a couple of questions about it.

On one hand, as we can see in the following image:

image

I usually create/inject/use Domain Classes (my use cases) in Framework Layer directly. The above image show us that we could reach Domain Layer from Framework.
I have re-structured your example in order to clarify C.A. concepts, thinking about Login component, as follow:

image

Now we can see how Framework (Android) has view components and "speaks" with Domain through LoginViewInterface, how Domain "talks" to Data Layer through LoginInteractorInterface (I usually call this Repositories/Services).

Communication is made through interfaces so that we are not violating any C.A. principles.

In your opinion, is that correct?

On the other hand, how could we implement DI (with Dagger 2 i.e.) in this example?

Let say, I would like to make a HTTP POST to BE in order to log me in. I would create a client (Retrofit + Okhttp i.e.) in Application Context and I would inject this client to Data Layer. Should I call Dagger in Data layer? Shoud I pass client's instance through from some where inside Framework Layer (Activity)?

Thank you in advance!

P.D.: I have tried to push a new branch with these changes and made a PR but I couldn't :(

I have a problem in gradle build

A problem occurred configuring project ':app'.

java.lang.NullPointerException (no error message)

  • Try:
    Run with --scan to get full insights.

  • Exception is:
    org.gradle.api.ProjectConfigurationException: A problem occurred configuring project ':app'.
    at org.gradle.configuration.project.LifecycleProjectEvaluator.addConfigurationFailure(LifecycleProjectEvaluator.java:109)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.onAfterEvaluateFailure(LifecycleProjectEvaluator.java:105)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:87)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.doConfigure(LifecycleProjectEvaluator.java:72)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.access$100(LifecycleProjectEvaluator.java:37)
    at org.gradle.configuration.project.LifecycleProjectEvaluator$ConfigureProject.run(LifecycleProjectEvaluator.java:125)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:317)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:309)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:185)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:97)
    at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:52)
    at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:677)
    at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:138)
    at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
    at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
    at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:41)
    at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuild.run(DefaultGradleLauncher.java:262)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:317)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:309)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:185)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:97)
    at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    at org.gradle.initialization.DefaultGradleLauncher.configureBuild(DefaultGradleLauncher.java:175)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:132)
    at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:115)
    at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:77)
    at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:74)
    at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:152)
    at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:38)
    at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:96)
    at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:74)
    at org.gradle.tooling.internal.provider.runner.ClientProvidedPhasedActionRunner.run(ClientProvidedPhasedActionRunner.java:61)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
    at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.run(RunAsBuildOperationBuildActionRunner.java:47)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:317)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:309)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:185)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:97)
    at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:43)
    at org.gradle.tooling.internal.provider.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:51)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:50)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:46)
    at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:65)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:46)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:32)
    at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:39)
    at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:25)
    at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:80)
    at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:53)
    at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:62)
    at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:34)
    at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
    at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
    at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
    at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
    at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:59)
    at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:31)
    at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:59)
    at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:44)
    at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:46)
    at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:30)
    at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
    at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
    at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
    at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
    at org.gradle.util.Swapper.swap(Swapper.java:38)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
    at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
    at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:62)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
    at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:82)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
    at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
    at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:295)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
    Caused by: java.lang.NullPointerException
    at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:782)
    at com.google.common.base.Splitter.split(Splitter.java:376)

Scrren rotation

What about screen rotation scenario?
MVP helps majorly with it, and you did not implement it.
Would be great if presenters would be saved during activity recreation (rotation) with the help, for ex. retainedFragment.
I implemented on your example my MVP model, if it is right and you have time, implement it, please, your repo really hepls peaople understand mvp consept
repo - https://github.com/spartacus777/MvpSample

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.