Until become a iOS team member, I spent most of my time to design and prepare the infrastructure for the Android version of the same App. The recent App is almost an Internetl App. Considering the UI responsive time, UX (user experience), and network bandwidth consumption, the data ususally is saved in the mobile device using some kind of form, e.g., SQLite or file). As a result, the App should synchronize the data between mobile devices and remote servers on need. In addition, the mobile network is not as stabile as the PC network (I'm not sure that 4G will be better). Therefore, a lots of issues should be considered. Since the Android App development is suspended for some reason (I become a iOS team member), the design and the thought just in my mind, and I don't have chance to write them down.
Recently, the Android App development is prepared to continue. Thus, I used some free time to write down the thought. I persist in the separation of Model and View, so the conceptual architecture diagram is like Figure 1 - the diagram is very generic, and could be used in most Internet Apps。The architecture is primary divied into few colored parts. The green part is Model. Business logics are all located here. In principle this part will be platform-independent - this part only uses the APIs common in Java SE and Android SDK. Therefore, to test this part, the Android simulator is not required and can use JUnit to achieve the maximum test coverage in least time.
For the developers that only consider the data structure as model, the business logics may locate at View or Controller (the Controller here is the Controller of MVC). For me, the data structure is only a part of Model, i.e., the Domain Data Model block in the figure. How to maintain the relationship between data objects or how to response the system events defined in the use case or user story? For me, these logics to handle system events in main controller all belong Model, i.e., the Business Logic Managers block in the figure. The responsibility is to communicate with server through Web Service Interfaces, maintain the relationship between data objects based on the server's responses, and then persist the status (Persistence) in the mobile device through DAO Interfaces.
Figure 1 - Android App Conceptual Architecture
The orange part is the platform-dependent implementation. For example, use Android SQLite API to implement DAO, and then inject the platform-dependent implementation into Model by Setter Injection or Interface Injection. To achieve this, the green part can not direct depend on the platform-dependent implementation. Therefore, both the Web Service Interfaces and the DAO Interfaces blocks only define the interfaces without implementation. The implementation is provided by the Web Service Implementation and the DAO Implementation block respectively in the orange part. This results in Dependency inversion. Thus, it is easy to inject mock objects of Web Service Interfaces and DAO Interfaces for testing.
Another role of the orange part is to play the Android Service. Android allows Service running in background. For the App prepared to develop, a service can be run in background is very useful. When an Activity becomes active, it is easy to obtain the latest status by binding the running service.
DAO Implementation is platform-dependent, so color it as orange is fine, but Web Service Implementation is colored as violet. This is because that it is possible to implement the Restful Web Services which exchanges JSON data only with the APIs common in Java SE and Android SDK and the JSON library also available in Android. That also means a platform-independent Web Service Implementation is possible, and can be tested with JUnit.
The gray part is View. The primary block is Android Activities & UI Flow Controls. To test this block, an Android simulator or a physical device is required, and is time-consuming. However, this block determines whether App is user-friendly or not. Besides, the API in the green part and orange part will be synchronous. In order not to block UI, Android SDK provides some asynchronous helper class (e.g.,
AsyncTask), but I feel that is not good enough. Therefore, Asynchronous Supports & UI Components will provides some customized helper classes for the App special needs. In addition, since Android does not allow the program running in non UI Thread to update the UI, the Asynchronous Supports & UI Components block is also responsible for transforming the UI update request from non UI thread to UI Thread. This block is colored as blue, and should be designed to cross projects as the assets of the company in the long-term.
This is a general design, but the App prepared to develop will integrate a third-party game engine - the architecture may have some modification, e.g., more interfaces in the Domain Model or Android Service to communicate with the game engine, using IoC to protect Domain Model, etc. Finally, in order not to affect objects in different parts, the maven (or gradle) module mechanism is used to group objects in different modules and control their visibility by the dependency between modules. I hope the Android app can be developed smoothly under a clear requirement (iOS version is complete).