Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

API Practices in the Android Platform by Earlence Fernandes and Boris Farber

DZone's Guide to

API Practices in the Android Platform by Earlence Fernandes and Boris Farber

·
Free Resource
Following our first article about the API Design Importance http://architects.dzone.com/articles/understand-importance-apil we continue the series .In this article we decided to list out the several practices exhibiting good API Design practices we have seen in Android platform. This is not an Android introduction or tutorial (to read and understand it, no knowledge of Android platform is assumed).

 

Google Android is an open source stack for mobile devices [1]. It has a Linux kernel upon which a Java Virtual Machine runs (known as the Dalvik VM). The API is primarily in Java with the added option of writing code in C via JNI and the NDK (Native Development Kit).

Message Passing

The platform is quite comprehensive with most of the JDK standard APIs (java.lang , java.util, java.io, java.net )ported. Each application runs in its own Linux process and each process has its own JVM. An Android application is typically made up of the following components [1].

  1. Activities
  2. Services
  3. Broadcast Receivers
  4. Content Providers

Activities represent a single logical action a user might undertake. A Service is like a background process. The Service has no UI. The Service is used to perform long running tasks. A broadcast receiver is designed to pick up broadcasts and filter out the ones intended for the component on whose behalf it is acting. A content provider is a sophisticated mechanism for handling data and data sources.

Fig 1. Android’s Component Model

All of these components are connected via intents. This is of importance to use since it is a loosely coupled design, but a sense of coherency is maintained. Thus this is a good API design technique.

SIDE NOTE:

Coupled Design is of 2 types

Strongly coupled systems where in the systems being connected have intrinsic knowledge of each other. This prevents easy replacement of a component.Loosely coupled systems where in the systems just adhere to a communication contract and hence are easily replaceable.

INTENTS as a Message Passing Technique

As indicated above, Intents are a way of achieving communication (light overhead) between the various Android components. Intent specifies the action, the category and optionally data to act upon. Hence, in a single mechanism, data and action is encapsulated.

TECHNIQUE:

Maintain a loosely coupled architecture with a simple mechanism to achieve communication between the components. This allows a lot of flexibility when adding newer components.

For example if the API designer wants to add another component, then he can simply add it by maintaining the contract of communication the other components are currently using.This is illustrated by the mechanisms Android has to facilitate communication – Intents and a form of IPC.

UI Development Styles

Android API provides 2 alternatives for designing the UI (layout and construction) [2].

  •  
    • Using declarative style via XML file
    • Using procedural style directly via code

Each has its own pros and cons but the main idea is the support of 2 programming styles here! Here we summarize the key differences and tradeoffs between these styles

 

Style

Pros

Cons

Declarative(XML)

  • Simple to learn. Just specify WHAT is needed WHERE without specifying HOW to actually accomplish it. Internally, Android performs what is called "XML Layout Inflation" to actually render the screen.
  • Use of XML as the language allows extensibility.
  • There is a slight loss of control over the actual process.
  • Overhead in the system to read the declarative code and draw components.

Procedural (Code)

  • Total control over the layout process.
  • Can control when layout/view objects are created.
  • No overhead code to read and parse another language as is the case with declarative layout.
  • More control implies more work.
  • Learning curve is slightly steeper than the other mode.
  • TECHNIQUE:

    Maintain several programming styles to the API since each has its own applicability. The declarative style saves time, removes burden from the developer. The procedural style gives the developer a greater degree of control, but adds more burden on coding.

    For example if the API design is for a UI library, maintaining the above 2 approaches will be an added advantage for reasons stated above. For the declarative style, use of XML is quite ingenious, although there are several options. Consider the use of lighter JSON (JavaScript Object Notation). From a UI library point of view, if a XML/JSON is used to specify (note the use of the word ‘specify’ here) the UI, a GUI interpreter may have to be written to actually draw out the UI.

    Composite Design Pattern in UI Schemes

    The idea is to allow building of custom UI components by leveraging good OO techniques of careful inheritance of classes and implementation of interfaces [3].

     

    In Android, each user element is called a "View". It forms the parent of a hierarchy known as the "View Hierarchy Tree". This tree implies controlled inheritance relationships. We do not need to stress the importance of careful inheritance in modern OO languages

    It is worth noting that this is a description of the Composite Design Pattern. The "View" class is the root of the tree (similar to Swing’s JComponent class [4]).

    If we split the composite design pattern as COMPONENT, LEAF and COMPOSITE, then we would have [5].

    COMPONENT – "View" or "ViewGroup" (which represents abstraction for all components)

    LEAF – Actual UI elements like "TextView" or "ScrollView" which represent leaf objects of the composition.

    COMPOSITE – The entire UI built up using view elements.

    In classic composite style, any operation (like drawing out the UI), requires a traversal of the tree.

    Two techniques that offer various degrees of freedom while sub-classing.

    First, subclass the most generic class is available. As per our example, "View" or "ViewGroup" would be the most basic types here. Extending these classes provides the developer complete freedom on the appearance of the UI element (in the case of our example) and full control on the functionality (in the more general case). However, care must be taken so that our custom implementation does not distort the concept the class represents to such an extent that it does not adhere to the semantics of its parent class.

    Second, subclass various classes lower down in the inheritance hierarchy that is closer to the functionality we wish to implement. Consider the following figure.

    Fig 1. Android’s Component Model

    Suppose we have some functionality that is closer to "Child2" than to "Parent", it makes sense to subclass "Child2" and make use of the implementations readily available. This may not sound like an API technique but more like common sense. Let us point that good API design is good common sense!

    Moreover, this is stated in the Android Custom View Design guidelines.

    Security and Permissions

    We will first define security and permissions in the context of android and software.

    Remember that Android is basically a Linux kernel and all processes follow the Linux security model for execution and access control [6].

    Bear the following points in mind while reading subsequent paragraphs:

    1. Each android application runs in a sandboxed Linux process with its own Linux process ID.
    2. Each application has its own VM instance, hence code runs in isolation.
    3. All the files created by an application are visible to it only. There are ways to share, but this is through specific techniques only. (Which are outside the scope of this text).

    The other point of consideration is Android is a "mobile" operating system. This implies that it must have the facility of controlling access to device functions, execution of 3rd party code.

    1. Android uses an XML based file to control access to device features.
    2. Centralized point of access control.
    3. ONLY the developer can assign/revoke these privileges.

    TECHNIQUE:

    For APIs that are security critical or deal with confidential data, maintaining a central point of control reduces vulnerabilities. But in keeping with Security traditions, there is no perfect solution. Having a central control point reduces vulnerabilities in the system, but is very strict. A compromise must be made depending upon the context of use.

    References

    1. http://developer.android.com/guide/topics/fundamentals.html
    2. http://developer.android.com/guide/topics/ui/index.html
    3. Modern C++ Style, Bjarne Stroustrup, http://www.artima.com/intv/modern.html
    4. http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JComponent.html
    5. The Design Patterns, Java Companion Guide, James W. Cooper.
    6. http://www.linuxtopia.org/LinuxSecurity/
    Topics:

    Opinions expressed by DZone contributors are their own.

    THE DZONE NEWSLETTER

    Dev Resources & Solutions Straight to Your Inbox

    Thanks for subscribing!

    Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

    X

    {{ parent.title || parent.header.title}}

    {{ parent.tldr }}

    {{ parent.urlSource.name }}