I have assisted some times ago to a meeting where the speaker suggested removing the Android framework from the business layer to make a right distinction between the business and the interface. The idea seemed interesting to me, I have thought about it since and give you the result in this article.
Without talking about Android, an important principle of software development is the separation of concerns. We often distinguish the interface, from the business, from the data storage. This permits a best maintainability of the code (readability, layers able to evolve independently), a code easier to test (right distinction business-UI, faster execution), eventually the reuse of layers.
Removing the dependency to the Android framework from the business layer (and then migrate it in a standalone project) would ease the distinction between the interface and the business. There would be no more possibility for interconnections of interface code in the business. Without Android framework, the unit tests of the business layer would be fully executable outside the emulator without using instrumented tests or solutions like Roboelectric. The business code being written in pure Java, it would be really reusable.
Most of the time, on applications simply displaying remote contents, there is no problem : the APIs of the Android framework (android.*) are not used.
Be careful though, the Android framework does not only contain rendering libraries, it also provides many tools including storage supports (SQLite, Shared Preferences, ContentProvider) which can be used from the business layer. The solution would be to add an abstraction layer above and to pass its implementation to the business layer (which then would not know that it comes from the Android framework). By and large, all facilities provided by the Android framework which we would use in the business layer should be abstracted and initialized in the same way.
If we dig a bit more and begin to look in detail the packages of the Android framework, we realize that there are technical services (low and high level) which can be used to implement our business layer : related to hardware specificities (geocoding and bluetooth management), image manipulation functions (android.graphics), network functions (android.net), security functions (android.security), parsing functions (android.sax, android.util) or also utility functions (android.util). When we will want to use these services (not that many), we will be blocked. We will then have to, either find an alternative composing with the standard java libraries included in Android or external libraries compatible with Java and Android (lose of coherence between our code and Android standards), either add a method to our framework abstraction (potentially heavy and less coherent : low and high level methods aside or a more complex interface structure).
This distinction, interesting at first sight and working on simple cases, can appear problematic in the long term when we will want to use a service included in the framework.
Something to see is that this is not, on a side, packages inherited from the JDK with technical services to support the business layer, and on another side, Android packages : graphical interfaces, OS, etc. The Android framework is a fully-fledged environment which partly reuse packages inherited from the JDK but also complementary packages developed specifically.
Then, can we imagine an other distinction based on the Android environment with on a side interface and OS packages, and on the other side packages which we can use to implement the business layer ? We would then pass from a vision of business reusability : Android – Web – Desktop to an Android (mobility) vision : Smartphone/Tablet – Wear – TV – Auto.
To realize this, we could compile 1 reduced version of the Android SDK containing only the services which can be used to support the business layer. Can we really distinguish the one from the other ? It must also be possible to develop an IDE plugin to block the use of some specific packages in a project.