This is a sample app that is part of a series of blog posts I have written about how to architect an android application using Uncle Bob's clean architecture approach.

Overview

Android-CleanArchitecture

New version available written in Kotlin:

Architecting Android… Reloaded

Introduction

This is a sample app that is part of a blog post I have written about how to architect android application using the Uncle Bob's clean architecture approach.

Architecting Android…The clean way?

Architecting Android…The evolution

Tasting Dagger 2 on Android

Clean Architecture…Dynamic Parameters in Use Cases

Demo video of this sample

Clean architecture

http://fernandocejas.com/2015/07/18/architecting-android-the-evolution/

Architectural approach

http://fernandocejas.com/2015/07/18/architecting-android-the-evolution/

Architectural reactive approach

http://fernandocejas.com/2015/07/18/architecting-android-the-evolution/

Local Development

Here are some useful Gradle/adb commands for executing this example:

  • ./gradlew clean build - Build the entire example and execute unit and integration tests plus lint check.
  • ./gradlew installDebug - Install the debug apk on the current connected device.
  • ./gradlew runUnitTests - Execute domain and data layer tests (both unit and integration).
  • ./gradlew runAcceptanceTests - Execute espresso and instrumentation acceptance tests.

Discussions

Refer to the issues section: https://github.com/android10/Android-CleanArchitecture/issues

Code style

Here you can download and install the java codestyle. https://github.com/android10/java-code-styles

License

Copyright 2018 Fernando Cejas

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

http://www.fernandocejas.com

Android Arsenal

Buy Me A Coffee

