Project Architecture - xialin/GrabMovie GitHub Wiki

Overview

I have been looking for some good practices for Android architecture design. There is no right or wrong, and is always open for discussion. What's discussed below is just what makes more sense to me among all.

Java Package Architecture

We can loosely follow a Model-View-Controller structure when organising an Android project.

com.example
├─ activities
├─ fragments
├─ managers
├─ models
├─ network
└─ views
   ├─ adapters
   ├─ widgets
   └─ notifications
├─ utils
├─ MyApplication.java
├─ Constants.java
  • First of all, activities and fragments are two important packages that should be grouped separately. They are considered as the UI controllers.
  • There are some controller classes that are application-wide (not for particular UI screens) and close to Android system. They should be grouped under managers.
  • models package contains both local and remote data objects. Local objects are those stored in your app database, remote objects are those JSON-parsed from API responses.
  • Classes that are responsible for interacting with the backend (APIs) stay in the network package.
  • views package contains custom Views, notifications, action bar views, widgets, etc.
  • Miscellaneous data processing classes, such as DateUtils and Logger, stay in the utils package.

Resources

layout XMLs

  • Naming pattern: type_foo_bar.xml e.g. activity_main.xml
  • Optimize layout hierarchies and avoid too many nested layouts
  • A rule of thumb, attributes android:layout_**** should be defined in the layout XML, while other attributes android:**** should stay in a style XML. The idea is to keep only layout (positioning, margin, sizing) and content attributes in the layout files, while keeping all appearance details (colours, padding, font) in styles files. Exceptions are:
    • android:id should obviously be in the layout files
    • android:orientation for a LinearLayout normally makes more sense in layout files
    • android:text should be in layout files because it defines content
    • Sometimes it will make sense to make a generic style defining android:layout_width and android:layout_height but by default these should appear in the layout files

styles.xml

  • Use styles for common components such as text, button etc.
  • Split styles.xml into smaller files e.g. styles_main.xml, styles_item.xml etc.

colors.xml

colors.xml is a color palette. There should be nothing else in your colors.xml than just a mapping from a color name to an RGBA value.

<resources>

    <!-- grayscale -->
    <color name="white"     >#FFFFFF</color>
    <color name="gray_light">#DBDBDB</color>
    <color name="gray"      >#939393</color>
    <color name="gray_dark" >#5F5F5F</color>
    <color name="black"     >#323232</color>

    <!-- basic colors -->
    <color name="green">#27D34D</color>
    <color name="blue">#2A91BD</color>
    <color name="orange">#FF9D2F</color>
    <color name="red">#FF432F</color>

</resources>

dimens.xml

Treat dimens.xml like colors.xml. You should also define a "palette" of typical spacing and font sizes, for basically the same purposes as for colors. A good example of a dimens file:

<resources>

    <!-- font sizes -->
    <dimen name="font_larger">22sp</dimen>
    <dimen name="font_large">18sp</dimen>
    <dimen name="font_normal">15sp</dimen>
    <dimen name="font_small">12sp</dimen>

    <!-- typical spacing between two views -->
    <dimen name="spacing_huge">40dp</dimen>
    <dimen name="spacing_large">24dp</dimen>
    <dimen name="spacing_normal">14dp</dimen>
    <dimen name="spacing_small">10dp</dimen>
    <dimen name="spacing_tiny">4dp</dimen>

    <!-- typical sizes of views -->
    <dimen name="button_height_tall">60dp</dimen>
    <dimen name="button_height_normal">40dp</dimen>
    <dimen name="button_height_short">32dp</dimen>

</resources>

strings.xml

Name your strings with keys that resemble namespaces, namespaces are necessary to bring context and break ambiguity.

Bad

<string name="network_error">Network error</string>
<string name="call_failed">Call failed</string>
<string name="map_failed">Map loading failed</string>

Good

<string name="error.message.network">Network error</string>
<string name="error.message.call">Call failed</string>
<string name="error.message.map">Map loading failed</string>

Don't write string values in all uppercase. Stick to normal text conventions (e.g., capitalize first character). If you need to display the string in all caps, then do that using for instance the attribute textAllCaps on a TextView.

Bad

<string name="error.message.call">CALL FAILED</string>

Good

<string name="error.message.call">Call failed</string>

References:

https://github.com/futurice/android-best-practices#resources

⚠️ **GitHub.com Fallback** ⚠️