First, it depends on what application you are doing.
you should do a textual or schematic description on how a user will work with application. Fix down every possible scenario. Put down examples that will be used later for tests.
Decide what belongs to the functionality and what - to the changeable configuration. Extract functionalities and data entities from scenarios.
From scenarios make decision what your app will be. Is it service, activity, widget , even a content provider or a complex system, including some different components. Test your decision against scenarios.
In the case of the complex system, distribute functionalities and data entities among application components. Make a list of components and what they are (activities or smth else).
Make the list of UI components with description what they do (not HOW yet)
These will be widgets and activities or fragments or layouts later.
Make draft layouts for UI components. Make simple passes from one to another.
Look at the UI. Return to scenarios and play all of them them with your draft UI. All UI components and classes put into one hierarchy of packages or package.
Make a list of data entities. Decide what will be in what. Plan them as collections or tables in DB or different DBs. Make them as classes, put them into another hierarchy of packages or another package. Here also put DB helpers - classes that talk with DB by SQL.
Make a testing classes(JUNITs or better TestNG) for filling UI and data entities with test data and launching them.
Adapters needn't be public, for they are used in their parent GroupView only. So, no files for adapters usually.
Do not put all globals into special static classes - it is a bad practice. You are mixing so the code and the configuration. Use this very interesting solution. For now, it is the best I know for Android.
Configuration data should be put into resources. If some of them are complex, use XML sources and parser(s). Make readers of resource data into global variables. Not all of them will be static! They could belong to the main Activity instance, for example.
Do not use unconfigurable constants in the code! May be, your name only :-).
Every constant becomes non-constant sometimes.
On the other side, if some of you code is not normal java, but scripts - a mix of data and language, then you can and must mix data and code.
Always do so:write something - connect something to a bulk - add test(s) for this new thing - test this new one - test the bulk - repeat. Small steps only!
Edit. You can also use the test driven development - write tests before appropriate code. This way, running tests before the code is ready, you have double testing - thus you check if the tests really react to incorrect code.
On Android, the canonical answer to this is to use a combination of Activities, Fragments, Adapters, Loaders and Services.
In my project we're pretty strict about how we do things. Activities are used to set up the base view, which is usually just a FrameLayout or something similar. We have no UI logic whatsoever in there. An Activity is just used to wire everything up. UI is all handled by Fragments (except for some special fragments that we treat like an Activity). Network reads are all done in Loaders and we use Adapters to push the data to the UI. Adapters are owned by the Fragments, but the Activity wires them up to the Loaders with callbacks. Services are used for network writes.
This setup takes a pretty decent amount of time to set up the infrastructure and develop your basic workflow, but once you've got a working pattern, you can just kind of coast your way through the rest of it. Want a Floating Action Button, just include the right fragment and base classes handle the boilerplate.
So in the end it's more of an MVP stack than a MVC. Our views are aware of what a user is trying to do and indicate that via interfaces. Here's a typical workflow:
User is looking at a thing and wants to vote on it. The fragment that holds the upvote button catches the click. First it updates the vote count locally to the expected new value. Note that this isn't official, and it's not persisted anywhere. It just improves latency in the most common case where the vote hasn't changed. It casts the parent (Activity or Fragment) to an interface with an upvote()
method and calls it. The Activity (or Fragment) gets the upvote call and passes it on to the service, with a callback. The service puts the action into a queue (we single-thread writes) and eventually calls the API. The API returns the new number of votes. The Service calls the callback, which gets routed into the Loader. The Loader updates the relevant section of the model, and then signals to the Adapter that new data is available, which the UI then picks up and shows. Note that if it's too difficult to patch the model, the Loader could just go re-request it.
So that's a pretty big mouthful, but our logic is separated, the entire UI is built via composition, the components are all highly testable, and it's usually pretty easy to trace out what happened when there's a bug.
Best Answer
Uncle Bob would probably prefer seeing the "business intend" of ur app in the top level folder structure. This is what I means with "screaming architecture".
so as I have described in my blog post here https://plainionist.github.io/Implementing-Clean-Architecture-Scream/ ur top level structure should contain things like
these aspects which e.g. ur customer would also see using ur app.
on the next level I would at least separate the usecases and entities from the rest. depending of the size of ur app could could have one project per circle within each of the top level folders.
with this approach u would have a screaming architecture clearly separating different business and technical concerns.
on the other hand that would create quite some projects. u would have to balance both aspects for ur project.
(Any feedback to my blog post is welcome as well so that I can improve it further)