Comments
  • Breaking dependency rule: Data layer is dependent on Domain layer?

    Breaking dependency rule: Data layer is dependent on Domain layer?

    Apologies if this has been previously asked.

    I'm following the articles and the samples - the dependency rule states you can only point inwards.

    In the sample, the data layer repository is implementing the domain layer repo interface. Isn't this breaking the rule? I've tried to understand why this is acceptable but to no avail,

    Can someone fill me in ?

    opened by qasimvibrent 16
  • NullPointerException on UserListActivity

    NullPointerException on UserListActivity

    Had crash on first launch. After i clicked on load sample data. 12-23 12:46:53.522 2958-2958/com.fernanependocejas.android10.sample.presentation E: FATAL EXCEPTION: main Process: com.fernanependocejas.android10.sample.presentation, PID: 2958 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.fernanependocejas.android10.sample.presentation/com.fernandocejas.android10.sample.presentation.view.activity.UserListActivity}: java.lang.NullPointerException at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233) at android.app.ActivityThread.access$800(ActivityThread.java:135) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5001) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.NullPointerException at com.fernandocejas.frodo.aspect.LogObservable.methodAnnotatedWithRxLogObservable(LogObservable.java:27) at com.fernandocejas.android10.sample.data.net.RestApiImpl.userEntityList(RestApiImpl.java) at com.fernandocejas.android10.sample.data.repository.datasource.CloudUserDataStore.userEntityList(CloudUserDataStore.java:51) at com.fernandocejas.android10.sample.data.repository.UserDataRepository.users(UserDataRepository.java:54) at com.fernandocejas.android10.sample.domain.interactor.GetUserList.buildUseCaseObservable(GetUserList.java:41) at com.fernandocejas.android10.sample.domain.interactor.UseCase.execute(UseCase.java:59) at com.fernandocejas.android10.sample.presentation.presenter.UserListPresenter.getUserList(UserListPresenter.java:113) at com.fernandocejas.android10.sample.presentation.presenter.UserListPresenter.loadUserList(UserListPresenter.java:77) at com.fernandocejas.android10.sample.presentation.presenter.UserListPresenter.initialize(UserListPresenter.java:68) at com.fernandocejas.android10.sample.presentation.view.fragment.UserListFragment.loadUserList(UserListFragment.java:155) at com.fernandocejas.android10.sample.presentation.view.fragment.UserListFragment.onActivityCreated(UserListFragment.java:76)

    bug 
    opened by Drake1804 16
  • Single activity architecture

    Single activity architecture

    Great repo. However, I didn't like the multiple activity design. This version only uses a single MainActivity and three fragments.

    I am relatively new to dependency injection and Dagger2 so I'd appreciate any feedback you might have.

    If you want this to go into a separate branch, just let me know.

    opened by wkarl 14
  • Can I use this architecture in real project?

    Can I use this architecture in real project?

    This is not an issue. It's really a clearly defined architecture. A lot of technologies are introduced into the architecture, I 've never used them before, Dagger, RxAndroid, Butternife, etc. But I am little confused by the fine defined UseCases, for example , GetUserList, GetUserDetails for user usecases. If I want to do user search, I must define SearchUser usecase, I want to do CRUD for many many Objects, I need to write hands of usecases separately. And, I'm not sure how to pass parameters to the usecases. For example, GetUserDetails, pass the userId by constructor in UserModule. How can I pass a search critera to SearchUser UseCase? A Map? Or a Model? Is there another way instead of constructor?

    Thank you very much for any suggestion.

    opened by sitexa 13
  • Long running Use Case and orientation change

    Long running Use Case and orientation change

    In the current approach, every time after the orientation changes, the use case is executed once again. It would be a good solution if there would be a way to reuse the current operation after the orientation change, if the previous one is still running

    enhancement 
    opened by kmalmur 10
  • Make domain and data modules dependent on javax.inject instead of dagger 2

    Make domain and data modules dependent on javax.inject instead of dagger 2

    Dagger 2 has implicit dependency:

    +--- com.google.dagger:dagger:2.0.2
    |    \--- javax.inject:javax.inject:1
    

    Domain and Data modules don't depend on any class from the Dagger 2 API. They need only @Inject annotation, so it makes no sense to have the entire library in classpath.

    opened by DmitriyZaitsev 9
  • Question about testing

    Question about testing

    Hi, i have general question. I have checked test code.

    In Data layer test, test class only tests if some method is called, and does not care about result of method. Example, RepositoryTest only tests if method for getting User object is called, but it does not check if it really gets User object from that method. Same for DataStore classes.

    In Domain layer, again same thing for UseCases. It only tests if UseCase calls some repository method. Does not care about if it really gets result from that method.

    In Presentation layer, again PresenterTest only tests if Presenter calls some method of UseCase.

    Question:

    1. What is point of "testing only if method is invoked" :grey_question:
    2. Why none of the Test classes care about the result of method they've called :grey_question: Example, Presenter only checks if it calls useCase method, but why it does not check if view.showContent() is called after useCase returns data? There is no test for if UserCache is able to return right data?

    Sorry if i am missing sth

    opened by jemshit 8
  • Fatal error java.lang.Verify during getting users list on Samsung devices with Android version less than 5

    Fatal error java.lang.Verify during getting users list on Samsung devices with Android version less than 5

    During get users from API on Samsung devices with Android < 5 always throwing fatal error.

    Reproduces on devices:

    • Samsung GT-i9300, Android 4.4.4
    • Samsung SM-T530, Android 4.4.2
    • Samsung Nexus S, Android 4.1.2

    On Samsung SM-G531F, Android 5.1.1 worked correctly

    May be bug reproduced for all devices on Android < 5 (no-samsung devices with v4.. not available for me).

    Error listing:

    E/AndroidRuntime: FATAL EXCEPTION: main Process: com.fernanependocejas.android10.sample.presentation, PID: 31028 java.lang.VerifyError: com/fernandocejas/android10/sample/data/net/RestApiImpl$AjcClosure1 at com.fernandocejas.android10.sample.data.net.RestApiImpl.userEntityList(RestApiImpl.java:53) at com.fernandocejas.android10.sample.data.repository.datasource.CloudUserDataStore.userEntityList(CloudUserDataStore.java:51) at com.fernandocejas.android10.sample.data.repository.UserDataRepository.users(UserDataRepository.java:54) at com.fernandocejas.android10.sample.domain.interactor.GetUserList.buildUseCaseObservable(GetUserList.java:41) at com.fernandocejas.android10.sample.domain.interactor.UseCase.execute(UseCase.java:60) at com.fernandocejas.android10.sample.presentation.presenter.UserListPresenter.getUserList(UserListPresenter.java:115) at com.fernandocejas.android10.sample.presentation.presenter.UserListPresenter.loadUserList(UserListPresenter.java:79) at com.fernandocejas.android10.sample.presentation.presenter.UserListPresenter.initialize(UserListPresenter.java:70) at com.fernandocejas.android10.sample.presentation.view.fragment.UserListFragment.loadUserList(UserListFragment.java:158) at com.fernandocejas.android10.sample.presentation.view.fragment.UserListFragment.onViewCreated(UserListFragment.java:80) at android.app.FragmentManagerImpl.moveToState(FragmentManager.java) at android.app.FragmentManagerImpl.moveToState(FragmentManager.java) at android.app.BackStackRecord.run(BackStackRecord.java) at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java) at android.app.Activity.performStart(Activity.java) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java) at android.app.ActivityThread.access$800(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java) at android.os.Handler.dispatchMessage(Handler.java) at android.os.Looper.loop(Looper.java) at android.app.ActivityThread.main(ActivityThread.java) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java) at dalvik.system.NativeStart.main(Native Method)

    opened by filatoff 8
  • Unsubscribe in onDestroy()

    Unsubscribe in onDestroy()

    I think the code hides a potential issue that might appear with a minor change to the requirements. It calls Butterknife.unbind() in onDestroyView(). Also it calls view methods from Subscriber and unsubscribes in onDestroy(). If one of Subscriber's callbacks is called between onDestroy() and onDestroyView() we will get a NPE. I think it's not possible to reproduce the issue in this particular sample. Howerver, in a more complicated application that is using fragments' backstack it might be a problem.

    opened by shchurov 7
  • Rethink Observable.create() ?

    Rethink Observable.create() ?

    According to this article here, they said that:

    Don't use Observable.create() if you can, it's very easy to shoot yourself in the foot! (and then shoot again for each new subscriber!)

    question discussion 
    opened by spirosoik 7
  • New http request on conf changes

    New http request on conf changes

    I like how you architectured your application but, in a real android app. you would't want to waste resources and make new network request every time the user does something as simple as rotating their phone.

    opened by feresr 7
  • which layer should the mediaplayer be

    which layer should the mediaplayer be

    Hello, if this project has player that can play the movie,which layer should mediaplayer be, Fragment, viewmodel or usecase? I searched on the internet and I can't find solutions, thanks.

    opened by ikidou 0
  • NDK warning on build

    NDK warning on build

    When initiating a build on the command line, I am seeing a very old NDK warning. I have ndk-bundle installed. There is no local.properties file at project root. Log:

    Android-CleanArchitecture git:(master) ./gradlew clean build
    To honour the JVM settings for this build a new JVM will be forked. Please consider using the daemon: https://docs.gradle.org/4.1/userguide/gradle_daemon.html.
    Daemon will be stopped at the end of the build stopping after processing
    Configuration on demand is an incubating feature.
    
    > Configure project :data
    NDK is missing a "platforms" directory.
    If you are using NDK, verify the ndk.dir is set to a valid NDK directory.  It is currently set to /Users/shipit/Library/Android/sdk/ndk-bundle.
    If you are not using NDK, unset the NDK variable from ANDROID_NDK_HOME or local.properties to remove this warning.
    
    opened by shipit 1
  • Full Learning Document or Video

    Full Learning Document or Video

    Hello, dear CleanArchitecture team, first I have to thank you for this amazing open-source project to help out the community, secondly, I need to ask is there any video on this project or a full document to learn this whole project implementation?

    I am an Android developer and I've been using MVC till now, but I want to switch to this AMAZING architecture now, honestly, I don't know where to begin to understand the logic of this Architecture, is there any roadmap that I can follow to learn this architecture which one of you have used before? I appreciate it if anyone can help me with a link or a video for documentation.

    Thanks in advance.

    opened by R-Ashh 0
  • Use of Schedulers on UseCase

    Use of Schedulers on UseCase

    Hi,

    I was reading your project and there's something regarding the use of Schedulers on UseCase that I don't well understand.

    Note that I'm quite new to android programming so please forgive me if I say something terribly wrong! 😅

    So, why the UseCase needs a ThreadExecutor for the "backend" computation and a Scheduler to execute the observer? Why not ask for the same type?

    I mean, if the reason to ask for a ThreadExecutor is to be free to use whatever executor you want, why the same thing doesn't apply for observeOn? Why can't we ask again for another ThreadExecutor and simply call observeOn(Schedulers.from(executor))? (Note: I understand that is very simple to refer to the main thread using Schedulers thanks to AndroidSchedulers.mainThread(). There isn't a so simple way to obtain the main ThreadExecutor on Android?)

    And why we can't achieve the same result asking for two Schedulers? I mean, if I want simply use Schedulers.io() as background scheduler, how can I pass it to the UseCase? If the UseCase was asking for a Scheduler also for subscribeOn, I could pass Schedulers.io() or a custom scheduler (created with Scheduler.from(myThreadExecutor)) based on my need.

    Thanks in advance!

    opened by canemacchina 0
Owner
Fernando Cejas
Head of Engineering @TIGNUM. Former Director at @wireapp. Former @soundcloud Core Engineering. Ex @IBM. Curious learner. Geek. OPEN SOURCE Advocate.
Fernando Cejas
🚀 Sample Android Clean Architecture on JetRorty App focused on the scalability, testability and maintainability written in Kotlin, following best practices using Jetpack with Compose.

Android Clean Architecture in Rorty is a sample project that presents modern, approach to Android application development using Kotlin and latest tech-stack.

Mr.Sanchez 114 Dec 26, 2022
Sample Android Clean Architecture on App focused on written in Kotlin, following best practices using Jetpack with Compose.

Rick And Morty Jetpack Compose Sample App Table of Contents About the Project Architecture Features Environment Setup Contact About The Project This S

Mert Toptas 132 Jan 2, 2023
Sample project that shows an approach for designing a multi-module architecture for Jetpack Compose Android applications.

Compose Multi-Module Architecture Sample Sample project that shows an approach for designing a multi-module architecture for Jetpack Compose Android a

Pavlo Stavytskyi 77 Jan 3, 2023
REST countries sample app that loads information from REST countries API V3 to show an approach to using some of the best practices in Android Development.

MAJORITY assignment solution in Kotlin via MVVM Repository Pattern. REST countries sample app that loads information from REST countries API V3 to sho

Rehan Sarwar 1 Nov 8, 2022
CleanArchitecture is a sample project that presents a modern, 2021 approach to Android application development.

CleanArchitecture is a sample project that presents a modern, 2021 approach to Android application development. The goal of the pro

Shushant tiwari 0 Nov 13, 2021
RoomJetpackCompose is an app written in Kotlin and shows a simple solution to perform CRUD operations in the Room database using Kotlin Flow in clean architecture.

RoomJetpackCompose is an app written in Kotlin and shows a simple solution to perform CRUD operations in the Room database using Kotlin Flow in clean architecture.

Alex 27 Jan 1, 2023
Blog implemented via the Storyblok Kotlin Multiplatform SDK (Android, JVM)

storyblok-mp-SDK-blog ... a showcase of using the Storyblok Kotlin Multiplatform Client to build a blog application (Android, JVM) What's included ??

Mike Penz 5 Sep 28, 2022
Sample application to demonstrate Multi-module Clean MVVM Architecture and usage of Android Hilt, Kotlin Flow, Navigation Graph, Unit tests etc.

MoneyHeist-Chars Sample application to demonstrate Multi-module Clean MVVM Architecture and usage of Android Hilt, Kotlin Flow, Navigation Graph, Room

Hisham 20 Nov 19, 2022
A sample application that build with combine use Clean Architecture framework and Github API

The Github Example Introduction This is a sample application that build with combine use Clean Architecture framework and Github API (https://develope

Nguyễn Hùng An 2 Aug 12, 2022
Location Reminder App build as part of the udacity nanodegree program

Location Reminder a Location Reminder App with notifications that remind the user to do something when the user is at a specific location. built as pa

André Wagner 0 Dec 26, 2021
Sample Project with Clean Architecture for demonstrating using Kotlin Flows for fetching User Location and networking.

Nearby-Places-Foursquare-Android Getting Nearby Places using Foursquare API API's Used from FourSquare Get Key from Foursquare site. NearBy places Her

Abhishek Dubey 5 Nov 30, 2022
FaceTimeClone app that implements Coroutines , mvvm architecture , clean architecture , navigation component , hilt , etc.... using kotlin language

This repository contains a FaceTimeClone app that implements Coroutines , mvvm architecture , clean architecture , navigation component , hilt , etc.... using kotlin language

null 17 Dec 13, 2022
📚 Sample Android Components Architecture on a modular word focused on the scalability, testability and maintainability written in Kotlin, following best practices using Jetpack.

Android Components Architecture in a Modular Word Android Components Architecture in a Modular Word is a sample project that presents modern, 2020 app

Madalin Valceleanu 2.3k Jan 4, 2023
Android sliding panel that is part of the view hierarchy, not above it.

sliding-panel A ViewGroup that implements a sliding panel that is part of the view hierarchy, not above it. Difference from other libraries All other

Pierfrancesco Soffritti 441 Nov 12, 2022
A fork of our clean architecture boilerplate, this time using the Android Architecture Components

Android Clean Architecture Components Boilerplate Note: This is a fork of our original Clean Architecture Boilerplate, except in this repo we have swi

Buffer 1.3k Jan 3, 2023
Skeleton project for show the architecture of Android project using MVVM, Clean Architecture and Kotlin coroutine Flow

ClearScoreDemo Skeleton project for showing the architecture of Android project using MVVM, Clean architecture and Kotlin coroutine Flow App Architect

Plabon Modak 1 Mar 6, 2022
ATH Sample is a sample Authentication and Authorization Application with Kotlin Language and MVVM architecture.

ATH Sample ATH Sample is a sample Authentication and Authorization Application with Kotlin Language and MVVM architecture. Overview ATH Sample is a sa

AbolfaZl RezaEi 4 Jun 8, 2021
This repository is part of a Uni-Project to write a complete Compiler for a subset of Java.

Compiler This repository is part of a Uni-Project to write a complete Compiler for a subset of Java. Features error recovery using context sensitive a

null 3 Jan 10, 2022
ConstraintSetChangesTest - Simple project showing Changes of ConstraintSet value as part of mutable state in JetpackCompose.

ConstraintSetChangesTest Simple project showing Changes of ConstraintSet value as part of mutable state in JetpackCompose. Version: implementation

Mateusz Perlak 1 Feb 13, 2022